diff --git a/DEPS b/DEPS
index adc75396..e6e9748e 100644
--- a/DEPS
+++ b/DEPS
@@ -167,11 +167,11 @@
   # 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': '0fc9b3829b476786f4a50a8e8e9469cd309c17ea',
+  'skia_revision': '69537d79899407c4f4a5882a793b46fbf7f87256',
   # 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': 'd0b81401bafdfcd2c96913e63faaa0ce6b382fa8',
+  'v8_revision': 'c2dc845a0ba81912c7356178de67124da98f13ff',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -179,7 +179,7 @@
   # 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': 'c5e0ac757a112a24a0118d434e652fd7b558e6a8',
+  'angle_revision': 'ad5f71649e210069ab5427ddb46755358df220a1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -218,7 +218,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_revision': '1e9229f0fcb46fd4cd8e0fdc48fb4a44ddb7a8a1',
+  'freetype_revision': '545a481a74a3c3b70af8928793a01a84f8b0ee9b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling HarfBuzz
   # and whatever else without interference from each other.
@@ -286,7 +286,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.
-  'spv_tools_revision': 'c18c9ff6bc301f01b76319a818a975956abbf1d2',
+  'spv_tools_revision': '82f84c4b8f19a3a59647e851a5b3921d63b7b8e4',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -302,7 +302,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': 'e16a901fb85351a93b224ea1b7b6d603a07fd1cc',
+  'dawn_revision': '91b2142ee44d3e4eb3bafcbc8eec4d196006c9d3',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -862,7 +862,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'a441815f4dc37c2196a5b23182300bd0095f76ee',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '8e881f105660fce901e238c4926008c24874eb16',
       'condition': 'checkout_linux',
   },
 
@@ -1280,7 +1280,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'aa9175d6761d7ff7a172d637fda4a17df64453b5',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'e6b95e45544dd0ec3e57e21b2aec9a25bd7c664b',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1470,7 +1470,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '2701c130839edbeb226735b0775966b6423d9e83',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '066c2ab92f8034eea35ffced287ecaf08c9bb501',
+    Var('webrtc_git') + '/src.git' + '@' + '03f4b36bdd9a04d777ccbe526310448d8446cc4e',
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index a4ba626..c4821d4 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -882,22 +882,25 @@
     bool has_user_gesture,
     const base::Optional<url::Origin>& initiating_origin,
     network::mojom::URLLoaderFactoryPtr* out_factory) {
-  auto request = mojo::MakeRequest(out_factory);
+  mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver =
+      mojo::MakeRequest(out_factory);
   if (content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
     // Manages its own lifetime.
-    new android_webview::AwProxyingURLLoaderFactory(0 /* process_id */,
-                                                    std::move(request), nullptr,
-                                                    true /* intercept_only */);
+    new android_webview::AwProxyingURLLoaderFactory(
+        0 /* process_id */, std::move(receiver), nullptr,
+        true /* intercept_only */);
   } else {
-    base::PostTask(FROM_HERE, {content::BrowserThread::IO},
-                   base::BindOnce(
-                       [](network::mojom::URLLoaderFactoryRequest request) {
-                         // Manages its own lifetime.
-                         new android_webview::AwProxyingURLLoaderFactory(
-                             0 /* process_id */, std::move(request), nullptr,
-                             true /* intercept_only */);
-                       },
-                       std::move(request)));
+    base::PostTask(
+        FROM_HERE, {content::BrowserThread::IO},
+        base::BindOnce(
+            [](mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+                   receiver) {
+              // Manages its own lifetime.
+              new android_webview::AwProxyingURLLoaderFactory(
+                  0 /* process_id */, std::move(receiver), nullptr,
+                  true /* intercept_only */);
+            },
+            std::move(receiver)));
   }
   return false;
 }
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 a157f13..97225bbd 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
@@ -31,6 +31,7 @@
 #include "content/public/common/content_constants.h"
 #include "content/public/common/resource_type.h"
 #include "content/public/common/url_utils.h"
+#include "mojo/public/cpp/bindings/binding.h"
 #include "net/base/load_flags.h"
 #include "net/http/http_util.h"
 #include "services/network/public/cpp/resource_request.h"
@@ -719,7 +720,7 @@
 
 AwProxyingURLLoaderFactory::AwProxyingURLLoaderFactory(
     int process_id,
-    network::mojom::URLLoaderFactoryRequest loader_request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
     network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
     bool intercept_only)
     : process_id_(process_id), intercept_only_(intercept_only) {
@@ -731,8 +732,8 @@
         base::BindOnce(&AwProxyingURLLoaderFactory::OnTargetFactoryError,
                        base::Unretained(this)));
   }
-  proxy_bindings_.AddBinding(this, std::move(loader_request));
-  proxy_bindings_.set_connection_error_handler(
+  proxy_receivers_.Add(this, std::move(loader_receiver));
+  proxy_receivers_.set_disconnect_handler(
       base::BindRepeating(&AwProxyingURLLoaderFactory::OnProxyBindingError,
                           base::Unretained(this)));
 }
@@ -742,12 +743,12 @@
 // static
 void AwProxyingURLLoaderFactory::CreateProxy(
     int process_id,
-    network::mojom::URLLoaderFactoryRequest loader_request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
     network::mojom::URLLoaderFactoryPtrInfo target_factory_info) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
 
   // will manage its own lifetime
-  new AwProxyingURLLoaderFactory(process_id, std::move(loader_request),
+  new AwProxyingURLLoaderFactory(process_id, std::move(loader_receiver),
                                  std::move(target_factory_info), false);
 }
 
@@ -799,14 +800,14 @@
 }
 
 void AwProxyingURLLoaderFactory::OnProxyBindingError() {
-  if (proxy_bindings_.empty())
+  if (proxy_receivers_.empty())
     delete this;
 }
 
 void AwProxyingURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest loader_request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-  proxy_bindings_.AddBinding(this, std::move(loader_request));
+  proxy_receivers_.Add(this, std::move(loader_receiver));
 }
 
 }  // namespace android_webview
diff --git a/android_webview/browser/network_service/aw_proxying_url_loader_factory.h b/android_webview/browser/network_service/aw_proxying_url_loader_factory.h
index 62c1e25..25aeb15 100644
--- a/android_webview/browser/network_service/aw_proxying_url_loader_factory.h
+++ b/android_webview/browser/network_service/aw_proxying_url_loader_factory.h
@@ -7,8 +7,8 @@
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/cpp/resource_response.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
@@ -58,7 +58,7 @@
   // target factory.
   AwProxyingURLLoaderFactory(
       int process_id,
-      network::mojom::URLLoaderFactoryRequest loader_request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
       network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
       bool intercept_only);
 
@@ -67,7 +67,7 @@
   // static
   static void CreateProxy(
       int process_id,
-      network::mojom::URLLoaderFactoryRequest loader,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader,
       network::mojom::URLLoaderFactoryPtrInfo target_factory_info);
 
   void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader,
@@ -79,14 +79,15 @@
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
 
-  void Clone(network::mojom::URLLoaderFactoryRequest loader_request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+                 loader_receiver) override;
 
  private:
   void OnTargetFactoryError();
   void OnProxyBindingError();
 
   const int process_id_;
-  mojo::BindingSet<network::mojom::URLLoaderFactory> proxy_bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> proxy_receivers_;
   network::mojom::URLLoaderFactoryPtr target_factory_;
 
   // When true the loader resulting from this factory will only execute
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc b/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc
index e28a7bf..b43cdaa 100644
--- a/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc
+++ b/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.cc
@@ -128,14 +128,14 @@
 }
 
 void AwSafeBrowsingUIManager::CreateURLLoaderFactoryForIO(
-    network::mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   auto url_loader_factory_params =
       network::mojom::URLLoaderFactoryParams::New();
   url_loader_factory_params->process_id = network::mojom::kBrowserProcessId;
   url_loader_factory_params->is_corb_enabled = false;
   network_context_->GetNetworkContext()->CreateURLLoaderFactory(
-      std::move(request), std::move(url_loader_factory_params));
+      std::move(receiver), std::move(url_loader_factory_params));
 }
 
 }  // namespace android_webview
diff --git a/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.h b/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.h
index 85032ef..2b08971 100644
--- a/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.h
+++ b/android_webview/browser/safe_browsing/aw_safe_browsing_ui_manager.h
@@ -7,6 +7,7 @@
 
 #include "components/safe_browsing/base_ui_manager.h"
 #include "content/public/browser/web_contents.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 
 namespace network {
@@ -63,7 +64,7 @@
   // Called on the UI thread to create a URLLoaderFactory interface ptr for
   // the IO thread.
   void CreateURLLoaderFactoryForIO(
-      network::mojom::URLLoaderFactoryRequest request);
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver);
 
   // Provides phishing and malware statistics. Accessed on IO thread.
   std::unique_ptr<safe_browsing::PingManager> ping_manager_;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
index 7daa16f9..58ff811 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -2403,6 +2403,7 @@
     @Test
     @SmallTest
     @Feature({"AndroidWebView", "Preferences"})
+    @DisabledTest(message = "crbug.com/1010034")
     // As our implementation of network loads blocking uses the same net::URLRequest settings, make
     // sure that setting cache mode doesn't accidentally enable network loads.  The reference
     // behaviour is that when network loads are blocked, setting cache mode has no effect.
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn
index a3a164b..95e32520 100644
--- a/build/config/win/BUILD.gn
+++ b/build/config/win/BUILD.gn
@@ -61,9 +61,12 @@
     "/FS",  # Preserve previous PDB behavior.
     "/bigobj",  # Some of our files are bigger than the regular limits.
     "/utf-8",  # Assume UTF-8 by default to avoid code page dependencies.
-    "/Zc:twoPhase",
   ]
 
+  if (is_clang) {
+    cflags += [ "/Zc:twoPhase" ]
+  }
+
   # Force C/C++ mode for the given GN detected file type. This is necessary
   # for precompiled headers where the same source file is compiled in both
   # modes.
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index bc9f364..9567d8b2 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-8900019363308510144
\ No newline at end of file
+8899992290423399568
\ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index 3ae3f176..5cb0aa2 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-8900019543986013504
\ No newline at end of file
+8899994743731329152
\ No newline at end of file
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py
index 3f25061..219f7506 100755
--- a/build/vs_toolchain.py
+++ b/build/vs_toolchain.py
@@ -25,8 +25,8 @@
 
 # VS versions are listed in descending order of priority (highest first).
 MSVS_VERSIONS = collections.OrderedDict([
-  ('2017', '15.0'),
   ('2019', '16.0'),
+  ('2017', '15.0'),
 ])
 
 
@@ -417,17 +417,14 @@
   * //docs/windows_build_instructions.md mentions of VS or Windows SDK.
     Keeps the document consistent with the toolchain version.
   """
-  env_version = GetVisualStudioVersion()
-  if env_version == '2017':
-    # VS 2017 Update 9 (15.9.12) with 10.0.18362 SDK, 10.0.17763 version of
-    # Debuggers, and 10.0.17134 version of d3dcompiler_47.dll, with ARM64
-    # libraries.
-    toolchain_hash = '418b3076791776573a815eb298c8aa590307af63'
-    # Third parties that do not have access to the canonical toolchain can map
-    # canonical toolchain version to their own toolchain versions.
-    toolchain_hash_mapping_key = 'GYP_MSVS_HASH_%s' % toolchain_hash
-    return [os.environ.get(toolchain_hash_mapping_key, toolchain_hash)]
-  raise Exception('Unsupported VS version %s' % env_version)
+  # VS 2019 Update 9 (16.3.29324.140) with 10.0.18362 SDK, 10.0.17763 version of
+  # Debuggers, and 10.0.17134 version of d3dcompiler_47.dll, with ARM64
+  # libraries.
+  toolchain_hash = '8f58c55897a3282ed617055775a77ec3db771b88'
+  # Third parties that do not have access to the canonical toolchain can map
+  # canonical toolchain version to their own toolchain versions.
+  toolchain_hash_mapping_key = 'GYP_MSVS_HASH_%s' % toolchain_hash
+  return [os.environ.get(toolchain_hash_mapping_key, toolchain_hash)]
 
 
 def ShouldUpdateToolchain():
diff --git a/chrome/app/profiles_strings.grdp b/chrome/app/profiles_strings.grdp
index 55b6b74..a25a35d9 100644
--- a/chrome/app/profiles_strings.grdp
+++ b/chrome/app/profiles_strings.grdp
@@ -84,6 +84,9 @@
   <message name="IDS_PROFILES_SYNC_COMPLETE_TITLE" desc="Title of the profile card when sync is complete.">
     Syncing to
   </message>
+  <message name="IDS_PROFILES_OPEN_SYNC_SETTINGS_BUTTON" desc="Button in the profile menu to open sync settings when sync is on.">
+    Sync is on
+  </message>
   <message name="IDS_PROFILES_DICE_SIGNIN_BUTTON" desc="Button in the profile user menu to sign in and turn on Sync.">
     Turn on sync...
   </message>
@@ -118,6 +121,9 @@
     Addresses and more
   </message>
   <if expr="not use_titlecase">
+    <message name="IDS_PROFILES_OTHER_PROFILES_TITLE" desc="Title in the profile menu of the 'other profiles' section.">
+      Other people
+    </message>
     <message name="IDS_PROFILES_PROFILE_MANAGE_ACCOUNTS_BUTTON" desc="Button in the avatar menu bubble view used to manage accounts for a profile.">
       Your accounts
     </message>
@@ -135,6 +141,9 @@
     </message>
   </if>
   <if expr="use_titlecase">
+    <message name="IDS_PROFILES_OTHER_PROFILES_TITLE" desc="Title in the profile menu of the 'other profiles' section.">
+      Other People
+    </message>
     <message name="IDS_PROFILES_PROFILE_MANAGE_ACCOUNTS_BUTTON" desc="Button in the avatar menu bubble view used to manage accounts for a profile.">
       Your Accounts
     </message>
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd
index 3f8e6bf..70716c2 100644
--- a/chrome/app/theme/theme_resources.grd
+++ b/chrome/app/theme/theme_resources.grd
@@ -167,7 +167,6 @@
       <if expr="not _google_chrome">
         <structure type="chrome_scaled_image" name="IDR_PRODUCT_LOGO_16" file="chromium/product_logo_16.png" />
         <structure type="chrome_scaled_image" name="IDR_PRODUCT_LOGO_32" file="chromium/product_logo_32.png" />
-        <structure type="chrome_scaled_image" name="IDR_PRODUCT_LOGO_WHITE" file="chromium/product_logo_white.png" />
         <structure type="chrome_scaled_image" name="IDR_PRODUCT_LOGO_NAME_22" file="chromium/product_logo_name_22.png" />
       </if>
       <if expr="_google_chrome">
@@ -179,7 +178,6 @@
         <structure type="chrome_scaled_image" name="IDR_PRODUCT_LOGO_32_CANARY" file="google_chrome/product_logo_32_canary.png" />
         <structure type="chrome_scaled_image" name="IDR_PRODUCT_LOGO_32_DEV" file="google_chrome/product_logo_32_dev.png" />
         <if expr="not is_android">
-          <structure type="chrome_scaled_image" name="IDR_PRODUCT_LOGO_WHITE" file="google_chrome/product_logo_white.png" />
           <structure type="chrome_scaled_image" name="IDR_PRODUCT_LOGO_NAME_22" file="google_chrome/product_logo_name_22.png" />
         </if>
         <structure type="chrome_scaled_image" name="IDR_PRODUCT_LOGO_ENTERPRISE" file="google_chrome/product_logo_enterprise.png" />
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 64deee4..16938cb 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -3398,6 +3398,8 @@
       "sharing/sharing_app.cc",
       "sharing/sharing_app.h",
       "sharing/sharing_dialog.h",
+      "sharing/sharing_dialog_data.cc",
+      "sharing/sharing_dialog_data.h",
       "sharing/sharing_notification_handler.cc",
       "sharing/sharing_notification_handler.h",
       "sharing/sharing_ui_controller.cc",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 6ab8425..3c691cde 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -419,7 +419,6 @@
   "+third_party/blink/public/platform/web_touch_event.h",
   "+third_party/blink/public/platform/web_security_style.h",
   "+third_party/blink/public/platform/web_sudden_termination_disabler_type.h",
-  "+third_party/blink/public/platform/modules/notifications/web_notification_constants.h",
   "+third_party/blink/public/public_buildflags.h",
   "+third_party/blink/public/web/web_context_menu_data.h",
   "+third_party/blink/public/web/web_fullscreen_options.h",
diff --git a/chrome/browser/about_flags_browsertest.cc b/chrome/browser/about_flags_browsertest.cc
index 006bc75..ecb17cf 100644
--- a/chrome/browser/about_flags_browsertest.cc
+++ b/chrome/browser/about_flags_browsertest.cc
@@ -239,7 +239,8 @@
             GetOriginListText(contents, kSwitchName));
 }
 
-IN_PROC_BROWSER_TEST_P(AboutFlagsBrowserTest, OriginFlagEnabled) {
+// Flaky. http://crbug.com/1010678
+IN_PROC_BROWSER_TEST_P(AboutFlagsBrowserTest, DISABLED_OriginFlagEnabled) {
 #if !defined(OS_CHROMEOS)
   // On non-ChromeOS, the command line is modified after restart.
   EXPECT_EQ(
diff --git a/chrome/browser/android/vr/arcore_device/arcore_device.cc b/chrome/browser/android/vr/arcore_device/arcore_device.cc
index 62edd69..e3317aa18 100644
--- a/chrome/browser/android/vr/arcore_device/arcore_device.cc
+++ b/chrome/browser/android/vr/arcore_device/arcore_device.cc
@@ -157,7 +157,7 @@
 
   if (session_state_->pending_request_session_callback_) {
     DVLOG(1) << __func__ << ": Rejecting additional session request";
-    std::move(callback).Run(nullptr, nullptr);
+    std::move(callback).Run(nullptr, mojo::NullRemote());
     return;
   }
   session_state_->pending_request_session_callback_ = std::move(callback);
@@ -286,7 +286,7 @@
       std::move(session_state_->pending_request_session_callback_);
 
   if (!success) {
-    std::move(deferred_callback).Run(nullptr, nullptr);
+    std::move(deferred_callback).Run(nullptr, mojo::NullRemote());
     return;
   }
 
@@ -311,7 +311,7 @@
     mojom::XRRuntime::RequestSessionCallback deferred_callback,
     mojo::PendingRemote<mojom::XRFrameDataProvider> frame_data_provider,
     mojom::VRDisplayInfoPtr display_info,
-    mojom::XRSessionControllerPtrInfo session_controller_info,
+    mojo::PendingRemote<mojom::XRSessionController> session_controller,
     mojom::XRPresentationConnectionPtr presentation_connection) {
   DVLOG(2) << __func__;
   DCHECK(IsOnMainThread());
@@ -321,9 +321,8 @@
   session->display_info = std::move(display_info);
   session->submit_frame_sink = std::move(presentation_connection);
 
-  mojom::XRSessionControllerPtr controller(std::move(session_controller_info));
-
-  std::move(deferred_callback).Run(std::move(session), std::move(controller));
+  std::move(deferred_callback)
+      .Run(std::move(session), std::move(session_controller));
 }
 
 void ArCoreDevice::PostTaskToGlThread(base::OnceClosure task) {
diff --git a/chrome/browser/android/vr/arcore_device/arcore_device.h b/chrome/browser/android/vr/arcore_device/arcore_device.h
index ef7cd4d..8689e6a 100644
--- a/chrome/browser/android/vr/arcore_device/arcore_device.h
+++ b/chrome/browser/android/vr/arcore_device/arcore_device.h
@@ -97,7 +97,7 @@
       mojom::XRRuntime::RequestSessionCallback deferred_callback,
       mojo::PendingRemote<mojom::XRFrameDataProvider> frame_data_provider,
       mojom::VRDisplayInfoPtr display_info,
-      mojom::XRSessionControllerPtrInfo session_controller_info,
+      mojo::PendingRemote<mojom::XRSessionController> session_controller,
       mojom::XRPresentationConnectionPtr presentation_connection);
 
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
diff --git a/chrome/browser/android/vr/arcore_device/arcore_device_unittest.cc b/chrome/browser/android/vr/arcore_device/arcore_device_unittest.cc
index 63974d1..b3f75fe 100644
--- a/chrome/browser/android/vr/arcore_device/arcore_device_unittest.cc
+++ b/chrome/browser/android/vr/arcore_device/arcore_device_unittest.cc
@@ -18,6 +18,7 @@
 #include "device/vr/public/mojom/vr_service.mojom.h"
 #include "device/vr/test/fake_vr_device.h"
 #include "device/vr/test/fake_vr_service_client.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -123,11 +124,12 @@
   ArCoreDeviceTest() {}
   ~ArCoreDeviceTest() override {}
 
-  void OnSessionCreated(mojom::XRSessionPtr session,
-                        mojom::XRSessionControllerPtr controller) {
+  void OnSessionCreated(
+      mojom::XRSessionPtr session,
+      mojo::PendingRemote<mojom::XRSessionController> controller) {
     DVLOG(1) << __func__;
     session_ = std::move(session);
-    controller_ = std::move(controller);
+    controller_.Bind(std::move(controller));
     // TODO(crbug.com/837834): verify that things fail if restricted.
     // We should think through the right result here for javascript.
     // If an AR page tries to hittest while not focused, should it
@@ -211,7 +213,7 @@
  private:
   std::unique_ptr<ArCoreDevice> device_;
   mojom::XRSessionPtr session_;
-  mojom::XRSessionControllerPtr controller_;
+  mojo::Remote<mojom::XRSessionController> controller_;
 };
 
 TEST_F(ArCoreDeviceTest, RequestSession) {
diff --git a/chrome/browser/android/vr/arcore_device/arcore_gl.cc b/chrome/browser/android/vr/arcore_device/arcore_gl.cc
index ad757db..d7e3146 100644
--- a/chrome/browser/android/vr/arcore_device/arcore_gl.cc
+++ b/chrome/browser/android/vr/arcore_device/arcore_gl.cc
@@ -104,7 +104,6 @@
     : gl_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
       ar_image_transport_(std::move(ar_image_transport)),
       webxr_(std::make_unique<vr::WebXrPresentationState>()),
-      session_controller_binding_(this),
       environment_binding_(this) {
   DVLOG(1) << __func__;
   webxr_transform_ = WebXRImageTransformMatrix();
@@ -176,11 +175,6 @@
 
   CloseBindingsIfOpen();
 
-  mojom::XRSessionControllerPtrInfo controller_info;
-  session_controller_binding_.Bind(mojo::MakeRequest(&controller_info));
-  session_controller_binding_.set_connection_error_handler(base::BindOnce(
-      &ArCoreGl::OnBindingDisconnect, weak_ptr_factory_.GetWeakPtr()));
-
   device::mojom::XRPresentationTransportOptionsPtr transport_options =
       device::mojom::XRPresentationTransportOptions::New();
   transport_options->wait_for_gpu_fence = true;
@@ -203,11 +197,14 @@
 
   std::move(create_callback)
       .Run(frame_data_receiver_.BindNewPipeAndPassRemote(),
-           display_info_->Clone(), std::move(controller_info),
+           display_info_->Clone(),
+           session_controller_receiver_.BindNewPipeAndPassRemote(),
            std::move(submit_frame_sink));
 
   frame_data_receiver_.set_disconnect_handler(base::BindOnce(
       &ArCoreGl::OnBindingDisconnect, weak_ptr_factory_.GetWeakPtr()));
+  session_controller_receiver_.set_disconnect_handler(base::BindOnce(
+      &ArCoreGl::OnBindingDisconnect, weak_ptr_factory_.GetWeakPtr()));
 }
 
 bool ArCoreGl::InitializeGl(gfx::AcceleratedWidget drawing_widget) {
@@ -805,7 +802,7 @@
 
   environment_binding_.Close();
   frame_data_receiver_.reset();
-  session_controller_binding_.Close();
+  session_controller_receiver_.reset();
   presentation_receiver_.reset();
 }
 
diff --git a/chrome/browser/android/vr/arcore_device/arcore_gl.h b/chrome/browser/android/vr/arcore_device/arcore_gl.h
index 57fc289..6607816 100644
--- a/chrome/browser/android/vr/arcore_device/arcore_gl.h
+++ b/chrome/browser/android/vr/arcore_device/arcore_gl.h
@@ -18,7 +18,6 @@
 #include "device/vr/public/mojom/vr_service.mojom.h"
 #include "device/vr/util/fps_meter.h"
 #include "mojo/public/cpp/bindings/associated_binding.h"
-#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -53,7 +52,7 @@
 using ArCoreGlCreateSessionCallback = base::OnceCallback<void(
     mojo::PendingRemote<mojom::XRFrameDataProvider> frame_data_provider,
     mojom::VRDisplayInfoPtr display_info,
-    mojom::XRSessionControllerPtrInfo session_controller_info,
+    mojo::PendingRemote<mojom::XRSessionController> session_controller,
     mojom::XRPresentationConnectionPtr presentation_connection)>;
 
 // All of this class's methods must be called on the same valid GL thread with
@@ -203,7 +202,7 @@
   std::vector<std::unique_ptr<ArCoreHitTestRequest>> hit_test_requests_;
 
   mojo::Receiver<mojom::XRFrameDataProvider> frame_data_receiver_{this};
-  mojo::Binding<mojom::XRSessionController> session_controller_binding_;
+  mojo::Receiver<mojom::XRSessionController> session_controller_receiver_{this};
   mojo::AssociatedBinding<mojom::XREnvironmentIntegrationProvider>
       environment_binding_;
 
diff --git a/chrome/browser/banners/app_banner_ui_delegate_android.cc b/chrome/browser/banners/app_banner_ui_delegate_android.cc
index e42e450..426fccc 100644
--- a/chrome/browser/banners/app_banner_ui_delegate_android.cc
+++ b/chrome/browser/banners/app_banner_ui_delegate_android.cc
@@ -295,10 +295,8 @@
   AppBannerSettingsHelper::RecordBannerInstallEvent(
       web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB);
 
-  // TODO(https://crbug.com/861643): Support maskable icons here.
-  ShortcutHelper::AddToLauncherWithSkBitmap(web_contents, *shortcut_info_,
-                                            primary_icon_,
-                                            /*is_icon_maskable=*/false);
+  ShortcutHelper::AddToLauncherWithSkBitmap(
+      web_contents, *shortcut_info_, primary_icon_, has_primary_maskable_icon_);
 }
 
 void AppBannerUiDelegateAndroid::SendBannerAccepted() {
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
index 35d7730..4eca632 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.cc
@@ -853,6 +853,9 @@
           nullable_filter, delete_begin_, delete_end_,
           base::AdaptCallbackForRepeating(CreateTaskCompletionClosure(
               TracingDataType::kPasswordsStatistics)));
+      password_store->RemoveLeakedCredentialsByUrlAndTime(
+          nullable_filter, delete_begin_, delete_end_,
+          CreateTaskCompletionClosure(TracingDataType::kLeakedCredentials));
     }
   }
 
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h
index 9b0ec7e..56a73802 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate.h
@@ -226,7 +226,8 @@
     kHostCache = 29,
     kTpmAttestationKeys = 30,
     kStrikes = 31,
-    kMaxValue = kStrikes,
+    kLeakedCredentials = 32,
+    kMaxValue = kLeakedCredentials,
   };
 
   // Called by CreateTaskCompletionClosure().
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
index dc3a436..aad86bf 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_delegate_unittest.cc
@@ -1995,6 +1995,38 @@
 }
 
 TEST_F(ChromeBrowsingDataRemoverDelegateTest,
+       RemoveLeakedCredentialsByTimeOnly) {
+  RemovePasswordsTester tester(GetProfile());
+  base::Callback<bool(const GURL&)> empty_filter;
+
+  EXPECT_CALL(*tester.store(), RemoveLeakedCredentialsByUrlAndTimeImpl(
+                                   ProbablySameFilter(empty_filter),
+                                   base::Time(), base::Time::Max()));
+  BlockUntilBrowsingDataRemoved(
+      base::Time(), base::Time::Max(),
+      ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, false);
+}
+
+// TODO(crbug.com/589586): Disabled, since history is not yet marked as
+// a filterable datatype.
+TEST_F(ChromeBrowsingDataRemoverDelegateTest,
+       DISABLED_RemoveLeakedCredentialsByUrlAndTime) {
+  RemovePasswordsTester tester(GetProfile());
+  auto builder =
+      BrowsingDataFilterBuilder::Create(BrowsingDataFilterBuilder::WHITELIST);
+  builder->AddRegisterableDomain(kTestRegisterableDomain1);
+  base::RepeatingCallback<bool(const GURL&)> filter =
+      builder->BuildGeneralFilter();
+
+  EXPECT_CALL(*tester.store(),
+              RemoveLeakedCredentialsByUrlAndTimeImpl(
+                  ProbablySameFilter(filter), base::Time(), base::Time::Max()));
+  BlockUntilOriginDataRemoved(
+      base::Time(), base::Time::Max(),
+      ChromeBrowsingDataRemoverDelegate::DATA_TYPE_HISTORY, std::move(builder));
+}
+
+TEST_F(ChromeBrowsingDataRemoverDelegateTest,
        RemoveContentSettingsWithBlacklist) {
   // Add our settings.
   HostContentSettingsMap* host_content_settings_map =
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index c162d840..abc1c93 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -309,10 +309,10 @@
 #include "media/base/media_switches.h"
 #include "media/media_buildflags.h"
 #include "media/mojo/buildflags.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
 #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/scoped_interface_endpoint_handle.h"
 #include "net/base/load_flags.h"
@@ -4604,12 +4604,13 @@
                                  /* allow_directory_listing */ true);
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest loader) override {
-    bindings_.AddBinding(this, std::move(loader));
+  void Clone(
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) override {
+    receivers_.Add(this, std::move(loader));
   }
 
   int child_id_;
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
   DISALLOW_COPY_AND_ASSIGN(FileURLLoaderFactory);
 };
 
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 82289408..dfd9b23 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -208,6 +208,7 @@
     "//components/storage_monitor",
     "//components/strings",
     "//components/sync",
+    "//components/sync_device_info",
     "//components/sync_preferences",
     "//components/tracing:startup_tracing",
     "//components/translate/core/browser",
@@ -455,8 +456,6 @@
     "arc/arc_optin_uma.h",
     "arc/arc_support_host.cc",
     "arc/arc_support_host.h",
-    "arc/arc_ui_availability_reporter.cc",
-    "arc/arc_ui_availability_reporter.h",
     "arc/arc_util.cc",
     "arc/arc_util.h",
     "arc/arc_web_contents_data.cc",
@@ -811,10 +810,10 @@
     "crostini/crosvm_process_list.h",
     "crostini/fake_crostini_installer_ui_delegate.cc",
     "crostini/fake_crostini_installer_ui_delegate.h",
-    "crostini/throttle/crostini_throttle.cc",
-    "crostini/throttle/crostini_throttle.h",
     "crostini/throttle/crostini_active_window_throttle_observer.cc",
     "crostini/throttle/crostini_active_window_throttle_observer.h",
+    "crostini/throttle/crostini_throttle.cc",
+    "crostini/throttle/crostini_throttle.h",
     "cryptauth/client_app_metadata_provider_service.cc",
     "cryptauth/client_app_metadata_provider_service.h",
     "cryptauth/client_app_metadata_provider_service_factory.cc",
@@ -2449,7 +2448,6 @@
     "arc/app_shortcuts/arc_app_shortcuts_request_unittest.cc",
     "arc/arc_migration_guide_notification_unittest.cc",
     "arc/arc_support_host_unittest.cc",
-    "arc/arc_ui_availability_reporter_unittest.cc",
     "arc/arc_util_unittest.cc",
     "arc/bluetooth/arc_bluetooth_bridge_unittest.cc",
     "arc/bluetooth/arc_bluetooth_task_queue_unittest.cc",
@@ -2544,8 +2542,8 @@
     "crostini/crostini_unsupported_action_notifier_unittest.cc",
     "crostini/crosvm_metrics_unittest.cc",
     "crostini/crosvm_process_list_unittest.cc",
-    "crostini/throttle/crostini_throttle_unittest.cc",
     "crostini/throttle/crostini_active_window_throttle_observer_unittest.cc",
+    "crostini/throttle/crostini_throttle_unittest.cc",
     "cryptauth/client_app_metadata_provider_service_unittest.cc",
     "customization/customization_document_unittest.cc",
     "dbus/proxy_resolution_service_provider_unittest.cc",
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.cc b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.cc
index d9867d23..ca10087 100644
--- a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.cc
+++ b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl.cc
@@ -29,6 +29,7 @@
 #include "extensions/browser/uninstall_reason.h"
 #include "net/base/url_util.h"
 #include "services/network/public/mojom/cookie_manager.mojom.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 #include "url/gurl.h"
 
 namespace chromeos {
@@ -231,7 +232,7 @@
                   << "Trying to install PWA for " << install_url
                   << ". Num attempts so far # " << num_attempts_so_far;
   web_app::ExternalInstallOptions options(
-      install_url, web_app::LaunchContainer::kWindow,
+      install_url, blink::mojom::DisplayMode::kStandalone,
       web_app::ExternalInstallSource::kInternalDefault);
   options.override_previous_user_uninstall = true;
   // The ServiceWorker does not load in time for the installability check, so
diff --git a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc
index 9782339..b75658b 100644
--- a/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc
+++ b/chrome/browser/chromeos/android_sms/android_sms_app_setup_controller_impl_unittest.cc
@@ -31,6 +31,7 @@
 #include "extensions/common/extension_paths.h"
 #include "services/network/test/test_cookie_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 
 namespace chromeos {
 
@@ -44,7 +45,7 @@
 
 web_app::ExternalInstallOptions GetInstallOptionsForUrl(const GURL& url) {
   web_app::ExternalInstallOptions options(
-      url, web_app::LaunchContainer::kWindow,
+      url, blink::mojom::DisplayMode::kStandalone,
       web_app::ExternalInstallSource::kInternalDefault);
   options.override_previous_user_uninstall = true;
   options.bypass_service_worker_check = true;
diff --git a/chrome/browser/chromeos/arc/arc_optin_uma.cc b/chrome/browser/chromeos/arc/arc_optin_uma.cc
index 44656044..140506c 100644
--- a/chrome/browser/chromeos/arc/arc_optin_uma.cc
+++ b/chrome/browser/chromeos/arc/arc_optin_uma.cc
@@ -119,24 +119,8 @@
       base::TimeDelta::FromMinutes(10), 50);
 }
 
-void UpdateArcUiAvailableTime(const base::TimeDelta& elapsed_time,
-                              const std::string& mode,
-                              const Profile* profile) {
-  base::UmaHistogramCustomTimes(
-      GetHistogramNameByUserType("Arc.UiAvailable." + mode + ".TimeDelta",
-                                 profile),
-      elapsed_time, base::TimeDelta::FromSeconds(1),
-      base::TimeDelta::FromMinutes(5), 50);
-}
-
-void UpdatePlayStoreLaunchTime(const base::TimeDelta& elapsed_time) {
-  base::UmaHistogramCustomTimes("Arc.PlayStoreLaunch.TimeDelta", elapsed_time,
-                                base::TimeDelta::FromMilliseconds(10),
-                                base::TimeDelta::FromSeconds(20), 50);
-}
-
-void UpdatePlayStoreShownTimeDeprecated(const base::TimeDelta& elapsed_time,
-                                        const Profile* profile) {
+void UpdatePlayStoreShowTime(const base::TimeDelta& elapsed_time,
+                             const Profile* profile) {
   base::UmaHistogramCustomTimes(
       GetHistogramNameByUserType("Arc.PlayStoreShown.TimeDelta", profile),
       elapsed_time, base::TimeDelta::FromSeconds(1),
diff --git a/chrome/browser/chromeos/arc/arc_optin_uma.h b/chrome/browser/chromeos/arc/arc_optin_uma.h
index bf0a02f..991e32ea 100644
--- a/chrome/browser/chromeos/arc/arc_optin_uma.h
+++ b/chrome/browser/chromeos/arc/arc_optin_uma.h
@@ -238,14 +238,8 @@
                                        const Profile* profile);
 void UpdatePlayAutoInstallRequestTime(const base::TimeDelta& elapsed_time,
                                       const Profile* profile);
-void UpdateArcUiAvailableTime(const base::TimeDelta& elapsed_time,
-                              const std::string& mode,
-                              const Profile* profile);
-void UpdatePlayStoreLaunchTime(const base::TimeDelta& elapsed_time);
-// TODO(khmel): Remove this in favor of UpdateArcUiAvailableTime once it is
-// rolled and has confirmed usability.
-void UpdatePlayStoreShownTimeDeprecated(const base::TimeDelta& elapsed_time,
-                                        const Profile* profile);
+void UpdatePlayStoreShowTime(const base::TimeDelta& elapsed_time,
+                             const Profile* profile);
 void UpdateSilentAuthCodeUMA(OptInSilentAuthCode state);
 void UpdateSupervisionTransitionResultUMA(
     mojom::SupervisionChangeStatus result);
diff --git a/chrome/browser/chromeos/arc/arc_ui_availability_reporter.cc b/chrome/browser/chromeos/arc/arc_ui_availability_reporter.cc
deleted file mode 100644
index adb52f07..0000000
--- a/chrome/browser/chromeos/arc/arc_ui_availability_reporter.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2019 The Chromium 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 "chrome/browser/chromeos/arc/arc_ui_availability_reporter.h"
-
-#include "chrome/browser/chromeos/arc/arc_optin_uma.h"
-#include "components/arc/arc_service_manager.h"
-#include "components/arc/session/arc_bridge_service.h"
-
-namespace arc {
-
-class ArcUiAvailabilityReporter::ConnectionNotifierBase {
- public:
-  virtual ~ConnectionNotifierBase() = default;
-
-  // Returns true if connection is ready.
-  virtual bool IsConnected() = 0;
-
- protected:
-  explicit ConnectionNotifierBase(ArcUiAvailabilityReporter* owner)
-      : owner_(owner) {}
-
-  ArcUiAvailabilityReporter* owner() { return owner_; }
-
- private:
-  ArcUiAvailabilityReporter* const owner_;
-
-  DISALLOW_COPY_AND_ASSIGN(ConnectionNotifierBase);
-};
-
-namespace {
-
-template <typename InstanceType, typename HostType>
-class ConnectionNotifier
-    : public ArcUiAvailabilityReporter::ConnectionNotifierBase,
-      public ConnectionObserver<InstanceType> {
- public:
-  // |owner_| owns this object and |ConnectionNotifier| is destroyed in case
-  // statistics is reported or ARC session is terminated on user log-out and
-  // this automatically destroys this object at time of destroying |owner_|.
-  // |holder_| is owned by ArcBridgeService this lives longer than
-  // |ArcUiAvailabilityReporter|.
-  ConnectionNotifier(ArcUiAvailabilityReporter* owner,
-                     ConnectionHolder<InstanceType, HostType>* holder)
-      : ArcUiAvailabilityReporter::ConnectionNotifierBase(owner),
-        holder_(holder) {
-    DCHECK(!holder_->IsConnected());
-    holder_->AddObserver(this);
-  }
-
-  ~ConnectionNotifier() override { holder_->RemoveObserver(this); }
-
-  // ArcUiAvailabilityReporter::ConnectionNotifierBase:
-  bool IsConnected() override { return holder_->IsConnected(); }
-
-  // ConnectionObserver<InstanceType>:
-  void OnConnectionReady() override { owner()->MaybeReport(); }
-
- private:
-  ConnectionHolder<InstanceType, HostType>* const holder_;
-
-  DISALLOW_COPY_AND_ASSIGN(ConnectionNotifier);
-};
-
-}  // namespace
-
-ArcUiAvailabilityReporter::ArcUiAvailabilityReporter(Profile* profile,
-                                                     Mode mode)
-    : profile_(profile), mode_(mode), start_ticks_(base::TimeTicks::Now()) {
-  DCHECK(profile);
-  // Some unit tests may not have |ArcServiceManager| set.
-  ArcServiceManager* const service_manager = ArcServiceManager::Get();
-  if (!service_manager)
-    return;
-  // |initiated_from_oobe| must be set only if |initial_start| is set.
-  auto* const arc_bridge = ArcServiceManager::Get()->arc_bridge_service();
-  // Not expected instances are connected at the time of creation, however this
-  // is not always preserved in tests.
-  if (arc_bridge->app()->IsConnected() ||
-      arc_bridge->intent_helper()->IsConnected()) {
-    LOG(ERROR) << "App and/or intent_helper instances are already connected. "
-               << "This is not expected in production.";
-    return;
-  }
-
-  connection_notifiers_.emplace_back(
-      std::make_unique<ConnectionNotifier<mojom::AppInstance, mojom::AppHost>>(
-          this, arc_bridge->app()));
-  connection_notifiers_.emplace_back(
-      std::make_unique<ConnectionNotifier<mojom::IntentHelperInstance,
-                                          mojom::IntentHelperHost>>(
-          this, arc_bridge->intent_helper()));
-}
-
-ArcUiAvailabilityReporter::~ArcUiAvailabilityReporter() = default;
-
-// static
-std::string ArcUiAvailabilityReporter::GetHistogramNameForMode(Mode mode) {
-  switch (mode) {
-    case Mode::kOobeProvisioning:
-      return "OobeProvisioning";
-    case Mode::kInSessionProvisioning:
-      return "InSessionProvisioning";
-    case Mode::kAlreadyProvisioned:
-      return "AlreadyProvisioned";
-  }
-}
-
-void ArcUiAvailabilityReporter::MaybeReport() {
-  DCHECK(!connection_notifiers_.empty());
-
-  // Check that all tracked instance are connected.
-  for (const auto& connection_notifier : connection_notifiers_) {
-    if (!connection_notifier->IsConnected())
-      return;
-  }
-
-  UpdateArcUiAvailableTime(base::TimeTicks::Now() - start_ticks_,
-                           GetHistogramNameForMode(mode_), profile_);
-
-  // No more reporting is expected.
-  connection_notifiers_.clear();
-}
-
-}  // namespace arc
diff --git a/chrome/browser/chromeos/arc/arc_ui_availability_reporter.h b/chrome/browser/chromeos/arc/arc_ui_availability_reporter.h
deleted file mode 100644
index f5d73ea3..0000000
--- a/chrome/browser/chromeos/arc/arc_ui_availability_reporter.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_CHROMEOS_ARC_ARC_UI_AVAILABILITY_REPORTER_H_
-#define CHROME_BROWSER_CHROMEOS_ARC_ARC_UI_AVAILABILITY_REPORTER_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/time/time.h"
-
-class Profile;
-
-namespace arc {
-
-// Helper class that reports ARC UI availability to UMA. It observes major UI
-// instances are all connected.
-class ArcUiAvailabilityReporter {
- public:
-  // Helper that notifies |ArcUiAvailabilityReporter| that connection is ready.
-  class ConnectionNotifierBase;
-
-  enum class Mode {
-    kOobeProvisioning,
-    kInSessionProvisioning,
-    kAlreadyProvisioned
-  };
-
-  ArcUiAvailabilityReporter(Profile* profile, Mode mode);
-  ~ArcUiAvailabilityReporter();
-
-  static std::string GetHistogramNameForMode(Mode mode);
-
-  // Called when any tracked instance is connected.
-  void MaybeReport();
-
- private:
-  Profile* const profile_;
-  const Mode mode_;
-  const base::TimeTicks start_ticks_;
-
-  std::vector<std::unique_ptr<ConnectionNotifierBase>> connection_notifiers_;
-
-  DISALLOW_COPY_AND_ASSIGN(ArcUiAvailabilityReporter);
-};
-
-}  // namespace arc
-
-#endif  // CHROME_BROWSER_CHROMEOS_ARC_ARC_UI_AVAILABILITY_REPORTER_H_
diff --git a/chrome/browser/chromeos/arc/arc_ui_availability_reporter_unittest.cc b/chrome/browser/chromeos/arc/arc_ui_availability_reporter_unittest.cc
deleted file mode 100644
index 60e3571..0000000
--- a/chrome/browser/chromeos/arc/arc_ui_availability_reporter_unittest.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2019 The Chromium 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 "chrome/browser/chromeos/arc/arc_ui_availability_reporter.h"
-#include "base/metrics/histogram_samples.h"
-#include "base/metrics/statistics_recorder.h"
-#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
-#include "chrome/browser/ui/app_list/arc/arc_app_test.h"
-#include "chrome/test/base/testing_profile.h"
-#include "components/arc/arc_service_manager.h"
-#include "components/arc/arc_util.h"
-#include "components/arc/intent_helper/arc_intent_helper_bridge.h"
-#include "components/arc/session/arc_bridge_service.h"
-#include "components/arc/test/fake_app_instance.h"
-#include "components/arc/test/fake_intent_helper_instance.h"
-#include "content/public/test/browser_task_environment.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace arc {
-
-namespace {
-
-using Mode = ArcUiAvailabilityReporter::Mode;
-
-const base::HistogramBase* GetHistogram(Mode mode) {
-  return base::StatisticsRecorder::FindHistogram(
-      "Arc.UiAvailable." +
-      ArcUiAvailabilityReporter::GetHistogramNameForMode(mode) +
-      ".TimeDelta.Unmanaged");
-}
-
-int64_t ReadSingleStatistics(Mode mode) {
-  const base::HistogramBase* histogram = GetHistogram(mode);
-  DCHECK(histogram);
-
-  std::unique_ptr<base::HistogramSamples> samples =
-      histogram->SnapshotFinalDelta();
-  DCHECK(samples.get());
-  // Expected reported only once.
-  DCHECK_EQ(1, samples->TotalCount());
-  return samples->sum();
-}
-
-}  // namespace
-
-class ArcUiAvailabilityReporterTest : public testing::Test {
- public:
-  ArcUiAvailabilityReporterTest() {}
-  ~ArcUiAvailabilityReporterTest() override = default;
-
-  void SetUp() override {
-    testing::Test::SetUp();
-    arc::SetArcAvailableCommandLineForTesting(
-        base::CommandLine::ForCurrentProcess());
-    // arc_service_manager_ = std::make_unique<arc::ArcServiceManager>();
-    profile_ = TestingProfile::Builder().Build();
-
-    // Use ArcAppTest to initialize infrastructure.
-    arc_app_test_.set_activate_arc_on_start(false);
-    arc_app_test_.SetUp(profile());
-    app_instance_ = std::make_unique<FakeAppInstance>(
-        arc_app_test_.arc_app_list_prefs() /* app_host */);
-    intent_helper_instance_ = std::make_unique<FakeIntentHelperInstance>();
-    arc_intent_helper_bridge_ = std::make_unique<ArcIntentHelperBridge>(
-        profile(), arc_bridge_service());
-  }
-
-  void TearDown() override {
-    arc_intent_helper_bridge_.reset();
-    intent_helper_instance_.reset();
-    app_instance_.reset();
-    arc_app_test_.TearDown();
-    profile_.reset();
-    // arc_service_manager_.reset();
-    testing::Test::TearDown();
-  }
-
-  TestingProfile* profile() { return profile_.get(); }
-
-  ArcBridgeService* arc_bridge_service() {
-    return ArcServiceManager::Get()->arc_bridge_service();
-  }
-
-  FakeAppInstance* app_instance() { return app_instance_.get(); }
-
-  FakeIntentHelperInstance* intent_helper_instance() {
-    return intent_helper_instance_.get();
-  }
-
- private:
-  content::BrowserTaskEnvironment task_environment_;
-  // std::unique_ptr<arc::ArcServiceManager> arc_service_manager_;
-  std::unique_ptr<TestingProfile> profile_;
-  ArcAppTest arc_app_test_;
-  std::unique_ptr<ArcIntentHelperBridge> arc_intent_helper_bridge_;
-  std::unique_ptr<FakeAppInstance> app_instance_;
-  std::unique_ptr<FakeIntentHelperInstance> intent_helper_instance_;
-
-  DISALLOW_COPY_AND_ASSIGN(ArcUiAvailabilityReporterTest);
-};
-
-// Reporting is triggered in case both instances are connected.
-TEST_F(ArcUiAvailabilityReporterTest, Basic) {
-  ArcUiAvailabilityReporter reporter(profile(), Mode::kOobeProvisioning);
-  // No reporting at this time.
-  EXPECT_FALSE(GetHistogram(Mode::kOobeProvisioning));
-  arc_bridge_service()->app()->SetInstance(app_instance());
-  EXPECT_FALSE(GetHistogram(Mode::kOobeProvisioning));
-  arc_bridge_service()->intent_helper()->SetInstance(intent_helper_instance());
-  EXPECT_GE(ReadSingleStatistics(Mode::kOobeProvisioning), 0);
-  EXPECT_FALSE(GetHistogram(Mode::kInSessionProvisioning));
-  EXPECT_FALSE(GetHistogram(Mode::kAlreadyProvisioned));
-}
-
-// Reporting is triggered only once, even if instances are reconnected.
-TEST_F(ArcUiAvailabilityReporterTest, TriggeredOnce) {
-  ArcUiAvailabilityReporter reporter(profile(), Mode::kAlreadyProvisioned);
-  arc_bridge_service()->app()->SetInstance(app_instance());
-  arc_bridge_service()->intent_helper()->SetInstance(intent_helper_instance());
-  arc_bridge_service()->app()->CloseInstance(app_instance());
-  arc_bridge_service()->intent_helper()->CloseInstance(
-      intent_helper_instance());
-  arc_bridge_service()->app()->SetInstance(app_instance());
-  arc_bridge_service()->intent_helper()->SetInstance(intent_helper_instance());
-  EXPECT_GE(ReadSingleStatistics(Mode::kAlreadyProvisioned), 0);
-}
-
-// Reporting is triggered even if instance restart happened.
-TEST_F(ArcUiAvailabilityReporterTest, InstanceRestartAllowed) {
-  ArcUiAvailabilityReporter reporter(profile(), Mode::kInSessionProvisioning);
-  arc_bridge_service()->app()->SetInstance(app_instance());
-  arc_bridge_service()->app()->CloseInstance(app_instance());
-  arc_bridge_service()->intent_helper()->SetInstance(intent_helper_instance());
-  arc_bridge_service()->app()->SetInstance(app_instance());
-  EXPECT_GE(ReadSingleStatistics(Mode::kInSessionProvisioning), 0);
-}
-
-}  // namespace arc
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog.cc b/chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog.cc
index 04992c9..63a3dbf 100644
--- a/chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog.cc
+++ b/chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog.cc
@@ -5,8 +5,6 @@
 #include "chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog.h"
 
 #include <map>
-#include <memory>
-#include <string>
 
 #include "base/bind.h"
 #include "base/memory/ref_counted.h"
@@ -27,6 +25,7 @@
 #include "components/arc/arc_service_manager.h"
 #include "components/arc/session/arc_bridge_service.h"
 #include "components/sync/protocol/sync.pb.h"
+#include "components/sync_device_info/device_info.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/page_navigator.h"
@@ -56,6 +55,13 @@
 // Size of device icons in DIPs.
 constexpr int kDeviceIconSize = 16;
 
+using IntentPickerResponseWithDevices = base::OnceCallback<void(
+    std::vector<std::unique_ptr<syncer::DeviceInfo>> devices,
+    const std::string& launch_name,
+    apps::PickerEntryType entry_type,
+    apps::IntentPickerCloseReason close_reason,
+    bool should_persist)>;
+
 // Creates an icon for a specific |device_type|.
 gfx::Image CreateDeviceIcon(const sync_pb::SyncEnums::DeviceType device_type) {
   SkColor color = ui::NativeTheme::GetInstanceForNativeUi()->GetSystemColor(
@@ -96,7 +102,7 @@
     std::vector<apps::IntentPickerAppInfo> app_info,
     bool stay_in_chrome,
     bool show_remember_selection,
-    IntentPickerResponse callback) {
+    IntentPickerResponseWithDevices callback) {
   Browser* browser =
       web_contents ? chrome::FindBrowserWithWebContents(web_contents) : nullptr;
   if (!browser)
@@ -107,14 +113,13 @@
 
   PageActionIconType icon_type = PageActionIconType::kIntentPicker;
   ClickToCallUiController* controller = nullptr;
+  std::vector<std::unique_ptr<syncer::DeviceInfo>> devices;
 
   if (ShouldOfferClickToCallForURL(web_contents->GetBrowserContext(), url)) {
     icon_type = PageActionIconType::kClickToCall;
     controller =
         ClickToCallUiController::GetOrCreateFromWebContents(web_contents);
-    controller->UpdateDevices();
-
-    const auto& devices = controller->devices();
+    devices = controller->GetDevices();
     has_devices = !devices.empty();
     if (has_devices)
       app_info = AddDevices(devices, std::move(app_info));
@@ -127,7 +132,7 @@
       web_contents, icon_type == PageActionIconType::kIntentPicker);
   browser->window()->ShowIntentPickerBubble(
       std::move(app_info), stay_in_chrome, show_remember_selection, icon_type,
-      base::BindOnce(std::move(callback)));
+      base::BindOnce(std::move(callback), std::move(devices)));
 
   if (controller)
     controller->OnDialogShown(has_devices, has_apps);
@@ -369,24 +374,23 @@
   return true;
 }
 
-void HandleDeviceSelection(WebContents* web_contents,
-                           const std::string& device_guid,
-                           const GURL& url) {
+void HandleDeviceSelection(
+    WebContents* web_contents,
+    const std::vector<std::unique_ptr<syncer::DeviceInfo>>& devices,
+    const std::string& device_guid,
+    const GURL& url) {
   if (!web_contents)
     return;
-  ClickToCallUiController* controller =
-      ClickToCallUiController::GetOrCreateFromWebContents(web_contents);
-  if (!controller)
-    return;
 
-  for (const auto& device : controller->devices()) {
+  for (const auto& device : devices) {
     if (device->guid() == device_guid) {
-      controller->OnDeviceSelected(
-          GetUnescapedURLContent(url), *device,
-          SharingClickToCallEntryPoint::kLeftClickLink);
-      break;
+      ClickToCallUiController::GetOrCreateFromWebContents(web_contents)
+          ->OnDeviceSelected(GetUnescapedURLContent(url), *device,
+                             SharingClickToCallEntryPoint::kLeftClickLink);
+      return;
     }
   }
+  NOTREACHED();
 }
 
 // Handles |url| if possible. Returns true if it is actually handled.
@@ -461,15 +465,17 @@
 
 // Called when the dialog is closed. Note that once we show the UI, we should
 // never show the Chrome OS' fallback dialog.
-void OnIntentPickerClosed(int render_process_host_id,
-                          int routing_id,
-                          const GURL& url,
-                          bool safe_to_bypass_ui,
-                          std::vector<mojom::IntentHandlerInfoPtr> handlers,
-                          const std::string& selected_app_package,
-                          apps::PickerEntryType entry_type,
-                          apps::IntentPickerCloseReason reason,
-                          bool should_persist) {
+void OnIntentPickerClosed(
+    int render_process_host_id,
+    int routing_id,
+    const GURL& url,
+    bool safe_to_bypass_ui,
+    std::vector<mojom::IntentHandlerInfoPtr> handlers,
+    std::vector<std::unique_ptr<syncer::DeviceInfo>> devices,
+    const std::string& selected_app_package,
+    apps::PickerEntryType entry_type,
+    apps::IntentPickerCloseReason reason,
+    bool should_persist) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   // Even if ArcExternalProtocolDialog shares the same icon on the omnibox as an
@@ -485,7 +491,7 @@
   if (entry_type == apps::PickerEntryType::kDevice) {
     DCHECK_EQ(apps::IntentPickerCloseReason::OPEN_APP, reason);
     DCHECK(!should_persist);
-    HandleDeviceSelection(web_contents, selected_app_package, url);
+    HandleDeviceSelection(web_contents, devices, selected_app_package, url);
     RecordUmaDialogAction(Scheme::TEL, entry_type, /*accepted=*/true,
                           should_persist);
     chromeos::ChromeOsAppsNavigationThrottle::RecordUma(
@@ -792,6 +798,23 @@
   return IsChromeAnAppCandidate(handlers);
 }
 
+void OnIntentPickerClosedForTesting(
+    int render_process_host_id,
+    int routing_id,
+    const GURL& url,
+    bool safe_to_bypass_ui,
+    std::vector<mojom::IntentHandlerInfoPtr> handlers,
+    std::vector<std::unique_ptr<syncer::DeviceInfo>> devices,
+    const std::string& selected_app_package,
+    apps::PickerEntryType entry_type,
+    apps::IntentPickerCloseReason reason,
+    bool should_persist) {
+  OnIntentPickerClosed(render_process_host_id, routing_id, url,
+                       safe_to_bypass_ui, std::move(handlers),
+                       std::move(devices), selected_app_package, entry_type,
+                       reason, should_persist);
+}
+
 void RecordUmaDialogAction(Scheme scheme,
                            apps::PickerEntryType entry_type,
                            bool accepted,
@@ -800,12 +823,10 @@
       GetProtocolAction(scheme, entry_type, accepted, persisted);
   if (accepted) {
     base::UmaHistogramEnumeration(
-        "ChromeOS.Apps.ExternalProtocolDialog.Accepted", action,
-        ProtocolAction::kMaxValue);
+        "ChromeOS.Apps.ExternalProtocolDialog.Accepted", action);
   } else {
     base::UmaHistogramEnumeration(
-        "ChromeOS.Apps.ExternalProtocolDialog.Rejected", action,
-        ProtocolAction::kMaxValue);
+        "ChromeOS.Apps.ExternalProtocolDialog.Rejected", action);
   }
 }
 
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog.h b/chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog.h
index c7cadba..8043696 100644
--- a/chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog.h
+++ b/chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_CHROMEOS_ARC_INTENT_HELPER_ARC_EXTERNAL_PROTOCOL_DIALOG_H_
 #define CHROME_BROWSER_CHROMEOS_ARC_INTENT_HELPER_ARC_EXTERNAL_PROTOCOL_DIALOG_H_
 
+#include <memory>
+#include <string>
 #include <utility>
 #include <vector>
 
@@ -19,6 +21,10 @@
 class WebContents;
 }  // namespace content
 
+namespace syncer {
+class DeviceInfo;
+}  // namespace syncer
+
 namespace arc {
 
 using GurlAndActivityInfo =
@@ -153,6 +159,18 @@
                                  bool accepted,
                                  bool persisted);
 
+void OnIntentPickerClosedForTesting(
+    int render_process_host_id,
+    int routing_id,
+    const GURL& url,
+    bool safe_to_bypass_ui,
+    std::vector<mojom::IntentHandlerInfoPtr> handlers,
+    std::vector<std::unique_ptr<syncer::DeviceInfo>> devices,
+    const std::string& selected_app_package,
+    apps::PickerEntryType entry_type,
+    apps::IntentPickerCloseReason reason,
+    bool should_persist);
+
 }  // namespace arc
 
 #endif  // CHROME_BROWSER_CHROMEOS_ARC_INTENT_HELPER_ARC_EXTERNAL_PROTOCOL_DIALOG_H_
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog_unittest.cc b/chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog_unittest.cc
index 0ed28c25..ea95c7c 100644
--- a/chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog_unittest.cc
+++ b/chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog_unittest.cc
@@ -4,12 +4,21 @@
 
 #include "chrome/browser/chromeos/arc/intent_helper/arc_external_protocol_dialog.h"
 
-#include <memory>
-
 #include "base/macros.h"
+#include "base/time/time.h"
 #include "chrome/browser/chromeos/arc/arc_web_contents_data.h"
+#include "chrome/browser/sharing/sharing_device_registration.h"
+#include "chrome/browser/sharing/sharing_fcm_handler.h"
+#include "chrome/browser/sharing/sharing_fcm_sender.h"
+#include "chrome/browser/sharing/sharing_service.h"
+#include "chrome/browser/sharing/sharing_service_factory.h"
+#include "chrome/browser/sharing/sharing_sync_preference.h"
+#include "chrome/browser/sharing/vapid_key_manager.h"
 #include "chrome/test/base/browser_with_test_window_test.h"
 #include "components/arc/intent_helper/arc_intent_helper_bridge.h"
+#include "content/public/browser/render_process_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "url/gurl.h"
 
 namespace arc {
@@ -37,6 +46,8 @@
         web_contents_);
   }
 
+  content::WebContents* web_contents() { return web_contents_; }
+
  private:
   // Keep only one |WebContents| at a time.
   content::WebContents* web_contents_;
@@ -70,6 +81,38 @@
   return ptr;
 }
 
+// TODO(crbug.com/1011364): Extract this into a common mock file.
+class MockSharingService : public SharingService {
+ public:
+  explicit MockSharingService()
+      : SharingService(
+            /*sync_prefs=*/nullptr,
+            /*vapid_key_manager=*/nullptr,
+            std::make_unique<SharingDeviceRegistration>(
+                /*pref_service=*/nullptr,
+                /*sync_preference=*/nullptr,
+                /*instance_id_driver=*/nullptr,
+                /*vapid_key_manager=*/nullptr),
+            /*fcm_sender=*/nullptr,
+            std::make_unique<SharingFCMHandler>(
+                /*gcm_driver=*/nullptr,
+                /*sharing_fcm_sender=*/nullptr,
+                /*sync_preference=*/nullptr),
+            /*gcm_driver=*/nullptr,
+            /*device_info_tracker=*/nullptr,
+            /*local_device_info_provider=*/nullptr,
+            /*sync_service=*/nullptr,
+            /*notification_display_service=*/nullptr) {}
+
+  ~MockSharingService() override = default;
+
+  MOCK_METHOD4(SendMessageToDevice,
+               void(const std::string&,
+                    base::TimeDelta,
+                    chrome_browser_sharing::SharingMessage,
+                    SendMessageCallback));
+};
+
 }  // namespace
 
 // Tests that when no apps are returned from ARC, GetAction returns
@@ -954,4 +997,39 @@
   EXPECT_TRUE(in_out_safe_to_bypass_ui);
 }
 
+// Tests that clicking on a device calls through to SharingService.
+TEST_F(ArcExternalProtocolDialogTestUtils, TestSelectDeviceForTelLink) {
+  std::string device_guid = "device_guid";
+
+  MockSharingService* sharing_service = static_cast<MockSharingService*>(
+      SharingServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+          profile(), base::BindRepeating([](content::BrowserContext* context) {
+            return static_cast<std::unique_ptr<KeyedService>>(
+                std::make_unique<MockSharingService>());
+          })));
+
+  EXPECT_CALL(*sharing_service,
+              SendMessageToDevice(testing::Eq(device_guid), testing::_,
+                                  testing::_, testing::_));
+
+  CreateTab(/*started_from_arc=*/false);
+
+  content::RenderViewHost* rvh = web_contents()->GetRenderViewHost();
+  std::vector<mojom::IntentHandlerInfoPtr> handlers;
+  std::vector<std::unique_ptr<syncer::DeviceInfo>> devices;
+
+  devices.emplace_back(std::make_unique<syncer::DeviceInfo>(
+      device_guid, "device_name", "chrome_version", "user_agent",
+      sync_pb::SyncEnums_DeviceType_TYPE_PHONE, "device_id",
+      /*last_updated_timestamp=*/base::Time::Now(),
+      /*send_tab_to_self_receiving_enabled=*/false,
+      /*sharing_info=*/base::nullopt));
+
+  OnIntentPickerClosedForTesting(
+      rvh->GetProcess()->GetID(), rvh->GetRoutingID(), GURL("tel:0123456789"),
+      /*safe_to_bypass_ui=*/true, std::move(handlers), std::move(devices),
+      /*selected_app_package=*/device_guid, apps::PickerEntryType::kDevice,
+      apps::IntentPickerCloseReason::OPEN_APP, /*should_persist=*/false);
+}
+
 }  // namespace arc
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager.cc b/chrome/browser/chromeos/arc/session/arc_session_manager.cc
index 265a9a8..2742271d 100644
--- a/chrome/browser/chromeos/arc/session/arc_session_manager.cc
+++ b/chrome/browser/chromeos/arc/session/arc_session_manager.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/chromeos/arc/arc_migration_guide_notification.h"
 #include "chrome/browser/chromeos/arc/arc_optin_uma.h"
 #include "chrome/browser/chromeos/arc/arc_support_host.h"
-#include "chrome/browser/chromeos/arc/arc_ui_availability_reporter.h"
 #include "chrome/browser/chromeos/arc/arc_util.h"
 #include "chrome/browser/chromeos/arc/auth/arc_auth_service.h"
 #include "chrome/browser/chromeos/arc/optin/arc_terms_of_service_default_negotiator.h"
@@ -521,7 +520,6 @@
   }
   pai_starter_.reset();
   fast_app_reinstall_starter_.reset();
-  arc_ui_availability_reporter_.reset();
   profile_ = nullptr;
   state_ = State::NOT_INITIALIZED;
   if (scoped_opt_in_tracker_) {
@@ -681,9 +679,7 @@
   // the initial request.
   // |prefs::kArcProvisioningInitiatedFromOobe| is reset when provisioning is
   // done or ARC is opted out.
-  const bool opt_in_start = IsArcOobeOptInActive();
-  const bool signed_in = prefs->GetBoolean(prefs::kArcSignedIn);
-  if (opt_in_start)
+  if (IsArcOobeOptInActive())
     prefs->SetBoolean(prefs::kArcProvisioningInitiatedFromOobe, true);
 
   // If it is marked that sign in has been successfully done or if Play Store is
@@ -693,9 +689,9 @@
   // In Public Session mode ARC should be started silently without user
   // interaction. If opt-in verification is disabled, skip negotiation, too.
   // This is for testing purpose.
-  const bool start_arc_directly = signed_in || ShouldArcAlwaysStart() ||
-                                  IsRobotOrOfflineDemoAccountMode() ||
-                                  IsArcOptInVerificationDisabled();
+  const bool start_arc_directly =
+      prefs->GetBoolean(prefs::kArcSignedIn) || ShouldArcAlwaysStart() ||
+      IsRobotOrOfflineDemoAccountMode() || IsArcOptInVerificationDisabled();
 
   // When ARC is blocked because of filesystem compatibility, do not proceed
   // to starting ARC nor follow further state transitions.
@@ -707,18 +703,6 @@
     return false;
   }
 
-  // ARC might be re-enabled and in this case |arc_ui_availability_reporter_| is
-  // already set.
-  if (!arc_ui_availability_reporter_) {
-    arc_ui_availability_reporter_ = std::make_unique<ArcUiAvailabilityReporter>(
-        profile_,
-        opt_in_start
-            ? ArcUiAvailabilityReporter::Mode::kOobeProvisioning
-            : signed_in
-                  ? ArcUiAvailabilityReporter::Mode::kAlreadyProvisioned
-                  : ArcUiAvailabilityReporter::Mode::kInSessionProvisioning);
-  }
-
   if (!pai_starter_ && IsPlayStoreAvailable())
     pai_starter_ = ArcPaiStarter::CreateIfNeeded(profile_);
 
@@ -768,7 +752,6 @@
   scoped_opt_in_tracker_.reset();
   pai_starter_.reset();
   fast_app_reinstall_starter_.reset();
-  arc_ui_availability_reporter_.reset();
 
   // Reset any pending request to re-enable ARC.
   reenable_arc_ = false;
diff --git a/chrome/browser/chromeos/arc/session/arc_session_manager.h b/chrome/browser/chromeos/arc/session/arc_session_manager.h
index 4bd1accb..5ad9eb0 100644
--- a/chrome/browser/chromeos/arc/session/arc_session_manager.h
+++ b/chrome/browser/chromeos/arc/session/arc_session_manager.h
@@ -29,8 +29,6 @@
 class ArcFastAppReinstallStarter;
 class ArcPaiStarter;
 class ArcTermsOfServiceNegotiator;
-class ArcUiAvailabilityReporter;
-
 enum class ProvisioningResult : int;
 
 // This class is responsible for handing stages of ARC life-cycle.
@@ -377,7 +375,6 @@
   std::unique_ptr<ScopedOptInFlowTracker> scoped_opt_in_tracker_;
   std::unique_ptr<ArcPaiStarter> pai_starter_;
   std::unique_ptr<ArcFastAppReinstallStarter> fast_app_reinstall_starter_;
-  std::unique_ptr<ArcUiAvailabilityReporter> arc_ui_availability_reporter_;
 
   // The time when the sign in process started.
   base::TimeTicks sign_in_start_time_;
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.cc b/chrome/browser/chromeos/crostini/crostini_manager.cc
index e69ad4a..4555317 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager.cc
+++ b/chrome/browser/chromeos/crostini/crostini_manager.cc
@@ -1982,11 +1982,31 @@
   RemoveLinuxPackageOperationProgressObserver(
       AnsibleManagementService::GetForProfile(profile_));
 
+  if (!success) {
+    LOG(ERROR) << "Failed to install Ansible in default Crostini container";
+    // TODO(https://crbug.com/998124): Add a proper error.
+    InvokeAndErasePendingContainerCallbacks(
+        &start_container_callbacks_, kCrostiniDefaultVmName,
+        kCrostiniDefaultContainerName, CrostiniResult::UNKNOWN_ERROR);
+    return;
+  }
+
+  // TODO(https://crbug.com/998124): Propagate playbook to be applied.
+  AnsibleManagementService::GetForProfile(profile_)
+      ->ApplyAnsiblePlaybookToDefaultContainer(
+          /*playbook=*/"---",
+          base::BindOnce(
+              &CrostiniManager::OnAnsiblePlaybookToDefaultContainerApplied,
+              weak_ptr_factory_.GetWeakPtr()));
+}
+
+void CrostiniManager::OnAnsiblePlaybookToDefaultContainerApplied(bool success) {
   CrostiniResult result = CrostiniResult::SUCCESS;
   if (!success) {
-    LOG(ERROR) << "Failed to install Ansible to default Crostini container";
-    // TODO(okalitova): Add proper bug.
-    result = CrostiniResult::CONTAINER_START_FAILED;
+    LOG(ERROR) << "Failed to apply Ansible playbook to default Crostini "
+               << "container";
+    // TODO(https://crbug.com/998124): Add a proper error.
+    result = CrostiniResult::UNKNOWN_ERROR;
   }
 
   InvokeAndErasePendingContainerCallbacks(
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.h b/chrome/browser/chromeos/crostini/crostini_manager.h
index df77d17..9ec8b5119 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager.h
+++ b/chrome/browser/chromeos/crostini/crostini_manager.h
@@ -700,6 +700,10 @@
   // CrostiniAnsibleManagementService::InstallAnsibleInDefaultContainer
   void OnAnsibleInDefaultContainerInstalled(bool success);
 
+  // Callback for
+  // CrostiniAnsibleManagementService::ApplyAnsiblePlaybookToDefaultContainer
+  void OnAnsiblePlaybookToDefaultContainerApplied(bool success);
+
   // Helper for CrostiniManager::MaybeUpgradeCrostini. Makes blocking calls to
   // check for file paths and registered components.
   static void CheckPathsAndComponents();
diff --git a/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc b/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc
index cff125a..3687622 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc
+++ b/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc
@@ -209,6 +209,17 @@
     fake_cicerone_client_->InstallLinuxPackageProgress(signal);
   }
 
+  void SendSucceededApplySignal() {
+    vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal signal;
+    signal.set_owner_id(CryptohomeIdForProfile(profile()));
+    signal.set_vm_name(kCrostiniDefaultVmName);
+    signal.set_container_name(kCrostiniDefaultContainerName);
+    signal.set_status(
+        vm_tools::cicerone::ApplyAnsiblePlaybookProgressSignal::SUCCEEDED);
+
+    fake_cicerone_client_->NotifyApplyAnsiblePlaybookProgress(signal);
+  }
+
   base::RunLoop* run_loop() { return run_loop_.get(); }
   Profile* profile() { return profile_.get(); }
   CrostiniManager* crostini_manager() { return crostini_manager_; }
@@ -1419,33 +1430,71 @@
   run_loop()->Run();
 }
 
-TEST_F(CrostiniManagerTest, StartContainerWithAnsibleInfrastructureFailure) {
+TEST_F(CrostiniManagerTest, StartContainerWithAnsibleInfraInstallFailure) {
   scoped_feature_list_.Reset();
   scoped_feature_list_.InitAndEnableFeature(
       features::kCrostiniAnsibleInfrastructure);
 
   // Response for failed Ansible installation.
-  vm_tools::cicerone::InstallLinuxPackageResponse response;
-  response.set_status(vm_tools::cicerone::InstallLinuxPackageResponse::FAILED);
-  fake_cicerone_client_->set_install_linux_package_response(response);
+  vm_tools::cicerone::InstallLinuxPackageResponse install_response;
+  install_response.set_status(
+      vm_tools::cicerone::InstallLinuxPackageResponse::FAILED);
+  fake_cicerone_client_->set_install_linux_package_response(install_response);
 
   crostini_manager()->StartLxdContainer(
       kCrostiniDefaultVmName, kCrostiniDefaultContainerName,
       base::BindOnce(&ExpectCrostiniResult, run_loop()->QuitClosure(),
-                     CrostiniResult::CONTAINER_START_FAILED));
+                     CrostiniResult::UNKNOWN_ERROR));
 
   run_loop()->Run();
 }
 
-TEST_F(CrostiniManagerTest, StartContainerWithAnsibleInfrastructureSuccess) {
+TEST_F(CrostiniManagerTest, StartContainerWithAnsibleInfraApplicationFailure) {
   scoped_feature_list_.Reset();
   scoped_feature_list_.InitAndEnableFeature(
       features::kCrostiniAnsibleInfrastructure);
 
   // Response for successful Ansible installation.
-  vm_tools::cicerone::InstallLinuxPackageResponse response;
-  response.set_status(vm_tools::cicerone::InstallLinuxPackageResponse::STARTED);
-  fake_cicerone_client_->set_install_linux_package_response(response);
+  vm_tools::cicerone::InstallLinuxPackageResponse install_response;
+  install_response.set_status(
+      vm_tools::cicerone::InstallLinuxPackageResponse::STARTED);
+  fake_cicerone_client_->set_install_linux_package_response(install_response);
+
+  // Response for failed Ansible playbook application.
+  vm_tools::cicerone::ApplyAnsiblePlaybookResponse apply_response;
+  apply_response.set_status(
+      vm_tools::cicerone::ApplyAnsiblePlaybookResponse::FAILED);
+  fake_cicerone_client_->set_apply_ansible_playbook_response(apply_response);
+
+  crostini_manager()->StartLxdContainer(
+      kCrostiniDefaultVmName, kCrostiniDefaultContainerName,
+      base::BindOnce(&ExpectCrostiniResult, run_loop()->QuitClosure(),
+                     CrostiniResult::UNKNOWN_ERROR));
+
+  base::RunLoop().RunUntilIdle();
+
+  // Finish successful Ansible installation.
+  SendSucceededInstallSignal();
+
+  run_loop()->Run();
+}
+
+TEST_F(CrostiniManagerTest, StartContainerWithAnsibleInfraSuccess) {
+  scoped_feature_list_.Reset();
+  scoped_feature_list_.InitAndEnableFeature(
+      features::kCrostiniAnsibleInfrastructure);
+
+  // Response for successful Ansible installation.
+  vm_tools::cicerone::InstallLinuxPackageResponse install_response;
+  install_response.set_status(
+      vm_tools::cicerone::InstallLinuxPackageResponse::STARTED);
+  fake_cicerone_client_->set_install_linux_package_response(install_response);
+
+  // Response for successful Ansible playbook application.
+  vm_tools::cicerone::ApplyAnsiblePlaybookResponse apply_response;
+  apply_response.set_status(
+      vm_tools::cicerone::ApplyAnsiblePlaybookResponse::STARTED);
+  fake_cicerone_client_->set_apply_ansible_playbook_response(apply_response);
 
   crostini_manager()->StartLxdContainer(
       kCrostiniDefaultVmName, kCrostiniDefaultContainerName,
@@ -1457,6 +1506,9 @@
   // Finish successful Ansible installation.
   SendSucceededInstallSignal();
 
+  // Finish successful Ansible playbook application.
+  SendSucceededApplySignal();
+
   run_loop()->Run();
 }
 
diff --git a/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc b/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
index 57b8be8..7629c36 100644
--- a/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
+++ b/chrome/browser/chromeos/file_manager/external_filesystem_apitest.cc
@@ -810,13 +810,9 @@
 //
 // DriveFileSystemExtensionApiTests.
 //
-#if defined(LEAK_SANITIZER)
-#define MAYBE_FileSystemOperations DISABLED_FileSystemOperations
-#else
-#define MAYBE_FileSystemOperations FileSystemOperations
-#endif
+// This test is flaky. See https://crbug.com/1008880.
 IN_PROC_BROWSER_TEST_F(DriveFileSystemExtensionApiTest,
-                       MAYBE_FileSystemOperations) {
+                       DISABLED_FileSystemOperations) {
   EXPECT_TRUE(RunFileSystemExtensionApiTest(
       "file_browser/filesystem_operations_test",
       FILE_PATH_LITERAL("manifest.json"),
diff --git a/chrome/browser/chromeos/fileapi/external_file_url_loader_factory.cc b/chrome/browser/chromeos/fileapi/external_file_url_loader_factory.cc
index c583e02b..c1b10c9 100644
--- a/chrome/browser/chromeos/fileapi/external_file_url_loader_factory.cc
+++ b/chrome/browser/chromeos/fileapi/external_file_url_loader_factory.cc
@@ -24,6 +24,7 @@
 #include "content/public/common/url_constants.h"
 #include "extensions/browser/api/file_handlers/mime_util.h"
 #include "mojo/public/c/system/types.h"
+#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/system/simple_watcher.h"
 #include "net/base/io_buffer.h"
 #include "net/http/http_byte_range.h"
@@ -366,8 +367,8 @@
 }
 
 void ExternalFileURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest loader) {
-  bindings_.AddBinding(this, std::move(loader));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) {
+  receivers_.Add(this, std::move(loader));
 }
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/fileapi/external_file_url_loader_factory.h b/chrome/browser/chromeos/fileapi/external_file_url_loader_factory.h
index 471a3f7..2b4333c 100644
--- a/chrome/browser/chromeos/fileapi/external_file_url_loader_factory.h
+++ b/chrome/browser/chromeos/fileapi/external_file_url_loader_factory.h
@@ -6,7 +6,8 @@
 #define CHROME_BROWSER_CHROMEOS_FILEAPI_EXTERNAL_FILE_URL_LOADER_FACTORY_H_
 
 #include "base/macros.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
 namespace chromeos {
@@ -33,9 +34,10 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest loader) override;
+  void Clone(
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) override;
 
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
   void* profile_id_;
   const int render_process_host_id_;
 
diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc
index 5e1c118..f65bf79 100644
--- a/chrome/browser/devtools/devtools_sanity_browsertest.cc
+++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc
@@ -832,9 +832,16 @@
 // Tests that scripts tab is populated with inspected scripts even if it
 // hadn't been shown by the moment inspected paged refreshed.
 // @see http://crbug.com/26312
-IN_PROC_BROWSER_TEST_F(
-    DevToolsSanityTest,
-    TestScriptsTabIsPopulatedOnInspectedPageRefresh) {
+// This test is flaky on windows and linux asan. See https://crbug.com/1013003
+#if defined(OS_WIN) || defined(OS_MACOSX)
+#define MAYBE_TestScriptsTabIsPopulatedOnInspectedPageRefresh \
+  DISABLED_TestScriptsTabIsPopulatedOnInspectedPageRefresh
+#else
+#define MAYBE_TestScriptsTabIsPopulatedOnInspectedPageRefresh \
+  TestScriptsTabIsPopulatedOnInspectedPageRefresh
+#endif
+IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
+                       MAYBE_TestScriptsTabIsPopulatedOnInspectedPageRefresh) {
   RunTest("testScriptsTabIsPopulatedOnInspectedPageRefresh",
           kDebuggerTestPage);
 }
diff --git a/chrome/browser/extensions/test_blacklist_state_fetcher.cc b/chrome/browser/extensions/test_blacklist_state_fetcher.cc
index 0b07d9c7..72193d59 100644
--- a/chrome/browser/extensions/test_blacklist_state_fetcher.cc
+++ b/chrome/browser/extensions/test_blacklist_state_fetcher.cc
@@ -7,6 +7,7 @@
 #include "base/stl_util.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/safe_browsing/db/v4_test_util.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 
@@ -31,7 +32,8 @@
     clients_.push_back(std::move(client));
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
     NOTREACHED();
   }
 
diff --git a/chrome/browser/media/router/discovery/dial/device_description_fetcher_unittest.cc b/chrome/browser/media/router/discovery/dial/device_description_fetcher_unittest.cc
index 99b3c47c9..9e938251 100644
--- a/chrome/browser/media/router/discovery/dial/device_description_fetcher_unittest.cc
+++ b/chrome/browser/media/router/discovery/dial/device_description_fetcher_unittest.cc
@@ -47,7 +47,6 @@
   }
 
  private:
-  std::vector<network::mojom::URLLoaderFactoryRequest> requests_;
   network::TestURLLoaderFactory* const factory_;
 };
 
diff --git a/chrome/browser/media/router/discovery/dial/dial_url_fetcher.cc b/chrome/browser/media/router/discovery/dial/dial_url_fetcher.cc
index d060a9e1..f29fe01 100644
--- a/chrome/browser/media/router/discovery/dial/dial_url_fetcher.cc
+++ b/chrome/browser/media/router/discovery/dial/dial_url_fetcher.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/net/system_network_context_manager.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "net/base/load_flags.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_status_code.h"
@@ -62,12 +63,12 @@
           }
         })");
 
-void BindURLLoaderFactoryRequestOnUIThread(
-    network::mojom::URLLoaderFactoryRequest request) {
+void BindURLLoaderFactoryReceiverOnUIThread(
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   network::mojom::URLLoaderFactory* factory =
       g_browser_process->system_network_context_manager()
           ->GetURLLoaderFactory();
-  factory->Clone(std::move(request));
+  factory->Clone(std::move(receiver));
 }
 
 }  // namespace
@@ -170,7 +171,7 @@
   auto mojo_request = mojo::MakeRequest(&loader_factory);
   if (content::BrowserThread::IsThreadInitialized(content::BrowserThread::UI)) {
     base::PostTask(FROM_HERE, {content::BrowserThread::UI},
-                   base::BindOnce(&BindURLLoaderFactoryRequestOnUIThread,
+                   base::BindOnce(&BindURLLoaderFactoryReceiverOnUIThread,
                                   std::move(mojo_request)));
   }
 
diff --git a/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc b/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc
index d21dd50..17f542e 100644
--- a/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc
+++ b/chrome/browser/media/webrtc/webrtc_event_log_uploader.cc
@@ -15,6 +15,7 @@
 #include "components/version_info/version_info.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "net/base/load_flags.h"
 #include "net/base/mime_util.h"
 #include "net/http/http_status_code.h"
@@ -102,13 +103,14 @@
   return content_type;
 }
 
-void BindURLLoaderFactoryRequest(
-    network::mojom::URLLoaderFactoryRequest url_loader_factory_request) {
+void BindURLLoaderFactoryReceiver(
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+        url_loader_factory_receiver) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory =
       g_browser_process->shared_url_loader_factory();
   DCHECK(shared_url_loader_factory);
-  shared_url_loader_factory->Clone(std::move(url_loader_factory_request));
+  shared_url_loader_factory->Clone(std::move(url_loader_factory_receiver));
 }
 
 void OnURLLoadUploadProgress(uint64_t current, uint64_t total) {
@@ -280,7 +282,7 @@
   // thread.
   network::mojom::URLLoaderFactoryPtr url_loader_factory_ptr;
   base::PostTask(FROM_HERE, {content::BrowserThread::UI},
-                 base::BindOnce(BindURLLoaderFactoryRequest,
+                 base::BindOnce(BindURLLoaderFactoryReceiver,
                                 mojo::MakeRequest(&url_loader_factory_ptr)));
 
   url_loader_ = network::SimpleURLLoader::Create(
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc
index 95964da..fd00b37 100644
--- a/chrome/browser/net/system_network_context_manager.cc
+++ b/chrome/browser/net/system_network_context_manager.cc
@@ -56,6 +56,7 @@
 #include "content/public/common/service_names.mojom.h"
 #include "content/public/common/user_agent.h"
 #include "crypto/sha2.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "net/net_buildflags.h"
@@ -282,10 +283,11 @@
         std::move(client), traffic_annotation);
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
     if (!manager_)
       return;
-    manager_->GetURLLoaderFactory()->Clone(std::move(request));
+    manager_->GetURLLoaderFactory()->Clone(std::move(receiver));
   }
 
   // SharedURLLoaderFactory implementation:
diff --git a/chrome/browser/notifications/notification_platform_bridge_mac.mm b/chrome/browser/notifications/notification_platform_bridge_mac.mm
index e9c5566d..eba429e8 100644
--- a/chrome/browser/notifications/notification_platform_bridge_mac.mm
+++ b/chrome/browser/notifications/notification_platform_bridge_mac.mm
@@ -41,7 +41,7 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_constants.h"
+#include "third_party/blink/public/common/notifications/notification_constants.h"
 #include "third_party/crashpad/crashpad/client/crashpad_client.h"
 #include "ui/base/l10n/l10n_util_mac.h"
 #include "ui/message_center/public/cpp/notification.h"
@@ -252,7 +252,7 @@
   [builder setShowSettingsButton:(notification.should_show_settings_button())];
   std::vector<message_center::ButtonInfo> buttons = notification.buttons();
   if (!buttons.empty()) {
-    DCHECK_LE(buttons.size(), blink::kWebNotificationMaxActions);
+    DCHECK_LE(buttons.size(), blink::kNotificationMaxActions);
     NSString* buttonOne = base::SysUTF16ToNSString(buttons[0].title);
     NSString* buttonTwo = nullptr;
     if (buttons.size() > 1)
@@ -414,7 +414,7 @@
   if (button_index.intValue <
           notification_constants::kNotificationInvalidButtonIndex ||
       button_index.intValue >=
-          static_cast<int>(blink::kWebNotificationMaxActions)) {
+          static_cast<int>(blink::kNotificationMaxActions)) {
     LOG(ERROR) << "Invalid number of buttons supplied "
                << button_index.intValue;
     return false;
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index fce5072..0849b67 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -176,6 +176,7 @@
     called_set_logging_state_ = true;
     logging_state_active_ = active;
   }
+  void TouchToFillDismissed() override {}
 
   // Records whether SetLoggingState() gets called.
   bool called_set_logging_state_;
diff --git a/chrome/browser/password_manager/touch_to_fill_controller.cc b/chrome/browser/password_manager/touch_to_fill_controller.cc
index 19f8f88..2eb44e0 100644
--- a/chrome/browser/password_manager/touch_to_fill_controller.cc
+++ b/chrome/browser/password_manager/touch_to_fill_controller.cc
@@ -14,24 +14,11 @@
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/url_formatter/elide_url.h"
 #include "content/public/browser/web_contents.h"
+#include "services/network/public/cpp/is_potentially_trustworthy.h"
 
 using password_manager::CredentialPair;
 using password_manager::PasswordManagerDriver;
 
-namespace {
-
-void OnCredentialSelected(base::WeakPtr<PasswordManagerDriver> driver,
-                          const CredentialPair& credential) {
-  if (!driver)
-    return;
-
-  password_manager::metrics_util::LogFilledCredentialIsFromAndroidApp(
-      password_manager::IsValidAndroidFacetURI(credential.origin_url.spec()));
-  driver->FillSuggestion(credential.username, credential.password);
-}
-
-}  // namespace
-
 TouchToFillController::TouchToFillController(content::WebContents* web_contents)
     : web_contents_(web_contents) {}
 
@@ -39,14 +26,36 @@
 
 void TouchToFillController::Show(base::span<const CredentialPair> credentials,
                                  base::WeakPtr<PasswordManagerDriver> driver) {
+  DCHECK(!driver_ || driver_.get() == driver.get());
+  driver_ = std::move(driver);
+
   if (!view_)
     view_ = TouchToFillViewFactory::Create(this);
 
+  const GURL& url = driver_->GetLastCommittedURL();
   view_->Show(url_formatter::FormatUrlForSecurityDisplay(
-                  driver->GetLastCommittedURL(),
-                  url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC),
-              credentials,
-              base::BindOnce(OnCredentialSelected, std::move(driver)));
+                  url, url_formatter::SchemeDisplay::OMIT_HTTP_AND_HTTPS),
+              TouchToFillView::IsOriginSecure(
+                  network::IsUrlPotentiallyTrustworthy(url)),
+              credentials);
+}
+
+void TouchToFillController::OnCredentialSelected(
+    const CredentialPair& credential) {
+  if (!driver_)
+    return;
+
+  password_manager::metrics_util::LogFilledCredentialIsFromAndroidApp(
+      password_manager::IsValidAndroidFacetURI(credential.origin_url.spec()));
+  driver_->FillSuggestion(credential.username, credential.password);
+  std::exchange(driver_, nullptr)->TouchToFillDismissed();
+}
+
+void TouchToFillController::OnDismiss() {
+  if (!driver_)
+    return;
+
+  std::exchange(driver_, nullptr)->TouchToFillDismissed();
 }
 
 gfx::NativeView TouchToFillController::GetNativeView() {
diff --git a/chrome/browser/password_manager/touch_to_fill_controller.h b/chrome/browser/password_manager/touch_to_fill_controller.h
index fdc3556..a088ef5a 100644
--- a/chrome/browser/password_manager/touch_to_fill_controller.h
+++ b/chrome/browser/password_manager/touch_to_fill_controller.h
@@ -32,10 +32,18 @@
   ~TouchToFillController();
 
   // Instructs the controller to show the provided |credentials| to the user.
-  // Invokes FillSuggestion() on |driver| once the user made a selection.
   void Show(base::span<const password_manager::CredentialPair> credentials,
             base::WeakPtr<password_manager::PasswordManagerDriver> driver);
 
+  // Informs the controller that the user has made a selection. Invokes both
+  // FillSuggestion() and TouchToFillDismissed() on |driver_|. No-op if invoked
+  // repeatedly.
+  void OnCredentialSelected(const password_manager::CredentialPair& credential);
+
+  // Informs the controller that the user has dismissed the sheet. Invokes
+  // TouchToFillDismissed() on |driver_|. No-op if invoked repeatedly.
+  void OnDismiss();
+
   // The web page view containing the focused field.
   gfx::NativeView GetNativeView();
 
@@ -51,6 +59,10 @@
   // WebContentsUserData.
   content::WebContents* web_contents_ = nullptr;
 
+  // Driver passed to the latest invocation of Show(). Gets cleared when
+  // OnCredentialSelected() or OnDismissed() gets called.
+  base::WeakPtr<password_manager::PasswordManagerDriver> driver_;
+
   // View used to communicate with the Android frontend. Lazily instantiated so
   // that it can be injected by tests.
   std::unique_ptr<TouchToFillView> view_;
diff --git a/chrome/browser/password_manager/touch_to_fill_controller_unittest.cc b/chrome/browser/password_manager/touch_to_fill_controller_unittest.cc
index 888e71f..fc4a40d 100644
--- a/chrome/browser/password_manager/touch_to_fill_controller_unittest.cc
+++ b/chrome/browser/password_manager/touch_to_fill_controller_unittest.cc
@@ -22,29 +22,25 @@
 using ::testing::Eq;
 using ::testing::ReturnRefOfCopy;
 using ::testing::WithArg;
+using IsOriginSecure = TouchToFillView::IsOriginSecure;
 
-// Re-implementation of ::testing::SaveArg that works with move-only types.
-template <size_t K, typename T>
-auto SaveArg(T* ptr) {
-  return [ptr](auto&&... args) {
-    *ptr = std::get<K>(
-        std::forward_as_tuple(std::forward<decltype(args)>(args)...));
-  };
-}
+using IsPublicSuffixMatch = CredentialPair::IsPublicSuffixMatch;
 
 constexpr char kExampleCom[] = "https://example.com/";
 
 struct MockPasswordManagerDriver : password_manager::StubPasswordManagerDriver {
   MOCK_METHOD2(FillSuggestion,
                void(const base::string16&, const base::string16&));
+  MOCK_METHOD0(TouchToFillDismissed, void());
   MOCK_CONST_METHOD0(GetLastCommittedURL, const GURL&());
 };
 
 struct MockTouchToFillView : TouchToFillView {
   MOCK_METHOD3(Show,
                void(base::StringPiece16,
-                    base::span<const password_manager::CredentialPair>,
-                    ShowCallback));
+                    IsOriginSecure,
+                    base::span<const CredentialPair>));
+  MOCK_METHOD1(OnCredentialSelected, void(const CredentialPair&));
   MOCK_METHOD0(OnDismiss, void());
 };
 
@@ -78,44 +74,70 @@
 TEST_F(TouchToFillControllerTest, Show_And_Fill) {
   CredentialPair credentials[] = {
       {base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"),
-       GURL(kExampleCom), /*is_public_suffix_match=*/false}};
+       GURL(kExampleCom), IsPublicSuffixMatch(false)}};
 
-  TouchToFillView::ShowCallback callback;
-  EXPECT_CALL(view(), Show(Eq(base::ASCIIToUTF16("example.com")),
-                           ElementsAreArray(credentials), _))
-      .WillOnce(SaveArg<2>(&callback));
+  EXPECT_CALL(view(),
+              Show(Eq(base::ASCIIToUTF16("example.com")), IsOriginSecure(true),
+                   ElementsAreArray(credentials)));
   touch_to_fill_controller().Show(credentials, driver().AsWeakPtr());
 
   // Test that we correctly log the absence of an Android credential.
   base::HistogramTester tester;
   EXPECT_CALL(driver(), FillSuggestion(base::ASCIIToUTF16("alice"),
                                        base::ASCIIToUTF16("p4ssw0rd")));
-  std::move(callback).Run(credentials[0]);
+  EXPECT_CALL(driver(), TouchToFillDismissed);
+  touch_to_fill_controller().OnCredentialSelected(credentials[0]);
   tester.ExpectUniqueSample("PasswordManager.FilledCredentialWasFromAndroidApp",
                             false, 1);
 }
 
+TEST_F(TouchToFillControllerTest, Show_Insecure_Origin) {
+  EXPECT_CALL(driver(), GetLastCommittedURL())
+      .WillOnce(ReturnRefOfCopy(GURL("http://example.com")));
+
+  CredentialPair credentials[] = {
+      {base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"),
+       GURL(kExampleCom), IsPublicSuffixMatch(false)}};
+
+  EXPECT_CALL(view(),
+              Show(Eq(base::ASCIIToUTF16("example.com")), IsOriginSecure(false),
+                   ElementsAreArray(credentials)));
+  touch_to_fill_controller().Show(credentials, driver().AsWeakPtr());
+}
+
 TEST_F(TouchToFillControllerTest, Show_And_Fill_Android_Credential) {
   // Test multiple credentials with one of them being an Android credential.
   CredentialPair credentials[] = {
       {base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"),
-       GURL(kExampleCom),
-       /*is_public_suffix_match=*/false},
+       GURL(kExampleCom), IsPublicSuffixMatch(false)},
       {base::ASCIIToUTF16("bob"), base::ASCIIToUTF16("s3cr3t"),
-       GURL("android://hash@com.example.my"),
-       /*is_public_suffix_match=*/false}};
+       GURL("android://hash@com.example.my"), IsPublicSuffixMatch(false)}};
 
-  TouchToFillView::ShowCallback callback;
-  EXPECT_CALL(view(), Show(Eq(base::ASCIIToUTF16("example.com")),
-                           ElementsAreArray(credentials), _))
-      .WillOnce(SaveArg<2>(&callback));
+  EXPECT_CALL(view(),
+              Show(Eq(base::ASCIIToUTF16("example.com")), IsOriginSecure(true),
+                   ElementsAreArray(credentials)));
   touch_to_fill_controller().Show(credentials, driver().AsWeakPtr());
 
   // Test that we correctly log the presence of an Android credential.
   base::HistogramTester tester;
   EXPECT_CALL(driver(), FillSuggestion(base::ASCIIToUTF16("bob"),
                                        base::ASCIIToUTF16("s3cr3t")));
-  std::move(callback).Run(credentials[1]);
+  EXPECT_CALL(driver(), TouchToFillDismissed);
+  touch_to_fill_controller().OnCredentialSelected(credentials[1]);
   tester.ExpectUniqueSample("PasswordManager.FilledCredentialWasFromAndroidApp",
                             true, 1);
 }
+
+TEST_F(TouchToFillControllerTest, Dismiss) {
+  CredentialPair credentials[] = {
+      {base::ASCIIToUTF16("alice"), base::ASCIIToUTF16("p4ssw0rd"),
+       GURL(kExampleCom), IsPublicSuffixMatch(false)}};
+
+  EXPECT_CALL(view(),
+              Show(Eq(base::ASCIIToUTF16("example.com")), IsOriginSecure(true),
+                   ElementsAreArray(credentials)));
+  touch_to_fill_controller().Show(credentials, driver().AsWeakPtr());
+
+  EXPECT_CALL(driver(), TouchToFillDismissed);
+  touch_to_fill_controller().OnDismiss();
+}
diff --git a/chrome/browser/performance_manager/browser_child_process_watcher.cc b/chrome/browser/performance_manager/browser_child_process_watcher.cc
index 2fb04315..52530bed 100644
--- a/chrome/browser/performance_manager/browser_child_process_watcher.cc
+++ b/chrome/browser/performance_manager/browser_child_process_watcher.cc
@@ -95,10 +95,9 @@
   // specifically on crash.
   if (base::Contains(gpu_process_nodes_, id)) {
     auto* process_node = gpu_process_nodes_[id].get();
-    PerformanceManagerImpl* performance_manager =
-        PerformanceManagerImpl::GetInstance();
 
-    performance_manager->task_runner()->PostTask(
+    DCHECK(PerformanceManagerImpl::GetInstance());
+    PerformanceManagerImpl::GetTaskRunner()->PostTask(
         FROM_HERE, base::BindOnce(&ProcessNodeImpl::SetProcessExitStatus,
                                   base::Unretained(process_node), exit_code));
   }
@@ -118,9 +117,8 @@
       process.CreationTime();
 #endif
 
-  PerformanceManagerImpl* performance_manager =
-      PerformanceManagerImpl::GetInstance();
-  performance_manager->task_runner()->PostTask(
+  DCHECK(PerformanceManagerImpl::GetInstance());
+  PerformanceManagerImpl::GetTaskRunner()->PostTask(
       FROM_HERE, base::BindOnce(&ProcessNodeImpl::SetProcess,
                                 base::Unretained(process_node),
                                 process.Duplicate(), launch_time));
diff --git a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
index a2cd9c1..0bca796 100644
--- a/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
+++ b/chrome/browser/performance_manager/chrome_browser_main_extra_parts_performance_manager.cc
@@ -127,13 +127,11 @@
     const content::NotificationDetails& details) {
   switch (type) {
     case chrome::NOTIFICATION_PROFILE_CREATED: {
-      Profile* profile = content::Source<Profile>(source).ptr();
-      CreateSharedWorkerWatcher(profile);
+      // TODO(1013168): Create the worker watchers here.
       break;
     }
     case chrome::NOTIFICATION_PROFILE_DESTROYED: {
-      Profile* profile = content::Source<Profile>(source).ptr();
-      DeleteSharedWorkerWatcher(profile);
+      // TODO(1013168): Delete the worker watchers here.
       break;
     }
     default:
diff --git a/chrome/browser/performance_manager/chrome_content_browser_client_performance_manager_part.cc b/chrome/browser/performance_manager/chrome_content_browser_client_performance_manager_part.cc
index dcb9e00e..0a6486f4 100644
--- a/chrome/browser/performance_manager/chrome_content_browser_client_performance_manager_part.cc
+++ b/chrome/browser/performance_manager/chrome_content_browser_client_performance_manager_part.cc
@@ -31,11 +31,8 @@
       performance_manager::RenderProcessUserData::GetForRenderProcessHost(
           render_process_host);
 
-  performance_manager::PerformanceManagerImpl* performance_manager =
-      performance_manager::PerformanceManagerImpl::GetInstance();
-  DCHECK(performance_manager);
-
-  performance_manager->task_runner()->PostTask(
+  DCHECK(performance_manager::PerformanceManagerImpl::GetInstance());
+  performance_manager::PerformanceManagerImpl::GetTaskRunner()->PostTask(
       FROM_HERE, base::BindOnce(&performance_manager::ProcessNodeImpl::Bind,
                                 base::Unretained(user_data->process_node()),
                                 std::move(receiver)));
diff --git a/chrome/browser/profiles/gaia_info_update_service_unittest.cc b/chrome/browser/profiles/gaia_info_update_service_unittest.cc
index 1b4eda9..9156a3d 100644
--- a/chrome/browser/profiles/gaia_info_update_service_unittest.cc
+++ b/chrome/browser/profiles/gaia_info_update_service_unittest.cc
@@ -298,7 +298,7 @@
 // of ProfileInfoCache is complete.
 TEST_F(GAIAInfoUpdateServiceTest, HandlesProfileReordering) {
   size_t index = GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
-  GetCache()->SetNameOfProfileAtIndex(index, FullName16("B"));
+  GetCache()->SetLocalProfileNameOfProfileAtIndex(index, FullName16("B"));
   GetCache()->SetProfileIsUsingDefaultNameAtIndex(index, true);
 
   CreateProfile(FullName("A"));
diff --git a/chrome/browser/profiles/profile_attributes_entry.cc b/chrome/browser/profiles/profile_attributes_entry.cc
index 80a2ad3..1b4bf8d 100644
--- a/chrome/browser/profiles/profile_attributes_entry.cc
+++ b/chrome/browser/profiles/profile_attributes_entry.cc
@@ -45,6 +45,8 @@
 
 const base::Feature kPersistUPAInProfileInfoCache{
     "PersistUPAInProfileInfoCache", base::FEATURE_ENABLED_BY_DEFAULT};
+const base::Feature kConcatenateGaiaAndProfileName{
+    "ConcatenateGaiaAndProfileName", base::FEATURE_ENABLED_BY_DEFAULT};
 
 const char ProfileAttributesEntry::kAvatarIconKey[] = "avatar_icon";
 const char ProfileAttributesEntry::kBackgroundAppsKey[] = "background_apps";
@@ -108,7 +110,42 @@
   }
 }
 
+base::string16 ProfileAttributesEntry::GetLocalProfileName() const {
+  return GetString16(ProfileInfoCache::kNameKey);
+}
+
+base::string16 ProfileAttributesEntry::GetNameToDisplay() const {
+  DCHECK(base::FeatureList::IsEnabled(kConcatenateGaiaAndProfileName));
+  base::string16 name_to_display =
+      GetString16(ProfileInfoCache::kGAIAGivenNameKey);
+  if (name_to_display.empty())
+    name_to_display = GetString16(ProfileInfoCache::kGAIANameKey);
+
+  base::string16 local_profile_name = GetLocalProfileName();
+  if (name_to_display.empty())
+    return local_profile_name;
+
+  size_t number_of_profiles = profile_info_cache_->GetNumberOfProfiles();
+  if (number_of_profiles == 1)
+    return name_to_display;
+
+  auto it = std::search(name_to_display.begin(), name_to_display.end(),
+                        local_profile_name.begin(), local_profile_name.end(),
+                        base::CaseInsensitiveCompareASCII<char>());
+
+  if (it != name_to_display.end())
+    return name_to_display;
+
+  name_to_display.append(base::UTF8ToUTF16(" ("));
+  name_to_display.append(local_profile_name);
+  name_to_display.append(base::UTF8ToUTF16(")"));
+  return name_to_display;
+}
+
 base::string16 ProfileAttributesEntry::GetName() const {
+  if (base::FeatureList::IsEnabled(kConcatenateGaiaAndProfileName))
+    return GetNameToDisplay();
+
   return profile_info_cache_->GetNameOfProfileAtIndex(profile_index());
 }
 
@@ -267,8 +304,9 @@
   return bucket_index;
 }
 
-void ProfileAttributesEntry::SetName(const base::string16& name) {
-  profile_info_cache_->SetNameOfProfileAtIndex(profile_index(), name);
+void ProfileAttributesEntry::SetLocalProfileName(const base::string16& name) {
+  profile_info_cache_->SetLocalProfileNameOfProfileAtIndex(profile_index(),
+                                                           name);
 }
 
 void ProfileAttributesEntry::SetShortcutName(const base::string16& name) {
diff --git a/chrome/browser/profiles/profile_attributes_entry.h b/chrome/browser/profiles/profile_attributes_entry.h
index 987ec9f..dac9bca5 100644
--- a/chrome/browser/profiles/profile_attributes_entry.h
+++ b/chrome/browser/profiles/profile_attributes_entry.h
@@ -33,6 +33,7 @@
 };
 
 extern const base::Feature kPersistUPAInProfileInfoCache;
+extern const base::Feature kConcatenateGaiaAndProfileName;
 
 class ProfileAttributesEntry {
  public:
@@ -41,8 +42,11 @@
   ProfileAttributesEntry();
   virtual ~ProfileAttributesEntry() {}
 
-  // Gets the name of the profile, which is the one displayed in the User Menu.
+  // Gets the name of the profile to be displayed in the User Menu. The name can
+  // be the GAIA name, local profile name or a combination of them.
   base::string16 GetName() const;
+  // Gets the local profile name.
+  base::string16 GetLocalProfileName() const;
 
   base::string16 GetShortcutName() const;
   // Gets the path to the profile. Should correspond to the path passed to
@@ -112,7 +116,7 @@
   // reserved for the guest profile.
   size_t GetMetricsBucketIndex();
 
-  void SetName(const base::string16& name);
+  void SetLocalProfileName(const base::string16& name);
   void SetShortcutName(const base::string16& name);
   void SetActiveTimeToNow();
   void SetIsOmitted(bool is_omitted);
@@ -156,6 +160,10 @@
                   const base::FilePath& path,
                   PrefService* prefs);
 
+  // Gets the name of the profile as the concatenation of the Gaia name and the
+  // profile name, which is the one displayed in the User Menu.
+  base::string16 GetNameToDisplay() const;
+
   // Loads or uses an already loaded high resolution image of the generic
   // profile avatar.
   const gfx::Image* GetHighResAvatar() const;
diff --git a/chrome/browser/profiles/profile_attributes_storage.cc b/chrome/browser/profiles/profile_attributes_storage.cc
index 90b93ba..6bec40e 100644
--- a/chrome/browser/profiles/profile_attributes_storage.cc
+++ b/chrome/browser/profiles/profile_attributes_storage.cc
@@ -215,7 +215,8 @@
 
     if (std::none_of(entries.begin(), entries.end(),
                      [name](ProfileAttributesEntry* entry) {
-                       return entry->GetName() == name;
+                       return entry->GetLocalProfileName() == name ||
+                              entry->GetName() == name;
                      })) {
       return name;
     }
diff --git a/chrome/browser/profiles/profile_attributes_storage_unittest.cc b/chrome/browser/profiles/profile_attributes_storage_unittest.cc
index 8273d8bb..230a8cf 100644
--- a/chrome/browser/profiles/profile_attributes_storage_unittest.cc
+++ b/chrome/browser/profiles/profile_attributes_storage_unittest.cc
@@ -298,7 +298,7 @@
   EXPECT_EQ(path, entry->GetPath());
 
   EXPECT_CALL(observer(), OnProfileNameChanged(path, _)).Times(2);
-  TEST_STRING16_ACCESSORS(ProfileAttributesEntry, entry, Name);
+  TEST_STRING16_ACCESSORS(ProfileAttributesEntry, entry, LocalProfileName);
   VerifyAndResetCallExpectations();
 
   TEST_STRING16_ACCESSORS(ProfileAttributesEntry, entry, ShortcutName);
@@ -307,8 +307,10 @@
       ProfileAttributesEntry, entry, PasswordChangeDetectionToken);
   TEST_ACCESSORS(ProfileAttributesEntry, entry, BackgroundStatus, true, false);
 
+  EXPECT_CALL(observer(), OnProfileNameChanged(path, _)).Times(4);
   TEST_STRING16_ACCESSORS(ProfileAttributesEntry, entry, GAIAName);
   TEST_STRING16_ACCESSORS(ProfileAttributesEntry, entry, GAIAGivenName);
+  VerifyAndResetCallExpectations();
 
   EXPECT_CALL(observer(), OnProfileAvatarChanged(path)).Times(2);
   TEST_BOOL_ACCESSORS(ProfileAttributesEntry, entry, IsUsingGAIAPicture);
@@ -320,7 +322,6 @@
 
   TEST_BOOL_ACCESSORS(ProfileAttributesEntry, entry, IsEphemeral);
 
-  EXPECT_CALL(observer(), OnProfileNameChanged(path, _)).Times(2);
   TEST_BOOL_ACCESSORS(ProfileAttributesEntry, entry, IsUsingDefaultName);
   VerifyAndResetCallExpectations();
 
@@ -521,7 +522,7 @@
       GetProfilePath("alpha_path"), &entry));
 
   // Trigger a ProfileInfoCache re-sort.
-  entry->SetName(base::ASCIIToUTF16("zulu_name"));
+  entry->SetLocalProfileName(base::ASCIIToUTF16("zulu_name"));
   EXPECT_EQ(GetProfilePath("alpha_path"), entry->GetPath());
 }
 
@@ -576,7 +577,7 @@
   ASSERT_TRUE(storage()->GetProfileAttributesWithPath(
       GetProfilePath("testing_profile_path0"), &second_entry));
 
-  first_entry->SetName(base::ASCIIToUTF16("NewName"));
+  first_entry->SetLocalProfileName(base::ASCIIToUTF16("NewName"));
   EXPECT_EQ(base::ASCIIToUTF16("NewName"), second_entry->GetName());
   EXPECT_EQ(first_entry, second_entry);
 
@@ -585,9 +586,9 @@
   size_t index = profile_info_cache()->GetIndexOfProfileWithPath(
       GetProfilePath("testing_profile_path0"));
   EXPECT_EQ(base::ASCIIToUTF16("NewName"),
-      profile_info_cache()->GetNameOfProfileAtIndex(index));
+            profile_info_cache()->GetNameToDisplayOfProfileAtIndex(index));
 
-  profile_info_cache()->SetNameOfProfileAtIndex(
+  profile_info_cache()->SetLocalProfileNameOfProfileAtIndex(
       index, base::ASCIIToUTF16("OtherNewName"));
   EXPECT_EQ(base::ASCIIToUTF16("OtherNewName"), first_entry->GetName());
 }
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index ecdc9b0..5f294c5 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -1526,7 +1526,7 @@
                        ->GetProfileAttributesStorage()
                        .GetProfileAttributesWithPath(GetPath(), &entry);
   if (has_entry) {
-    entry->SetName(
+    entry->SetLocalProfileName(
         base::UTF8ToUTF16(GetPrefs()->GetString(prefs::kProfileName)));
     entry->SetIsUsingDefaultName(
         GetPrefs()->GetBoolean(prefs::kProfileUsingDefaultName));
diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc
index b10361b..1f4a466e 100644
--- a/chrome/browser/profiles/profile_info_cache.cc
+++ b/chrome/browser/profiles/profile_info_cache.cc
@@ -40,9 +40,6 @@
 
 namespace {
 
-const char kNameKey[] = "name";
-const char kGAIANameKey[] = "gaia_name";
-const char kGAIAGivenNameKey[] = "gaia_given_name";
 const char kGAIAIdKey[] = "gaia_id";
 const char kIsUsingDefaultNameKey[] = "is_using_default_name";
 const char kIsUsingDefaultAvatarKey[] = "is_using_default_avatar";
@@ -60,6 +57,9 @@
 }
 
 }  // namespace
+const char ProfileInfoCache::kNameKey[] = "name";
+const char ProfileInfoCache::kGAIANameKey[] = "gaia_name";
+const char ProfileInfoCache::kGAIAGivenNameKey[] = "gaia_given_name";
 
 ProfileInfoCache::ProfileInfoCache(PrefService* prefs,
                                    const base::FilePath& user_data_dir)
@@ -153,15 +153,34 @@
     info->SetString(kAccountIdKey, account_id.GetAccountIdKey());
   cache->SetWithoutPathExpansion(key, std::move(info));
 
+  // Switching from single profile to multi-profile might change the existing
+  // profile display name. We append the profile name to GAIA name only in case
+  // of multi-profile.
+  ProfileAttributesEntry* entry = nullptr;
+  base::string16 old_single_profile_name;
+  if (GetNumberOfProfiles() == 1 &&
+      base::FeatureList::IsEnabled(kConcatenateGaiaAndProfileName)) {
+    std::vector<ProfileAttributesEntry*> entries = GetAllProfilesAttributes();
+    entry = entries[0];
+    old_single_profile_name = entry->GetName();
+  }
+
   sorted_keys_.insert(FindPositionForProfile(key, name), key);
   profile_attributes_entries_[user_data_dir_.AppendASCII(key).value()] =
       std::unique_ptr<ProfileAttributesEntry>();
 
+  bool single_profile_name_changed =
+      entry && (entry->GetName() != old_single_profile_name);
+
   if (!disable_avatar_download_for_testing_)
     DownloadHighResAvatarIfNeeded(icon_index, profile_path);
 
-  for (auto& observer : observer_list_)
+  for (auto& observer : observer_list_) {
     observer.OnProfileAdded(profile_path);
+    if (single_profile_name_changed) {
+      observer.OnProfileNameChanged(entry->GetPath(), old_single_profile_name);
+    }
+  }
 }
 
 void ProfileInfoCache::DeleteProfileFromCache(
@@ -171,6 +190,24 @@
     NOTREACHED();
     return;
   }
+  // Switching from multi-profile to single profile might change the profile
+  // display name for the single profile left after deletion of the profile with
+  // |profile_path|. We append the profile name to GAIA name only in case of
+  // multi-profile.
+  size_t number_of_profiles = GetNumberOfProfiles();
+  ProfileAttributesEntry* single_profile_entry = nullptr;
+  base::string16 old_single_profile_name;
+  if (number_of_profiles == 2 &&
+      base::FeatureList::IsEnabled(kConcatenateGaiaAndProfileName)) {
+    for (auto& it : profile_attributes_entries_) {
+      base::FilePath path(it.first);
+      if (it.first != profile_path.value()) {
+        GetProfileAttributesWithPath(path, &single_profile_entry);
+        old_single_profile_name = single_profile_entry->GetName();
+      }
+    }
+  }
+
   base::string16 name = entry->GetName();
 
   for (auto& observer : observer_list_)
@@ -183,8 +220,17 @@
   sorted_keys_.erase(std::find(sorted_keys_.begin(), sorted_keys_.end(), key));
   profile_attributes_entries_.erase(profile_path.value());
 
-  for (auto& observer : observer_list_)
+  bool single_profile_name_changed =
+      single_profile_entry &&
+      single_profile_entry->GetName() != old_single_profile_name;
+
+  for (auto& observer : observer_list_) {
     observer.OnProfileWasRemoved(profile_path, name);
+    if (single_profile_name_changed) {
+      observer.OnProfileNameChanged(single_profile_entry->GetPath(),
+                                    old_single_profile_name);
+    }
+  }
 }
 
 size_t ProfileInfoCache::GetNumberOfProfiles() const {
@@ -203,7 +249,21 @@
   return std::string::npos;
 }
 
+base::string16 ProfileInfoCache::GetNameToDisplayOfProfileAtIndex(
+    size_t index) {
+  base::FilePath profile_path = GetPathOfProfileAtIndex(index);
+  ProfileAttributesEntry* entry;
+  GetProfileAttributesWithPath(profile_path, &entry);
+  if (!entry) {
+    DLOG(ERROR) << "No entry found for this profile!";
+    return base::string16();
+  }
+
+  return entry->GetName();
+}
+
 base::string16 ProfileInfoCache::GetNameOfProfileAtIndex(size_t index) const {
+  DCHECK(!base::FeatureList::IsEnabled(kConcatenateGaiaAndProfileName));
   base::string16 name;
   // Unless the user has customized the profile name, we should use the
   // profile's Gaia given name, if it's available.
@@ -376,8 +436,9 @@
   return icon_index;
 }
 
-void ProfileInfoCache::SetNameOfProfileAtIndex(size_t index,
-                                               const base::string16& name) {
+void ProfileInfoCache::SetLocalProfileNameOfProfileAtIndex(
+    size_t index,
+    const base::string16& name) {
   std::unique_ptr<base::DictionaryValue> info(
       GetInfoForProfileAtIndex(index)->DeepCopy());
   base::string16 current_name;
@@ -385,12 +446,12 @@
   if (name == current_name)
     return;
 
-  base::string16 old_display_name = GetNameOfProfileAtIndex(index);
+  base::string16 old_display_name = GetNameToDisplayOfProfileAtIndex(index);
   info->SetString(kNameKey, name);
 
   SetInfoForProfileAtIndex(index, std::move(info));
 
-  base::string16 new_display_name = GetNameOfProfileAtIndex(index);
+  base::string16 new_display_name = GetNameToDisplayOfProfileAtIndex(index);
   base::FilePath profile_path = GetPathOfProfileAtIndex(index);
   UpdateSortForProfileIndex(index);
 
@@ -502,12 +563,12 @@
   if (name == GetGAIANameOfProfileAtIndex(index))
     return;
 
-  base::string16 old_display_name = GetNameOfProfileAtIndex(index);
+  base::string16 old_display_name = GetNameToDisplayOfProfileAtIndex(index);
   std::unique_ptr<base::DictionaryValue> info(
       GetInfoForProfileAtIndex(index)->DeepCopy());
   info->SetString(kGAIANameKey, name);
   SetInfoForProfileAtIndex(index, std::move(info));
-  base::string16 new_display_name = GetNameOfProfileAtIndex(index);
+  base::string16 new_display_name = GetNameToDisplayOfProfileAtIndex(index);
   base::FilePath profile_path = GetPathOfProfileAtIndex(index);
   UpdateSortForProfileIndex(index);
 
@@ -523,12 +584,12 @@
   if (name == GetGAIAGivenNameOfProfileAtIndex(index))
     return;
 
-  base::string16 old_display_name = GetNameOfProfileAtIndex(index);
+  base::string16 old_display_name = GetNameToDisplayOfProfileAtIndex(index);
   std::unique_ptr<base::DictionaryValue> info(
       GetInfoForProfileAtIndex(index)->DeepCopy());
   info->SetString(kGAIAGivenNameKey, name);
   SetInfoForProfileAtIndex(index, std::move(info));
-  base::string16 new_display_name = GetNameOfProfileAtIndex(index);
+  base::string16 new_display_name = GetNameToDisplayOfProfileAtIndex(index);
   base::FilePath profile_path = GetPathOfProfileAtIndex(index);
   UpdateSortForProfileIndex(index);
 
@@ -612,14 +673,14 @@
   if (value == ProfileIsUsingDefaultNameAtIndex(index))
     return;
 
-  base::string16 old_display_name = GetNameOfProfileAtIndex(index);
+  base::string16 old_display_name = GetNameToDisplayOfProfileAtIndex(index);
 
   std::unique_ptr<base::DictionaryValue> info(
       GetInfoForProfileAtIndex(index)->DeepCopy());
   info->SetBoolean(kIsUsingDefaultNameKey, value);
   SetInfoForProfileAtIndex(index, std::move(info));
 
-  base::string16 new_display_name = GetNameOfProfileAtIndex(index);
+  base::string16 new_display_name = GetNameToDisplayOfProfileAtIndex(index);
   const base::FilePath profile_path = GetPathOfProfileAtIndex(index);
 
   if (old_display_name != new_display_name) {
@@ -684,7 +745,8 @@
     const base::string16& search_name) {
   base::string16 search_name_l = base::i18n::ToLower(search_name);
   for (size_t i = 0; i < GetNumberOfProfiles(); ++i) {
-    base::string16 name_l = base::i18n::ToLower(GetNameOfProfileAtIndex(i));
+    base::string16 name_l =
+        base::i18n::ToLower(GetNameToDisplayOfProfileAtIndex(i));
     int name_compare = search_name_l.compare(name_l);
     if (name_compare < 0)
       return sorted_keys_.begin() + i;
@@ -698,7 +760,7 @@
 }
 
 void ProfileInfoCache::UpdateSortForProfileIndex(size_t index) {
-  base::string16 name = GetNameOfProfileAtIndex(index);
+  base::string16 name = GetNameToDisplayOfProfileAtIndex(index);
 
   // Remove and reinsert key in |sorted_keys_| to alphasort.
   std::string key = CacheKeyFromProfilePath(GetPathOfProfileAtIndex(index));
@@ -743,10 +805,11 @@
                                   entry->GetPath());
 
     // Rename the necessary profiles.
-    base::string16 name = base::i18n::ToLower(entry->GetName());
+    base::string16 name = base::i18n::ToLower(entry->GetLocalProfileName());
     if (name == default_profile_name || name == default_legacy_profile_name) {
       entry->SetIsUsingDefaultName(true);
-      entry->SetName(ChooseNameForNewProfile(entry->GetAvatarIconIndex()));
+      entry->SetLocalProfileName(
+          ChooseNameForNewProfile(entry->GetAvatarIconIndex()));
     }
   }
 #endif
diff --git a/chrome/browser/profiles/profile_info_cache.h b/chrome/browser/profiles/profile_info_cache.h
index 6cd3d14..4cf7e58 100644
--- a/chrome/browser/profiles/profile_info_cache.h
+++ b/chrome/browser/profiles/profile_info_cache.h
@@ -73,6 +73,8 @@
   // directly referring to this implementation.
   size_t GetIndexOfProfileWithPath(
       const base::FilePath& profile_path) const override;
+  // Deprecated 10/2019, Do not use!
+  // Use GetNameToDisplayOfProfileAtIndex instead.
   base::string16 GetNameOfProfileAtIndex(size_t index) const override;
   // Will be removed SOON with ProfileInfoCache tests. Do not use!
   base::FilePath GetPathOfProfileAtIndex(size_t index) const override;
@@ -109,7 +111,8 @@
   size_t GetAvatarIconIndexOfProfileAtIndex(size_t index) const;
 
   // Warning: This will re-sort profiles and thus may change indices!
-  void SetNameOfProfileAtIndex(size_t index, const base::string16& name);
+  void SetLocalProfileNameOfProfileAtIndex(size_t index,
+                                           const base::string16& name);
   void SetAuthInfoOfProfileAtIndex(size_t index,
                                    const std::string& gaia_id,
                                    const base::string16& user_name,
@@ -137,6 +140,9 @@
 
   const base::FilePath& GetUserDataDir() const;
 
+  // Gets the name of the profile, which is the one displayed in the User Menu.
+  base::string16 GetNameToDisplayOfProfileAtIndex(size_t index);
+
   // Register cache related preferences in Local State.
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
@@ -155,6 +161,10 @@
   bool GetProfileAttributesWithPath(const base::FilePath& path,
                                     ProfileAttributesEntry** entry) override;
 
+  static const char kNameKey[];
+  static const char kGAIANameKey[];
+  static const char kGAIAGivenNameKey[];
+
  private:
   FRIEND_TEST_ALL_PREFIXES(ProfileAttributesStorageTest,
                            DownloadHighResAvatarTest);
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.cc b/chrome/browser/profiles/profile_info_cache_unittest.cc
index 9ebc8b7f..d99453d 100644
--- a/chrome/browser/profiles/profile_info_cache_unittest.cc
+++ b/chrome/browser/profiles/profile_info_cache_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/stl_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
@@ -54,7 +55,7 @@
 
 void ProfileNameVerifierObserver::OnProfileAdded(
     const base::FilePath& profile_path) {
-  base::string16 profile_name = GetCache()->GetNameOfProfileAtIndex(
+  base::string16 profile_name = GetCache()->GetNameToDisplayOfProfileAtIndex(
       GetCache()->GetIndexOfProfileWithPath(profile_path));
   EXPECT_TRUE(profile_names_.find(profile_name) == profile_names_.end());
   profile_names_.insert(profile_name);
@@ -62,7 +63,7 @@
 
 void ProfileNameVerifierObserver::OnProfileWillBeRemoved(
     const base::FilePath& profile_path) {
-  base::string16 profile_name = GetCache()->GetNameOfProfileAtIndex(
+  base::string16 profile_name = GetCache()->GetNameToDisplayOfProfileAtIndex(
       GetCache()->GetIndexOfProfileWithPath(profile_path));
   EXPECT_TRUE(profile_names_.find(profile_name) != profile_names_.end());
   profile_names_.erase(profile_name);
@@ -77,8 +78,9 @@
 void ProfileNameVerifierObserver::OnProfileNameChanged(
     const base::FilePath& profile_path,
     const base::string16& old_profile_name) {
-  base::string16 new_profile_name = GetCache()->GetNameOfProfileAtIndex(
-      GetCache()->GetIndexOfProfileWithPath(profile_path));
+  base::string16 new_profile_name =
+      GetCache()->GetNameToDisplayOfProfileAtIndex(
+          GetCache()->GetIndexOfProfileWithPath(profile_path));
   EXPECT_TRUE(profile_names_.find(old_profile_name) != profile_names_.end());
   EXPECT_TRUE(profile_names_.find(new_profile_name) == profile_names_.end());
   profile_names_.erase(old_profile_name);
@@ -87,7 +89,7 @@
 
 void ProfileNameVerifierObserver::OnProfileAvatarChanged(
     const base::FilePath& profile_path) {
-  base::string16 profile_name = GetCache()->GetNameOfProfileAtIndex(
+  base::string16 profile_name = GetCache()->GetNameToDisplayOfProfileAtIndex(
       GetCache()->GetIndexOfProfileWithPath(profile_path));
   EXPECT_TRUE(profile_names_.find(profile_name) != profile_names_.end());
 }
@@ -128,7 +130,61 @@
   testing_profile_manager_.DeleteProfileInfoCache();
 }
 
-TEST_F(ProfileInfoCacheTest, AddProfiles) {
+class ProfileInfoCacheTestWithParam
+    : public ProfileInfoCacheTest,
+      public ::testing::WithParamInterface<bool> {
+ public:
+  ProfileInfoCacheTestWithParam() : ProfileInfoCacheTest() {
+    concatenate_enabled_ = GetParam();
+    if (concatenate_enabled_) {
+      scoped_feature_list_.InitAndEnableFeature(kConcatenateGaiaAndProfileName);
+    } else {
+      scoped_feature_list_.InitAndDisableFeature(
+          kConcatenateGaiaAndProfileName);
+    }
+  }
+
+  base::string16 GetExpectedNameToDisplay(const base::string16& gaia_name,
+                                          const base::string16 profile_name,
+                                          bool is_using_default,
+                                          bool concatenate_enabled,
+                                          bool single_profile) {
+    if (gaia_name.empty() || profile_name.empty())
+      return gaia_name.empty() ? profile_name : gaia_name;
+
+    if (!concatenate_enabled)
+      return is_using_default ? gaia_name : profile_name;
+
+    if (single_profile)
+      return gaia_name;
+
+    auto it = std::search(gaia_name.begin(), gaia_name.end(),
+                          profile_name.begin(), profile_name.end(),
+                          base::CaseInsensitiveCompareASCII<char>());
+
+    if (it != gaia_name.end())
+      return gaia_name;
+
+    base::string16 name_to_display(gaia_name);
+    name_to_display.append(base::UTF8ToUTF16(" ("));
+    name_to_display.append(profile_name);
+    name_to_display.append(base::UTF8ToUTF16(")"));
+    return name_to_display;
+  }
+
+ protected:
+  base::test::ScopedFeatureList scoped_feature_list_;
+  bool concatenate_enabled_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ProfileInfoCacheTestWithParam);
+};
+
+INSTANTIATE_TEST_SUITE_P(ProfileInfoCacheTest,
+                         ProfileInfoCacheTestWithParam,
+                         testing::Bool());
+
+TEST_P(ProfileInfoCacheTestWithParam, AddProfiles) {
   EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
   // Avatar icons not used on Android.
 #if !defined(OS_ANDROID)
@@ -159,7 +215,10 @@
     GetCache()->SetGAIANameOfProfileAtIndex(i, gaia_name);
 
     EXPECT_EQ(i + 1, GetCache()->GetNumberOfProfiles());
-    EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(i));
+    EXPECT_EQ(GetExpectedNameToDisplay(gaia_name, profile_name, false,
+                                       concatenate_enabled_,
+                                       GetCache()->GetNumberOfProfiles() == 1),
+              GetCache()->GetNameToDisplayOfProfileAtIndex(i));
     EXPECT_EQ(profile_path, GetCache()->GetPathOfProfileAtIndex(i));
 #if !defined(OS_ANDROID)
     const SkBitmap* actual_icon =
@@ -188,16 +247,132 @@
     EXPECT_EQ(i, GetCache()->GetIndexOfProfileWithPath(profile_path));
     base::string16 profile_name =
         ASCIIToUTF16(base::StringPrintf("name_%ud", i));
-    EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(i));
+    base::string16 gaia_name = ASCIIToUTF16(base::StringPrintf("gaia_%ud", i));
+    EXPECT_EQ(GetExpectedNameToDisplay(gaia_name, profile_name, false,
+                                       concatenate_enabled_, false),
+              GetCache()->GetNameToDisplayOfProfileAtIndex(i));
 #if !defined(OS_ANDROID)
     EXPECT_EQ(i, GetCache()->GetAvatarIconIndexOfProfileAtIndex(i));
 #endif
     EXPECT_EQ(true, GetCache()->GetBackgroundStatusOfProfileAtIndex(i));
-    base::string16 gaia_name = ASCIIToUTF16(base::StringPrintf("gaia_%ud", i));
     EXPECT_EQ(gaia_name, GetCache()->GetGAIANameOfProfileAtIndex(i));
   }
 }
 
+TEST_P(ProfileInfoCacheTestWithParam, GAIAName) {
+  GetCache()->AddProfileToCache(
+      GetProfilePath("path_1"), ASCIIToUTF16("Person 1"), std::string(),
+      base::string16(), false, 0, std::string(), EmptyAccountId());
+  base::string16 profile_name(ASCIIToUTF16("Person 2"));
+  GetCache()->AddProfileToCache(GetProfilePath("path_2"), profile_name,
+                                std::string(), base::string16(), false, 0,
+                                std::string(), EmptyAccountId());
+
+  int index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
+  int index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
+
+  // Sanity check.
+  EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index1).empty());
+  EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index2).empty());
+
+  // Set GAIA name. This re-sorts the cache.
+  base::string16 gaia_name(ASCIIToUTF16("Pat Smith"));
+  GetCache()->SetGAIANameOfProfileAtIndex(index2, gaia_name);
+  index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
+  index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
+
+  // Since there is a GAIA name, we use that as a display name.
+  EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index1).empty());
+  EXPECT_EQ(gaia_name, GetCache()->GetGAIANameOfProfileAtIndex(index2));
+  EXPECT_EQ(GetExpectedNameToDisplay(gaia_name, profile_name, true,
+                                     concatenate_enabled_, false),
+            GetCache()->GetNameToDisplayOfProfileAtIndex(index2));
+
+  // This re-sorts the cache.
+  base::string16 custom_name(ASCIIToUTF16("Custom name"));
+  GetCache()->SetLocalProfileNameOfProfileAtIndex(index2, custom_name);
+  GetCache()->SetProfileIsUsingDefaultNameAtIndex(index2, false);
+
+  index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
+  index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
+
+  EXPECT_EQ(GetExpectedNameToDisplay(gaia_name, custom_name, false,
+                                     concatenate_enabled_, false),
+            GetCache()->GetNameToDisplayOfProfileAtIndex(index2));
+  EXPECT_EQ(gaia_name, GetCache()->GetGAIANameOfProfileAtIndex(index2));
+}
+
+TEST_F(ProfileInfoCacheTest, ConcatenateGaiaNameAndProfileName) {
+  base::test::ScopedFeatureList scoped_feature_list;
+  scoped_feature_list.InitAndEnableFeature(kConcatenateGaiaAndProfileName);
+
+  // Single profile should not append the profile name to Gaia name.
+  GetCache()->AddProfileToCache(
+      GetProfilePath("path_1"), ASCIIToUTF16("Person 1"), std::string(),
+      base::string16(), false, 0, std::string(), EmptyAccountId());
+  int index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
+  EXPECT_EQ(ASCIIToUTF16("Person 1"),
+            GetCache()->GetNameToDisplayOfProfileAtIndex(index1));
+  GetCache()->SetGAIANameOfProfileAtIndex(index1, ASCIIToUTF16("Patt Smith"));
+  EXPECT_EQ(ASCIIToUTF16("Patt Smith"),
+            GetCache()->GetNameToDisplayOfProfileAtIndex(index1));
+  GetCache()->SetGAIAGivenNameOfProfileAtIndex(index1, ASCIIToUTF16("Patt"));
+  EXPECT_EQ(ASCIIToUTF16("Patt"),
+            GetCache()->GetNameToDisplayOfProfileAtIndex(index1));
+
+  // Multiple profiles.
+  GetCache()->AddProfileToCache(
+      GetProfilePath("path_2"), ASCIIToUTF16("Person 2"), std::string(),
+      base::string16(), false, 0, std::string(), EmptyAccountId());
+
+  index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
+  EXPECT_EQ(ASCIIToUTF16("Patt (Person 1)"),
+            GetCache()->GetNameToDisplayOfProfileAtIndex(index1));
+
+  int index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
+  EXPECT_EQ(ASCIIToUTF16("Person 2"),
+            GetCache()->GetNameToDisplayOfProfileAtIndex(index2));
+  // Set Gaia name.
+  GetCache()->SetGAIANameOfProfileAtIndex(index2, ASCIIToUTF16("Patti Smith"));
+  index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
+  // Profile name is a substring of Gaia name.
+  GetCache()->SetLocalProfileNameOfProfileAtIndex(index2,
+                                                  ASCIIToUTF16("patti"));
+  index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
+  EXPECT_EQ(ASCIIToUTF16("Patti Smith"),
+            GetCache()->GetNameToDisplayOfProfileAtIndex(index2));
+  // Profile name equals Gaia given name.
+  GetCache()->SetGAIAGivenNameOfProfileAtIndex(index2, ASCIIToUTF16("Patti"));
+  index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
+  EXPECT_EQ(ASCIIToUTF16("Patti"),
+            GetCache()->GetNameToDisplayOfProfileAtIndex(index2));
+  GetCache()->SetLocalProfileNameOfProfileAtIndex(index2, ASCIIToUTF16("Work"));
+  EXPECT_EQ(ASCIIToUTF16("Patti (Work)"),
+            GetCache()->GetNameToDisplayOfProfileAtIndex(index2));
+
+  // Empty profile name.
+  GetCache()->AddProfileToCache(GetProfilePath("path_3"), base::string16(),
+                                std::string(), base::string16(), false, 0,
+                                std::string(), EmptyAccountId());
+  int index3 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_3"));
+  GetCache()->SetGAIAGivenNameOfProfileAtIndex(index3, ASCIIToUTF16("Pat"));
+  index3 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_3"));
+  EXPECT_EQ(ASCIIToUTF16("Pat"),
+            GetCache()->GetNameToDisplayOfProfileAtIndex(index3));
+  GetCache()->SetGAIANameOfProfileAtIndex(index3, ASCIIToUTF16("Pat Smith"));
+  GetCache()->SetGAIAGivenNameOfProfileAtIndex(index3, ASCIIToUTF16(""));
+  index3 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_3"));
+  EXPECT_EQ(ASCIIToUTF16("Pat Smith"),
+            GetCache()->GetNameToDisplayOfProfileAtIndex(index3));
+
+  // Single profile.
+  GetCache()->DeleteProfileFromCache(GetProfilePath("path_1"));
+  GetCache()->DeleteProfileFromCache(GetProfilePath("path_3"));
+  index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
+  EXPECT_EQ(ASCIIToUTF16("Patti"),
+            GetCache()->GetNameToDisplayOfProfileAtIndex(index2));
+}
+
 TEST_F(ProfileInfoCacheTest, DeleteProfile) {
   EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
 
@@ -215,7 +390,7 @@
 
   GetCache()->DeleteProfileFromCache(path_1);
   EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
-  EXPECT_EQ(name_2, GetCache()->GetNameOfProfileAtIndex(0));
+  EXPECT_EQ(name_2, GetCache()->GetNameToDisplayOfProfileAtIndex(0));
 
   GetCache()->DeleteProfileFromCache(path_2);
   EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
@@ -230,9 +405,9 @@
       base::string16(), false, 0, std::string(), EmptyAccountId());
 
   base::string16 new_name = ASCIIToUTF16("new_name");
-  GetCache()->SetNameOfProfileAtIndex(1, new_name);
-  EXPECT_EQ(new_name, GetCache()->GetNameOfProfileAtIndex(1));
-  EXPECT_NE(new_name, GetCache()->GetNameOfProfileAtIndex(0));
+  GetCache()->SetLocalProfileNameOfProfileAtIndex(1, new_name);
+  EXPECT_EQ(new_name, GetCache()->GetNameToDisplayOfProfileAtIndex(1));
+  EXPECT_NE(new_name, GetCache()->GetNameToDisplayOfProfileAtIndex(0));
 
   base::string16 new_user_name = ASCIIToUTF16("user_name");
   std::string new_gaia_id = "12345";
@@ -269,8 +444,8 @@
                                 EmptyAccountId());
 
   // Sanity check the initial order.
-  EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(0));
-  EXPECT_EQ(name_c, GetCache()->GetNameOfProfileAtIndex(1));
+  EXPECT_EQ(name_a, GetCache()->GetNameToDisplayOfProfileAtIndex(0));
+  EXPECT_EQ(name_c, GetCache()->GetNameToDisplayOfProfileAtIndex(1));
 
   // Add a new profile (start with a capital to test case insensitive sorting.
   base::string16 name_b = ASCIIToUTF16("Banana");
@@ -279,25 +454,25 @@
                                 EmptyAccountId());
 
   // Verify the new order.
-  EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(0));
-  EXPECT_EQ(name_b, GetCache()->GetNameOfProfileAtIndex(1));
-  EXPECT_EQ(name_c, GetCache()->GetNameOfProfileAtIndex(2));
+  EXPECT_EQ(name_a, GetCache()->GetNameToDisplayOfProfileAtIndex(0));
+  EXPECT_EQ(name_b, GetCache()->GetNameToDisplayOfProfileAtIndex(1));
+  EXPECT_EQ(name_c, GetCache()->GetNameToDisplayOfProfileAtIndex(2));
 
   // Change the name of an existing profile.
   name_a = UTF8ToUTF16("dog");
-  GetCache()->SetNameOfProfileAtIndex(0, name_a);
+  GetCache()->SetLocalProfileNameOfProfileAtIndex(0, name_a);
 
   // Verify the new order.
-  EXPECT_EQ(name_b, GetCache()->GetNameOfProfileAtIndex(0));
-  EXPECT_EQ(name_c, GetCache()->GetNameOfProfileAtIndex(1));
-  EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(2));
+  EXPECT_EQ(name_b, GetCache()->GetNameToDisplayOfProfileAtIndex(0));
+  EXPECT_EQ(name_c, GetCache()->GetNameToDisplayOfProfileAtIndex(1));
+  EXPECT_EQ(name_a, GetCache()->GetNameToDisplayOfProfileAtIndex(2));
 
   // Delete a profile.
   GetCache()->DeleteProfileFromCache(GetProfilePath("path_c"));
 
   // Verify the new order.
-  EXPECT_EQ(name_b, GetCache()->GetNameOfProfileAtIndex(0));
-  EXPECT_EQ(name_a, GetCache()->GetNameOfProfileAtIndex(1));
+  EXPECT_EQ(name_b, GetCache()->GetNameToDisplayOfProfileAtIndex(0));
+  EXPECT_EQ(name_a, GetCache()->GetNameToDisplayOfProfileAtIndex(1));
 }
 
 // Will be removed SOON with ProfileInfoCache tests.
@@ -328,45 +503,6 @@
   EXPECT_FALSE(GetCache()->GetBackgroundStatusOfProfileAtIndex(1));
 }
 
-TEST_F(ProfileInfoCacheTest, GAIAName) {
-  GetCache()->AddProfileToCache(
-      GetProfilePath("path_1"), ASCIIToUTF16("Person 1"), std::string(),
-      base::string16(), false, 0, std::string(), EmptyAccountId());
-  base::string16 profile_name(ASCIIToUTF16("Person 2"));
-  GetCache()->AddProfileToCache(GetProfilePath("path_2"), profile_name,
-                                std::string(), base::string16(), false, 0,
-                                std::string(), EmptyAccountId());
-
-  int index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
-  int index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
-
-  // Sanity check.
-  EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index1).empty());
-  EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index2).empty());
-
-  // Set GAIA name. This re-sorts the cache.
-  base::string16 gaia_name(ASCIIToUTF16("Pat Smith"));
-  GetCache()->SetGAIANameOfProfileAtIndex(index2, gaia_name);
-  index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
-  index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
-
-  // Since there is a GAIA name, we use that as a display name.
-  EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(index1).empty());
-  EXPECT_EQ(gaia_name, GetCache()->GetGAIANameOfProfileAtIndex(index2));
-  EXPECT_EQ(gaia_name, GetCache()->GetNameOfProfileAtIndex(index2));
-
-  // Don't use GAIA name as profile name. This re-sorts the cache.
-  base::string16 custom_name(ASCIIToUTF16("Custom name"));
-  GetCache()->SetNameOfProfileAtIndex(index2, custom_name);
-  GetCache()->SetProfileIsUsingDefaultNameAtIndex(index2, false);
-
-  index1 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_1"));
-  index2 = GetCache()->GetIndexOfProfileWithPath(GetProfilePath("path_2"));
-
-  EXPECT_EQ(custom_name, GetCache()->GetNameOfProfileAtIndex(index2));
-  EXPECT_EQ(gaia_name, GetCache()->GetGAIANameOfProfileAtIndex(index2));
-}
-
 TEST_F(ProfileInfoCacheTest, GAIAPicture) {
   const int kDefaultAvatarIndex = 0;
   const int kOtherAvatarIndex = 1;
@@ -507,7 +643,7 @@
   GetCache()->SetIsUsingGAIAPictureOfProfileAtIndex(0, true);
 
   // Verify that the profile name and picture are not empty.
-  EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(0));
+  EXPECT_EQ(profile_name, GetCache()->GetNameToDisplayOfProfileAtIndex(0));
   EXPECT_TRUE(gfx::test::AreImagesEqual(
       profile_image, GetCache()->GetAvatarIconOfProfileAtIndex(0)));
 }
@@ -522,7 +658,7 @@
       TestingProfile::TestingFactories());
   for (size_t i = 0; i < GetCache()->GetNumberOfProfiles(); i++) {
     bool is_supervised =
-        GetCache()->GetNameOfProfileAtIndex(i) == supervised_user_name;
+        GetCache()->GetNameToDisplayOfProfileAtIndex(i) == supervised_user_name;
     EXPECT_EQ(is_supervised, GetCache()->ProfileIsSupervisedAtIndex(i));
     std::string supervised_user_id =
         is_supervised ? supervised_users::kChildAccountSUID : "";
@@ -560,7 +696,7 @@
                                   EmptyAccountId());
 
     EXPECT_EQ(profile_path, GetCache()->GetPathOfProfileAtIndex(i));
-    EXPECT_EQ(profile_name, GetCache()->GetNameOfProfileAtIndex(i));
+    EXPECT_EQ(profile_name, GetCache()->GetNameToDisplayOfProfileAtIndex(i));
   }
 
   ASSERT_EQ(4U, GetCache()->GetNumberOfProfiles());
@@ -695,28 +831,28 @@
   // migrated to "Person %n" type names, i.e. any permutation of "Person 1" and
   // "Person 3".
   if (ASCIIToUTF16("Person 1") ==
-      GetCache()->GetNameOfProfileAtIndex(
+      GetCache()->GetNameToDisplayOfProfileAtIndex(
           GetCache()->GetIndexOfProfileWithPath(path_1))) {
     EXPECT_EQ(ASCIIToUTF16("Person 3"),
-              GetCache()->GetNameOfProfileAtIndex(
+              GetCache()->GetNameToDisplayOfProfileAtIndex(
                   GetCache()->GetIndexOfProfileWithPath(path_2)));
   } else {
     EXPECT_EQ(ASCIIToUTF16("Person 3"),
-              GetCache()->GetNameOfProfileAtIndex(
+              GetCache()->GetNameToDisplayOfProfileAtIndex(
                   GetCache()->GetIndexOfProfileWithPath(path_1)));
     EXPECT_EQ(ASCIIToUTF16("Person 1"),
-              GetCache()->GetNameOfProfileAtIndex(
+              GetCache()->GetNameToDisplayOfProfileAtIndex(
                   GetCache()->GetIndexOfProfileWithPath(path_2)));
   }
 
   // Other profile names should not be migrated even if they're the old
   // default cartoon profile names.
-  EXPECT_EQ(name_3, GetCache()->GetNameOfProfileAtIndex(
-      GetCache()->GetIndexOfProfileWithPath(path_3)));
-  EXPECT_EQ(name_4, GetCache()->GetNameOfProfileAtIndex(
-      GetCache()->GetIndexOfProfileWithPath(path_4)));
-  EXPECT_EQ(name_5, GetCache()->GetNameOfProfileAtIndex(
-      GetCache()->GetIndexOfProfileWithPath(path_5)));
+  EXPECT_EQ(name_3, GetCache()->GetNameToDisplayOfProfileAtIndex(
+                        GetCache()->GetIndexOfProfileWithPath(path_3)));
+  EXPECT_EQ(name_4, GetCache()->GetNameToDisplayOfProfileAtIndex(
+                        GetCache()->GetIndexOfProfileWithPath(path_4)));
+  EXPECT_EQ(name_5, GetCache()->GetNameToDisplayOfProfileAtIndex(
+                        GetCache()->GetIndexOfProfileWithPath(path_5)));
 }
 
 TEST_F(ProfileInfoCacheTest, GetGaiaImageForAvatarMenu) {
@@ -790,14 +926,14 @@
   ResetCache();
 
   // Profile names should have been preserved.
-  EXPECT_EQ(name_1, GetCache()->GetNameOfProfileAtIndex(
-      GetCache()->GetIndexOfProfileWithPath(path_1)));
-  EXPECT_EQ(name_2, GetCache()->GetNameOfProfileAtIndex(
-      GetCache()->GetIndexOfProfileWithPath(path_2)));
-  EXPECT_EQ(name_3, GetCache()->GetNameOfProfileAtIndex(
-      GetCache()->GetIndexOfProfileWithPath(path_3)));
-  EXPECT_EQ(name_4, GetCache()->GetNameOfProfileAtIndex(
-      GetCache()->GetIndexOfProfileWithPath(path_4)));
+  EXPECT_EQ(name_1, GetCache()->GetNameToDisplayOfProfileAtIndex(
+                        GetCache()->GetIndexOfProfileWithPath(path_1)));
+  EXPECT_EQ(name_2, GetCache()->GetNameToDisplayOfProfileAtIndex(
+                        GetCache()->GetIndexOfProfileWithPath(path_2)));
+  EXPECT_EQ(name_3, GetCache()->GetNameToDisplayOfProfileAtIndex(
+                        GetCache()->GetIndexOfProfileWithPath(path_3)));
+  EXPECT_EQ(name_4, GetCache()->GetNameToDisplayOfProfileAtIndex(
+                        GetCache()->GetIndexOfProfileWithPath(path_4)));
 }
 #endif
 
@@ -842,22 +978,22 @@
 
   GetCache()->RemoveProfileByAccountId(account_id_3);
   EXPECT_EQ(3u, GetCache()->GetNumberOfProfiles());
-  EXPECT_EQ(name_1, GetCache()->GetNameOfProfileAtIndex(0));
+  EXPECT_EQ(name_1, GetCache()->GetNameToDisplayOfProfileAtIndex(0));
 
   GetCache()->RemoveProfileByAccountId(account_id_1);
   EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
-  EXPECT_EQ(name_2, GetCache()->GetNameOfProfileAtIndex(0));
+  EXPECT_EQ(name_2, GetCache()->GetNameToDisplayOfProfileAtIndex(0));
 
   // this profile is already deleted.
   GetCache()->RemoveProfileByAccountId(account_id_3);
   EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
-  EXPECT_EQ(name_2, GetCache()->GetNameOfProfileAtIndex(0));
+  EXPECT_EQ(name_2, GetCache()->GetNameToDisplayOfProfileAtIndex(0));
 
   // Remove profile by partial match
   GetCache()->RemoveProfileByAccountId(
       AccountId::FromUserEmail(account_id_2.GetUserEmail()));
   EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
-  EXPECT_EQ(name_4, GetCache()->GetNameOfProfileAtIndex(0));
+  EXPECT_EQ(name_4, GetCache()->GetNameToDisplayOfProfileAtIndex(0));
 
   // Remove last profile
   GetCache()->RemoveProfileByAccountId(account_id_4);
diff --git a/chrome/browser/profiles/profile_list_desktop_unittest.cc b/chrome/browser/profiles/profile_list_desktop_unittest.cc
index c4877af3..59eb638 100644
--- a/chrome/browser/profiles/profile_list_desktop_unittest.cc
+++ b/chrome/browser/profiles/profile_list_desktop_unittest.cc
@@ -217,7 +217,7 @@
   ProfileAttributesEntry* entry;
   ASSERT_TRUE(manager()->profile_attributes_storage()->
                   GetProfileAttributesWithPath(profile1->GetPath(), &entry));
-  entry->SetName(ASCIIToUTF16(newname1));
+  entry->SetLocalProfileName(ASCIIToUTF16(newname1));
   EXPECT_EQ(1, change_count());
 
   // Now the first menu item should be named "beta", and the second be "gamma".
diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
index 5e4950d5..4e44716 100644
--- a/chrome/browser/profiles/profile_manager.cc
+++ b/chrome/browser/profiles/profile_manager.cc
@@ -1009,7 +1009,7 @@
     // data in the profile attributes storage.
     if (has_entry) {
       avatar_index = entry->GetAvatarIconIndex();
-      profile_name = base::UTF16ToUTF8(entry->GetName());
+      profile_name = base::UTF16ToUTF8(entry->GetLocalProfileName());
       supervised_user_id = entry->GetSupervisedUserId();
     } else if (profile->GetPath() ==
                    profiles::GetDefaultProfileDir(user_data_dir())) {
@@ -1030,8 +1030,9 @@
   if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileAvatarIndex))
     profile->GetPrefs()->SetInteger(prefs::kProfileAvatarIndex, avatar_index);
 
-  if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileName))
+  if (!profile->GetPrefs()->HasPrefPath(prefs::kProfileName)) {
     profile->GetPrefs()->SetString(prefs::kProfileName, profile_name);
+  }
 
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
   bool force_supervised_user_id =
diff --git a/chrome/browser/profiles/profile_manager_unittest.cc b/chrome/browser/profiles/profile_manager_unittest.cc
index 742c02e9..047a0cef 100644
--- a/chrome/browser/profiles/profile_manager_unittest.cc
+++ b/chrome/browser/profiles/profile_manager_unittest.cc
@@ -1444,7 +1444,7 @@
   // We should display custom names for local profiles.
   const base::string16 custom_profile_name = ASCIIToUTF16("Batman");
   ProfileAttributesEntry* entry = storage.GetAllProfilesAttributes()[0];
-  entry->SetName(custom_profile_name);
+  entry->SetLocalProfileName(custom_profile_name);
   entry->SetIsUsingDefaultName(false);
   EXPECT_EQ(custom_profile_name, entry->GetName());
   EXPECT_EQ(custom_profile_name,
@@ -1501,13 +1501,17 @@
   entry->SetGAIAGivenName(gaia_given_name);
   EXPECT_EQ(gaia_given_name, entry->GetName());
   EXPECT_EQ(gaia_given_name,
-      profiles::GetAvatarNameForProfile(profile1->GetPath()));
+            profiles::GetAvatarNameForProfile(profile1->GetPath()));
 
   // Multiple profiles means displaying the actual profile names.
   const base::string16 profile_name2 = storage.ChooseNameForNewProfile(1u);
   Profile* profile2 = AddProfileToStorage(profile_manager,
                                           "path_2", profile_name2);
-  EXPECT_EQ(gaia_given_name,
+  base::string16 expected_profile_name(gaia_given_name);
+  expected_profile_name.append(ASCIIToUTF16(" ("));
+  expected_profile_name.append(profile_name1);
+  expected_profile_name.append(ASCIIToUTF16(")"));
+  EXPECT_EQ(expected_profile_name,
             profiles::GetAvatarNameForProfile(profile1->GetPath()));
   EXPECT_EQ(profile_name2,
             profiles::GetAvatarNameForProfile(profile2->GetPath()));
@@ -1576,7 +1580,7 @@
 
   // Adding a Gaia name to a profile that previously had a default name should
   // start displaying it.
-  const base::string16 gaia_given_name(ASCIIToUTF16("Robin"));
+  const base::string16 gaia_given_name(ASCIIToUTF16("Robin (Person 1)"));
   ASSERT_TRUE(storage.GetProfileAttributesWithPath(profile1->GetPath(),
                                                    &entry));
   entry->SetGAIAGivenName(gaia_given_name);
diff --git a/chrome/browser/profiles/profile_metrics.cc b/chrome/browser/profiles/profile_metrics.cc
index dd4139e..5090c283 100644
--- a/chrome/browser/profiles/profile_metrics.cc
+++ b/chrome/browser/profiles/profile_metrics.cc
@@ -199,7 +199,7 @@
       counts->unused++;
     } else {
       counts->active++;
-      if (!storage.IsDefaultProfileName(entry->GetName()))
+      if (!storage.IsDefaultProfileName(entry->GetLocalProfileName()))
         counts->named++;
       if (entry->IsSupervised())
         counts->supervised++;
diff --git a/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc b/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc
index 9d69da5..cc5c54a 100644
--- a/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc
+++ b/chrome/browser/profiles/profile_shortcut_manager_unittest_win.cc
@@ -314,8 +314,8 @@
     ProfileAttributesEntry* entry;
     ASSERT_TRUE(profile_attributes_storage_->
                     GetProfileAttributesWithPath(profile_path, &entry));
-    ASSERT_NE(entry->GetName(), new_profile_name);
-    entry->SetName(new_profile_name);
+    ASSERT_NE(entry->GetLocalProfileName(), new_profile_name);
+    entry->SetLocalProfileName(new_profile_name);
     task_environment_.RunUntilIdle();
   }
 
@@ -783,7 +783,7 @@
   EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_3_name_));
 
   const base::string16 new_profile_3_name = L"New Name 3";
-  entry_3->SetName(new_profile_3_name);
+  entry_3->SetLocalProfileName(new_profile_3_name);
   task_environment_.RunUntilIdle();
   EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_3_name_));
   EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(new_profile_3_name));
@@ -793,7 +793,7 @@
   ProfileAttributesEntry* entry_2;
   ASSERT_TRUE(profile_attributes_storage_->
                   GetProfileAttributesWithPath(profile_2_path_, &entry_2));
-  entry_2->SetName(new_profile_2_name);
+  entry_2->SetLocalProfileName(new_profile_2_name);
   task_environment_.RunUntilIdle();
   EXPECT_FALSE(ProfileShortcutExistsAtDefaultPath(profile_2_name_));
   ValidateProfileShortcut(FROM_HERE, new_profile_2_name, profile_2_path_);
diff --git a/chrome/browser/profiles/profiles_state.cc b/chrome/browser/profiles/profiles_state.cc
index 7d212dc..3a67d03 100644
--- a/chrome/browser/profiles/profiles_state.cc
+++ b/chrome/browser/profiles/profiles_state.cc
@@ -133,7 +133,12 @@
     return;
   }
 
-  if (new_profile_name == entry->GetName())
+  base::string16 current_profile_name =
+      base::FeatureList::IsEnabled(kConcatenateGaiaAndProfileName)
+          ? entry->GetLocalProfileName()
+          : entry->GetName();
+
+  if (new_profile_name == current_profile_name)
     return;
 
   // This is only called when updating the profile name through the UI,
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn
index 800135310..08948cf 100644
--- a/chrome/browser/resources/BUILD.gn
+++ b/chrome/browser/resources/BUILD.gn
@@ -364,10 +364,12 @@
     "$root_gen_dir/chrome/bluetooth_internals_resources.pak",
     "$root_gen_dir/chrome/omnibox_resources.pak",
     "$root_gen_dir/chrome/usb_internals_resources.pak",
+    "$root_gen_dir/components/sync_driver_resources.pak",
   ]
   deps = [
     "//chrome/browser/resources/bluetooth_internals:resources",
     "//chrome/browser/resources/omnibox:resources",
     "//chrome/browser/resources/usb_internals:resources",
+    "//components/sync/driver:resources",
   ]
 }
diff --git a/chrome/browser/resources/chromeos/login/screen_error_message.css b/chrome/browser/resources/chromeos/login/screen_error_message.css
index 1e1b4f2..ab4b158 100644
--- a/chrome/browser/resources/chromeos/login/screen_error_message.css
+++ b/chrome/browser/resources/chromeos/login/screen_error_message.css
@@ -2,10 +2,6 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file. */
 
-#error-message {
-  width: 768px;
-}
-
 .show-with-ui-state-update,
 .show-with-ui-state-signin,
 .show-with-ui-state-supervised,
diff --git a/chrome/browser/resources/user_manager/shared_styles.html b/chrome/browser/resources/user_manager/shared_styles.html
index 3bc6fc4..9d3367b9 100644
--- a/chrome/browser/resources/user_manager/shared_styles.html
+++ b/chrome/browser/resources/user_manager/shared_styles.html
@@ -39,8 +39,8 @@
       @media (prefers-color-scheme: dark) {
         .product-logo {
           content: -webkit-image-set(
-              url(../../../app/theme/default_100_percent/%DISTRIBUTION%/product_logo_white.png) 1x,
-              url(../../../app/theme/default_200_percent/%DISTRIBUTION%/product_logo_white.png) 2x);
+              url(../../../../components/resources/default_100_percent/%DISTRIBUTION%/product_logo_white.png) 1x,
+              url(../../../../components/resources/default_200_percent/%DISTRIBUTION%/product_logo_white.png) 2x);
         }
       }
     </style>
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc
index ec5dd0f9..196ffd29 100644
--- a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc
+++ b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc
@@ -329,7 +329,7 @@
 }
 
 void CertificateReportingServiceTestHelper::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   NOTREACHED();
 }
 
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h
index ebf88fc..209a234b 100644
--- a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h
+++ b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h
@@ -14,6 +14,7 @@
 #include "chrome/browser/safe_browsing/certificate_reporting_service.h"
 #include "content/public/test/browser_task_environment.h"
 #include "content/public/test/test_browser_thread.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 
@@ -157,7 +158,8 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
   std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override;
 
   ReportSendingResult expected_report_result_;
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
index 20b9f10b..ac923fe 100644
--- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_unittest.cc
@@ -37,6 +37,8 @@
 #include "content/public/test/navigation_simulator.h"
 #include "content/public/test/web_contents_tester.h"
 #include "extensions/buildflags/buildflags.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "net/url_request/url_request_test_util.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -98,12 +100,13 @@
     client->OnComplete(status);
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
-    bindings_.AddBinding(this, std::move(request));
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
+    receivers_.Add(this, std::move(receiver));
   }
 
  private:
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   DISALLOW_COPY_AND_ASSIGN(CacheMissNetworkURLLoaderFactory);
 };
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_browsertest.cc b/chrome/browser/sharing/click_to_call/click_to_call_browsertest.cc
index 66f59cb..60e68e7 100644
--- a/chrome/browser/sharing/click_to_call/click_to_call_browsertest.cc
+++ b/chrome/browser/sharing/click_to_call/click_to_call_browsertest.cc
@@ -113,7 +113,9 @@
         kClickToCallContextMenuForSelectedText},
        {});
   SetUpDevices(/*count=*/1);
-  GetSyncService(0)->GetUserSettings()->SetSyncRequested(false);
+  // Disable syncing preferences which is necessary for Sharing.
+  GetSyncService(0)->GetUserSettings()->SetSelectedTypes(false, {});
+  AwaitQuiescence();
 
   std::unique_ptr<TestRenderViewContextMenu> menu =
       InitRightClickMenu(GURL(kTelUrl), base::ASCIIToUTF16("Google"),
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer.cc b/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer.cc
index 233300c..279e913 100644
--- a/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer.cc
+++ b/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer.cc
@@ -57,29 +57,26 @@
 
   phone_number_ = phone_number;
   entry_point_ = entry_point;
-
-  controller_->UpdateDevices();
-  const std::vector<std::unique_ptr<syncer::DeviceInfo>>& devices =
-      controller_->devices();
+  devices_ = controller_->GetDevices();
   LogSharingDevicesToShow(controller_->GetFeatureMetricsPrefix(),
-                          kSharingUiContextMenu, devices.size());
-  if (devices.empty())
+                          kSharingUiContextMenu, devices_.size());
+  if (devices_.empty())
     return;
 
   proxy_->AddSeparator();
-  if (devices.size() == 1) {
+  if (devices_.size() == 1) {
 #if defined(OS_MACOSX)
     proxy_->AddMenuItem(
         IDC_CONTENT_CONTEXT_SHARING_CLICK_TO_CALL_SINGLE_DEVICE,
         l10n_util::GetStringFUTF16(
             IDS_CONTENT_CONTEXT_SHARING_CLICK_TO_CALL_SINGLE_DEVICE,
-            base::UTF8ToUTF16(devices[0]->client_name())));
+            base::UTF8ToUTF16(devices_[0]->client_name())));
 #else
     proxy_->AddMenuItemWithIcon(
         IDC_CONTENT_CONTEXT_SHARING_CLICK_TO_CALL_SINGLE_DEVICE,
         l10n_util::GetStringFUTF16(
             IDS_CONTENT_CONTEXT_SHARING_CLICK_TO_CALL_SINGLE_DEVICE,
-            base::UTF8ToUTF16(devices[0]->client_name())),
+            base::UTF8ToUTF16(devices_[0]->client_name())),
         vector_icons::kCallIcon);
 #endif
   } else {
@@ -104,7 +101,7 @@
   sub_menu_model_ = std::make_unique<ui::SimpleMenuModel>(&sub_menu_delegate_);
 
   int command_id = kSubMenuFirstDeviceCommandId;
-  for (const auto& device : controller_->devices()) {
+  for (const auto& device : devices_) {
     if (command_id > kSubMenuLastDeviceCommandId)
       break;
     sub_menu_model_->AddItem(command_id++,
@@ -113,7 +110,7 @@
 }
 
 bool ClickToCallContextMenuObserver::IsCommandIdSupported(int command_id) {
-  size_t device_count = controller_->devices().size();
+  size_t device_count = devices_.size();
   if (device_count == 0)
     return false;
 
@@ -133,7 +130,7 @@
 
 void ClickToCallContextMenuObserver::ExecuteCommand(int command_id) {
   if (command_id == IDC_CONTENT_CONTEXT_SHARING_CLICK_TO_CALL_SINGLE_DEVICE) {
-    DCHECK(controller_->devices().size() == 1);
+    DCHECK(devices_.size() == 1);
     SendClickToCallMessage(0);
   }
 }
@@ -141,14 +138,12 @@
 void ClickToCallContextMenuObserver::SendClickToCallMessage(
     int chosen_device_index) {
   DCHECK(entry_point_);
-  const std::vector<std::unique_ptr<syncer::DeviceInfo>>& devices =
-      controller_->devices();
-  if (chosen_device_index >= static_cast<int>(devices.size()))
+  if (chosen_device_index >= static_cast<int>(devices_.size()))
     return;
 
   LogSharingSelectedDeviceIndex(controller_->GetFeatureMetricsPrefix(),
                                 kSharingUiContextMenu, chosen_device_index);
 
-  controller_->OnDeviceSelected(phone_number_, *devices[chosen_device_index],
+  controller_->OnDeviceSelected(phone_number_, *devices_[chosen_device_index],
                                 *entry_point_);
 }
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer.h b/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer.h
index ccce41d..bab6ee5 100644
--- a/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer.h
+++ b/chrome/browser/sharing/click_to_call/click_to_call_context_menu_observer.h
@@ -16,6 +16,10 @@
 #include "components/renderer_context_menu/render_view_context_menu_observer.h"
 #include "ui/base/models/simple_menu_model.h"
 
+namespace syncer {
+class DeviceInfo;
+}  // namespace syncer
+
 class RenderViewContextMenuProxy;
 
 class ClickToCallUiController;
@@ -63,6 +67,8 @@
 
   ClickToCallUiController* controller_ = nullptr;
 
+  std::vector<std::unique_ptr<syncer::DeviceInfo>> devices_;
+
   SubMenuDelegate sub_menu_delegate_{this};
 
   std::string phone_number_;
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.cc b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.cc
index b9faf9c..3a9fb771 100644
--- a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.cc
+++ b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.cc
@@ -20,7 +20,6 @@
 #include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/paint_vector_icon.h"
-#include "ui/native_theme/native_theme.h"
 #include "ui/strings/grit/ui_strings.h"
 
 using SharingMessage = chrome_browser_sharing::SharingMessage;
@@ -67,9 +66,19 @@
   SharingUiController::OnDialogClosed(dialog);
 }
 
-base::string16 ClickToCallUiController::GetTitle() {
-  return l10n_util::GetStringUTF16(
-      IDS_BROWSER_SHARING_CLICK_TO_CALL_DIALOG_TITLE_LABEL);
+base::string16 ClickToCallUiController::GetTitle(
+    SharingDialogType dialog_type) {
+  switch (dialog_type) {
+    case SharingDialogType::kErrorDialog:
+      return SharingUiController::GetTitle(dialog_type);
+    case SharingDialogType::kEducationalDialog:
+      return l10n_util::GetStringUTF16(
+          IDS_BROWSER_SHARING_CLICK_TO_CALL_DIALOG_TITLE_NO_DEVICES);
+    case SharingDialogType::kDialogWithoutDevicesWithApp:
+    case SharingDialogType::kDialogWithDevicesMaybeApps:
+      return l10n_util::GetStringUTF16(
+          IDS_BROWSER_SHARING_CLICK_TO_CALL_DIALOG_TITLE_LABEL);
+  }
 }
 
 PageActionIconType ClickToCallUiController::GetIconType() {
@@ -151,42 +160,27 @@
   return SharingFeatureName::kClickToCall;
 }
 
-base::string16 ClickToCallUiController::GetEducationWindowTitleText() const {
-  return l10n_util::GetStringUTF16(
-      IDS_BROWSER_SHARING_CLICK_TO_CALL_DIALOG_TITLE_NO_DEVICES);
-}
-
 void ClickToCallUiController::OnHelpTextClicked(SharingDialogType dialog_type) {
   LogClickToCallHelpTextClicked(dialog_type);
   SharingUiController::OnHelpTextClicked(dialog_type);
 }
 
-int ClickToCallUiController::GetHeaderImageId() const {
+SharingDialogData ClickToCallUiController::CreateDialogData(
+    SharingDialogType dialog_type) {
+  SharingDialogData data = SharingUiController::CreateDialogData(dialog_type);
+
   // Do not add the header image for error dialogs.
-  if (HasSendFailed())
-    return 0;
+  if (dialog_type != SharingDialogType::kErrorDialog) {
+    data.header_image_light = IDR_CLICK_TO_CALL_ILLUSTRATION_LIGHT;
+    data.header_image_dark = IDR_CLICK_TO_CALL_ILLUSTRATION_DARK;
+  }
 
-  const ui::NativeTheme* native_theme =
-      ui::NativeTheme::GetInstanceForNativeUi();
-  bool is_dark = native_theme && native_theme->ShouldUseDarkColors();
+  data.help_text_id =
+      IDS_BROWSER_SHARING_CLICK_TO_CALL_DIALOG_HELP_TEXT_NO_DEVICES;
+  data.help_link_text_id =
+      IDS_BROWSER_SHARING_CLICK_TO_CALL_DIALOG_TROUBLESHOOT_LINK;
 
-  return is_dark ? IDR_CLICK_TO_CALL_ILLUSTRATION_DARK
-                 : IDR_CLICK_TO_CALL_ILLUSTRATION_LIGHT;
-}
-
-std::unique_ptr<views::StyledLabel> ClickToCallUiController::GetHelpTextLabel(
-    views::StyledLabelListener* listener) {
-  const base::string16 link = l10n_util::GetStringUTF16(
-      IDS_BROWSER_SHARING_CLICK_TO_CALL_DIALOG_TROUBLESHOOT_LINK);
-  size_t offset;
-  const base::string16 text = l10n_util::GetStringFUTF16(
-      IDS_BROWSER_SHARING_CLICK_TO_CALL_DIALOG_HELP_TEXT_NO_DEVICES, link,
-      &offset);
-  auto label = std::make_unique<views::StyledLabel>(text, listener);
-  views::StyledLabel::RangeStyleInfo link_style =
-      views::StyledLabel::RangeStyleInfo::CreateForLink();
-  label->AddStyleRange(gfx::Range(offset, offset + link.length()), link_style);
-  return label;
+  return data;
 }
 
 WEB_CONTENTS_USER_DATA_KEY_IMPL(ClickToCallUiController)
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.h b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.h
index dfe71666..646ae25 100644
--- a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.h
+++ b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller.h
@@ -39,7 +39,7 @@
                         SharingClickToCallEntryPoint entry_point);
 
   // Overridden from SharingUiController:
-  base::string16 GetTitle() override;
+  base::string16 GetTitle(SharingDialogType dialog_type) override;
   PageActionIconType GetIconType() override;
   sync_pb::SharingSpecificFields::EnabledFeatures GetRequiredFeature() override;
   void OnDeviceChosen(const syncer::DeviceInfo& device) override;
@@ -49,11 +49,7 @@
   const gfx::VectorIcon& GetVectorIcon() const override;
   base::string16 GetTextForTooltipAndAccessibleName() const override;
   SharingFeatureName GetFeatureMetricsPrefix() const override;
-  base::string16 GetEducationWindowTitleText() const override;
   void OnHelpTextClicked(SharingDialogType dialog_type) override;
-  int GetHeaderImageId() const override;
-  std::unique_ptr<views::StyledLabel> GetHelpTextLabel(
-      views::StyledLabelListener* listener) override;
   void OnDialogShown(bool has_devices, bool has_apps) override;
 
  protected:
@@ -61,6 +57,7 @@
 
   // Overridden from SharingUiController:
   void DoUpdateApps(UpdateAppsCallback callback) override;
+  SharingDialogData CreateDialogData(SharingDialogType dialog_type) override;
 
  private:
   friend class content::WebContentsUserData<ClickToCallUiController>;
diff --git a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller_unittest.cc b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller_unittest.cc
index cc26d04..15758415 100644
--- a/chrome/browser/sharing/click_to_call/click_to_call_ui_controller_unittest.cc
+++ b/chrome/browser/sharing/click_to_call/click_to_call_ui_controller_unittest.cc
@@ -142,5 +142,5 @@
 TEST_F(ClickToCallUiControllerTest, GetSyncedDevices) {
   EXPECT_CALL(*service(), GetDeviceCandidates(testing::Eq(
                               sync_pb::SharingSpecificFields::CLICK_TO_CALL)));
-  controller_->UpdateAndShowDialog();
+  controller_->GetDevices();
 }
diff --git a/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer.cc b/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer.cc
index dbe8c64..658a51f 100644
--- a/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer.cc
+++ b/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer.cc
@@ -53,29 +53,27 @@
 void SharedClipboardContextMenuObserver::InitMenu(
     const content::ContextMenuParams& params) {
   text_ = params.selection_text;
-  controller_->UpdateDevices();
-  const std::vector<std::unique_ptr<syncer::DeviceInfo>>& devices =
-      controller_->devices();
+  devices_ = controller_->GetDevices();
   LogSharingDevicesToShow(controller_->GetFeatureMetricsPrefix(),
-                          nullptr /* No suffix */, devices.size());
+                          nullptr /* No suffix */, devices_.size());
 
-  if (devices.empty())
+  if (devices_.empty())
     return;
 
   proxy_->AddSeparator();
-  if (devices.size() == 1) {
+  if (devices_.size() == 1) {
 #if defined(OS_MACOSX)
     proxy_->AddMenuItem(
         IDC_CONTENT_CONTEXT_SHARING_SHARED_CLIPBOARD_SINGLE_DEVICE,
         l10n_util::GetStringFUTF16(
             IDS_CONTENT_CONTEXT_SHARING_SHARED_CLIPBOARD_SINGLE_DEVICE,
-            base::UTF8ToUTF16(devices[0]->client_name())));
+            base::UTF8ToUTF16(devices_[0]->client_name())));
 #else
     proxy_->AddMenuItemWithIcon(
         IDC_CONTENT_CONTEXT_SHARING_SHARED_CLIPBOARD_SINGLE_DEVICE,
         l10n_util::GetStringFUTF16(
             IDS_CONTENT_CONTEXT_SHARING_SHARED_CLIPBOARD_SINGLE_DEVICE,
-            base::UTF8ToUTF16(devices[0]->client_name())),
+            base::UTF8ToUTF16(devices_[0]->client_name())),
         controller_->GetVectorIcon());
 #endif
   } else {
@@ -99,7 +97,7 @@
   sub_menu_model_ = std::make_unique<ui::SimpleMenuModel>(&sub_menu_delegate_);
 
   int command_id = kSubMenuFirstDeviceCommandId;
-  for (const auto& device : controller_->devices()) {
+  for (const auto& device : devices_) {
     if (command_id > kSubMenuLastDeviceCommandId)
       break;
     sub_menu_model_->AddItem(command_id++,
@@ -108,7 +106,7 @@
 }
 
 bool SharedClipboardContextMenuObserver::IsCommandIdSupported(int command_id) {
-  size_t device_count = controller_->devices().size();
+  size_t device_count = devices_.size();
   if (device_count == 0)
     return false;
 
@@ -129,20 +127,18 @@
 void SharedClipboardContextMenuObserver::ExecuteCommand(int command_id) {
   if (command_id ==
       IDC_CONTENT_CONTEXT_SHARING_SHARED_CLIPBOARD_SINGLE_DEVICE) {
-    DCHECK(controller_->devices().size() == 1);
+    DCHECK(devices_.size() == 1);
     SendSharedClipboardMessage(0);
   }
 }
 
 void SharedClipboardContextMenuObserver::SendSharedClipboardMessage(
     int chosen_device_index) {
-  const std::vector<std::unique_ptr<syncer::DeviceInfo>>& devices =
-      controller_->devices();
-  if (chosen_device_index >= static_cast<int>(devices.size()))
+  if (chosen_device_index >= static_cast<int>(devices_.size()))
     return;
   LogSharingSelectedDeviceIndex(controller_->GetFeatureMetricsPrefix(),
                                 nullptr /* No suffix */, chosen_device_index);
 
-  controller_->OnDeviceSelected(text_, *devices[chosen_device_index]);
+  controller_->OnDeviceSelected(text_, *devices_[chosen_device_index]);
   LogSharedClipboardSelectedTextSize(text_.size());
 }
diff --git a/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer.h b/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer.h
index 4f7ede2..a98ffea 100644
--- a/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer.h
+++ b/chrome/browser/sharing/shared_clipboard/shared_clipboard_context_menu_observer.h
@@ -15,6 +15,10 @@
 #include "components/renderer_context_menu/render_view_context_menu_observer.h"
 #include "ui/base/models/simple_menu_model.h"
 
+namespace syncer {
+class DeviceInfo;
+}  // namespace syncer
+
 class RenderViewContextMenuProxy;
 class SharedClipboardUiController;
 
@@ -61,6 +65,8 @@
 
   SharedClipboardUiController* controller_ = nullptr;
 
+  std::vector<std::unique_ptr<syncer::DeviceInfo>> devices_;
+
   SubMenuDelegate sub_menu_delegate_{this};
 
   base::string16 text_;
diff --git a/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller.cc b/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller.cc
index 441ea82..4ca432f 100644
--- a/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller.cc
+++ b/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller.cc
@@ -37,9 +37,17 @@
   OnDeviceChosen(device);
 }
 
-base::string16 SharedClipboardUiController::GetTitle() {
-  // There is no left click dialog - so no title
-  return base::string16();
+base::string16 SharedClipboardUiController::GetTitle(
+    SharingDialogType dialog_type) {
+  // Shared clipboard only shows error dialogs.
+  DCHECK_EQ(SharingDialogType::kErrorDialog, dialog_type);
+
+  if (send_result() == SharingSendMessageResult::kPayloadTooLarge) {
+    return l10n_util::GetStringUTF16(
+        IDS_BROWSER_SHARING_SHARED_CLIPBOARD_ERROR_DIALOG_TITLE_PAYLOAD_TOO_LARGE);
+  }
+
+  return SharingUiController::GetTitle(dialog_type);
 }
 
 PageActionIconType SharedClipboardUiController::GetIconType() {
@@ -73,15 +81,6 @@
   return l10n_util::GetStringUTF16(IDS_BROWSER_SHARING_CONTENT_TYPE_TEXT);
 }
 
-base::string16 SharedClipboardUiController::GetErrorDialogTitle() const {
-  if (send_result() == SharingSendMessageResult::kPayloadTooLarge) {
-    return l10n_util::GetStringUTF16(
-        IDS_BROWSER_SHARING_SHARED_CLIPBOARD_ERROR_DIALOG_TITLE_PAYLOAD_TOO_LARGE);
-  }
-
-  return SharingUiController::GetErrorDialogTitle();
-}
-
 base::string16 SharedClipboardUiController::GetErrorDialogText() const {
   if (send_result() == SharingSendMessageResult::kPayloadTooLarge) {
     return l10n_util::GetStringUTF16(
@@ -106,17 +105,4 @@
   return SharingFeatureName::kSharedClipboard;
 }
 
-base::string16 SharedClipboardUiController::GetEducationWindowTitleText()
-    const {
-  // No educational window text for shared clipboard.
-  return base::string16();
-}
-
-// There is no Help Text for Shared Clipboard feature.
-std::unique_ptr<views::StyledLabel>
-SharedClipboardUiController::GetHelpTextLabel(
-    views::StyledLabelListener* listener) {
-  return nullptr;
-}
-
 WEB_CONTENTS_USER_DATA_KEY_IMPL(SharedClipboardUiController)
diff --git a/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller.h b/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller.h
index 951900c0..b971c1f 100644
--- a/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller.h
+++ b/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller.h
@@ -32,20 +32,16 @@
                         const syncer::DeviceInfo& device);
 
   // Overridden from SharingUiController:
-  base::string16 GetTitle() override;
+  base::string16 GetTitle(SharingDialogType dialog_type) override;
   PageActionIconType GetIconType() override;
   sync_pb::SharingSpecificFields::EnabledFeatures GetRequiredFeature() override;
   void OnDeviceChosen(const syncer::DeviceInfo& device) override;
   void OnAppChosen(const SharingApp& app) override;
   base::string16 GetContentType() const override;
-  base::string16 GetErrorDialogTitle() const override;
   base::string16 GetErrorDialogText() const override;
   const gfx::VectorIcon& GetVectorIcon() const override;
   base::string16 GetTextForTooltipAndAccessibleName() const override;
   SharingFeatureName GetFeatureMetricsPrefix() const override;
-  base::string16 GetEducationWindowTitleText() const override;
-  std::unique_ptr<views::StyledLabel> GetHelpTextLabel(
-      views::StyledLabelListener* listener) override;
 
  protected:
   explicit SharedClipboardUiController(content::WebContents* web_contents);
diff --git a/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller_unittest.cc b/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller_unittest.cc
index c754afd..f7cc196 100644
--- a/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller_unittest.cc
+++ b/chrome/browser/sharing/shared_clipboard/shared_clipboard_ui_controller_unittest.cc
@@ -147,5 +147,5 @@
   EXPECT_CALL(*service(),
               GetDeviceCandidates(testing::Eq(
                   sync_pb::SharingSpecificFields::SHARED_CLIPBOARD)));
-  controller_->UpdateAndShowDialog();
+  controller_->GetDevices();
 }
diff --git a/chrome/browser/sharing/sharing_dialog_data.cc b/chrome/browser/sharing/sharing_dialog_data.cc
new file mode 100644
index 0000000..4fa4f67
--- /dev/null
+++ b/chrome/browser/sharing/sharing_dialog_data.cc
@@ -0,0 +1,11 @@
+// Copyright 2019 The Chromium 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 "chrome/browser/sharing/sharing_dialog_data.h"
+
+SharingDialogData::SharingDialogData() = default;
+
+SharingDialogData::~SharingDialogData() = default;
+
+SharingDialogData::SharingDialogData(SharingDialogData&& other) = default;
diff --git a/chrome/browser/sharing/sharing_dialog_data.h b/chrome/browser/sharing/sharing_dialog_data.h
new file mode 100644
index 0000000..1ad7a40
--- /dev/null
+++ b/chrome/browser/sharing/sharing_dialog_data.h
@@ -0,0 +1,49 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_SHARING_SHARING_DIALOG_DATA_H_
+#define CHROME_BROWSER_SHARING_SHARING_DIALOG_DATA_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "base/strings/string16.h"
+#include "chrome/browser/sharing/sharing_app.h"
+#include "chrome/browser/sharing/sharing_metrics.h"
+#include "components/sync_device_info/device_info.h"
+
+class SharingDialog;
+
+// All data required to display a SharingDialog.
+struct SharingDialogData {
+ public:
+  SharingDialogData();
+  ~SharingDialogData();
+  SharingDialogData(SharingDialogData&& other);
+
+  SharingDialogType type = SharingDialogType::kErrorDialog;
+  SharingFeatureName prefix = SharingFeatureName::kUnknown;
+
+  std::vector<std::unique_ptr<syncer::DeviceInfo>> devices;
+  std::vector<SharingApp> apps;
+
+  base::string16 title;
+  base::string16 error_text;
+  int help_text_id = 0;
+  int help_link_text_id = 0;
+  int header_image_light = 0;
+  int header_image_dark = 0;
+
+  base::OnceCallback<void(SharingDialogType)> help_callback;
+  base::OnceCallback<void(const syncer::DeviceInfo&)> device_callback;
+  base::OnceCallback<void(const SharingApp&)> app_callback;
+  base::OnceCallback<void(SharingDialog*)> close_callback;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SharingDialogData);
+};
+
+#endif  // CHROME_BROWSER_SHARING_SHARING_DIALOG_DATA_H_
diff --git a/chrome/browser/sharing/sharing_service.cc b/chrome/browser/sharing/sharing_service.cc
index 017c6172..0513526 100644
--- a/chrome/browser/sharing/sharing_service.cc
+++ b/chrome/browser/sharing/sharing_service.cc
@@ -447,16 +447,12 @@
 }
 
 bool SharingService::IsSyncDisabled() const {
-  // TODO(alexchau): Better way to make
-  // ClickToCallBrowserTest.ContextMenu_DevicesAvailable_SyncTurnedOff pass
-  // without unnecessarily checking SyncService::GetDisableReasons.
   return sync_service_ && (sync_service_->GetTransportState() ==
                                syncer::SyncService::TransportState::DISABLED ||
                            (sync_service_->GetTransportState() ==
                                 syncer::SyncService::TransportState::ACTIVE &&
                             !sync_service_->GetActiveDataTypes().HasAll(
-                                GetRequiredSyncDataTypes())) ||
-                           sync_service_->GetDisableReasons());
+                                GetRequiredSyncDataTypes())));
 }
 
 syncer::ModelTypeSet SharingService::GetRequiredSyncDataTypes() const {
diff --git a/chrome/browser/sharing/sharing_ui_controller.cc b/chrome/browser/sharing/sharing_ui_controller.cc
index d6fd440..c93f296e 100644
--- a/chrome/browser/sharing/sharing_ui_controller.cc
+++ b/chrome/browser/sharing/sharing_ui_controller.cc
@@ -8,6 +8,7 @@
 
 #include "chrome/browser/sharing/sharing_constants.h"
 #include "chrome/browser/sharing/sharing_dialog.h"
+#include "chrome/browser/sharing/sharing_dialog_data.h"
 #include "chrome/browser/sharing/sharing_service_factory.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window.h"
@@ -31,6 +32,14 @@
   return browser ? browser->tab_strip_model()->GetActiveWebContents() : nullptr;
 }
 
+SharingDialogType GetSharingDialogType(bool has_devices, bool has_apps) {
+  if (has_devices)
+    return SharingDialogType::kDialogWithDevicesMaybeApps;
+  if (has_apps)
+    return SharingDialogType::kDialogWithoutDevicesWithApp;
+  return SharingDialogType::kEducationalDialog;
+}
+
 }  // namespace
 
 SharingUiController::SharingUiController(content::WebContents* web_contents)
@@ -55,15 +64,37 @@
   DCHECK(!dialog_);
 }
 
-void SharingUiController::ShowNewDialog() {
+SharingDialogData SharingUiController::CreateDialogData(
+    SharingDialogType dialog_type) {
+  SharingDialogData data;
+
+  data.type = dialog_type;
+  data.prefix = GetFeatureMetricsPrefix();
+  data.title = GetTitle(data.type);
+  data.error_text = GetErrorDialogText();
+
+  auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
+  data.help_callback =
+      base::BindOnce(&SharingUiController::OnHelpTextClicked, weak_ptr);
+  data.device_callback =
+      base::BindOnce(&SharingUiController::OnDeviceChosen, weak_ptr);
+  data.app_callback =
+      base::BindOnce(&SharingUiController::OnAppChosen, weak_ptr);
+  data.close_callback =
+      base::BindOnce(&SharingUiController::OnDialogClosed, weak_ptr);
+  return data;
+}
+
+void SharingUiController::ShowNewDialog(SharingDialogData dialog_data) {
   CloseDialog();
   BrowserWindow* window = GetWindowFromWebContents(web_contents_);
   if (!window)
     return;
-
-  dialog_ = window->ShowSharingDialog(web_contents(), this);
+  bool has_devices = !dialog_data.devices.empty();
+  bool has_apps = !dialog_data.apps.empty();
+  dialog_ = window->ShowSharingDialog(web_contents(), std::move(dialog_data));
   UpdateIcon();
-  OnDialogShown(!devices_.empty(), !apps_.empty());
+  OnDialogShown(has_devices, has_apps);
 }
 
 void SharingUiController::UpdateIcon() {
@@ -85,7 +116,7 @@
 
 void SharingUiController::MaybeShowErrorDialog() {
   if (HasSendFailed() && web_contents_ == GetCurrentWebContents(web_contents_))
-    ShowNewDialog();
+    ShowNewDialog(CreateDialogData(SharingDialogType::kErrorDialog));
 }
 
 void SharingUiController::SendMessageToDevice(
@@ -127,15 +158,18 @@
                               weak_ptr_factory_.GetWeakPtr(), last_dialog_id_));
 }
 
-void SharingUiController::UpdateDevices() {
-  devices_ = sharing_service_->GetDeviceCandidates(GetRequiredFeature());
+std::vector<std::unique_ptr<syncer::DeviceInfo>>
+SharingUiController::GetDevices() {
+  return sharing_service_->GetDeviceCandidates(GetRequiredFeature());
 }
 
 base::string16 SharingUiController::GetTargetDeviceName() const {
   return base::UTF8ToUTF16(target_device_name_);
 }
 
-base::string16 SharingUiController::GetErrorDialogTitle() const {
+base::string16 SharingUiController::GetTitle(SharingDialogType dialog_type) {
+  // We only handle error messages generically.
+  DCHECK_EQ(SharingDialogType::kErrorDialog, dialog_type);
   switch (send_result()) {
     case SharingSendMessageResult::kDeviceNotFound:
     case SharingSendMessageResult::kNetworkError:
@@ -173,8 +207,7 @@
           GetTargetDeviceName());
 
     case SharingSendMessageResult::kSuccessful:
-      NOTREACHED();
-      FALLTHROUGH;
+      return base::string16();
 
     case SharingSendMessageResult::kPayloadTooLarge:
     case SharingSendMessageResult::kInternalError:
@@ -183,19 +216,19 @@
   }
 }
 
-int SharingUiController::GetHeaderImageId() const {
-  return 0;
-}
-
 void SharingUiController::OnAppsReceived(int dialog_id,
                                          std::vector<SharingApp> apps) {
   if (dialog_id != last_dialog_id_)
     return;
 
-  apps_ = std::move(apps);
-  UpdateDevices();
+  auto devices = GetDevices();
 
-  ShowNewDialog();
+  SharingDialogData dialog_data =
+      CreateDialogData(GetSharingDialogType(!devices.empty(), !apps.empty()));
+  dialog_data.devices = std::move(devices);
+  dialog_data.apps = std::move(apps);
+
+  ShowNewDialog(std::move(dialog_data));
 }
 
 bool SharingUiController::HasSendFailed() const {
diff --git a/chrome/browser/sharing/sharing_ui_controller.h b/chrome/browser/sharing/sharing_ui_controller.h
index db660c2..c39c2a9e 100644
--- a/chrome/browser/sharing/sharing_ui_controller.h
+++ b/chrome/browser/sharing/sharing_ui_controller.h
@@ -16,6 +16,7 @@
 #include "chrome/browser/sharing/proto/sharing_message.pb.h"
 #include "chrome/browser/sharing/sharing_app.h"
 #include "chrome/browser/sharing/sharing_constants.h"
+#include "chrome/browser/sharing/sharing_dialog_data.h"
 #include "chrome/browser/sharing/sharing_metrics.h"
 #include "chrome/browser/sharing/sharing_service.h"
 #include "chrome/browser/ui/page_action/page_action_icon_type.h"
@@ -44,7 +45,7 @@
   virtual ~SharingUiController();
 
   // Title of the dialog.
-  virtual base::string16 GetTitle() = 0;
+  virtual base::string16 GetTitle(SharingDialogType dialog_type);
   // Called when user chooses a synced device to complete the task.
   virtual void OnDeviceChosen(const syncer::DeviceInfo& device) = 0;
   // Called when user chooses a local app to complete the task.
@@ -56,36 +57,26 @@
   virtual base::string16 GetTextForTooltipAndAccessibleName() const = 0;
   // Get the name of the feature to be used as a prefix for the metric name.
   virtual SharingFeatureName GetFeatureMetricsPrefix() const = 0;
-  virtual base::string16 GetEducationWindowTitleText() const = 0;
 
   // Called by the SharingDialog when it is being closed.
   virtual void OnDialogClosed(SharingDialog* dialog);
 
-  // Get the help text label for the help dialog.
-  virtual std::unique_ptr<views::StyledLabel> GetHelpTextLabel(
-      views::StyledLabelListener* listener) = 0;
-
   // Closes the current dialog and resets all state.
   void ClearLastDialog();
 
+  // Gets the current list of apps and devices and shows a new dialog.
   void UpdateAndShowDialog();
 
-  void UpdateDevices();
+  // Gets the current list of devices that support the required feature.
+  std::vector<std::unique_ptr<syncer::DeviceInfo>> GetDevices();
 
-  // Function used by GetErrorDialogTitle() and GetErrorDialogText().
+  // Describes the content type of shared data.
   virtual base::string16 GetContentType() const = 0;
 
-  // Returns the message to be shown as title in error dialog based on
-  // |send_result_|.
-  virtual base::string16 GetErrorDialogTitle() const;
-
   // Returns the message to be shown in the body of error dialog based on
   // |send_result_|.
   virtual base::string16 GetErrorDialogText() const;
 
-  // Returns the image id shown as a header in the dialog.
-  virtual int GetHeaderImageId() const;
-
   // Returns the currently open SharingDialog or nullptr if there is no
   // dialog open.
   SharingDialog* dialog() const { return dialog_; }
@@ -98,18 +89,7 @@
   bool HasSendFailed() const;
 
   content::WebContents* web_contents() const { return web_contents_; }
-  const std::vector<SharingApp>& apps() const { return apps_; }
-  const std::vector<std::unique_ptr<syncer::DeviceInfo>>& devices() const {
-    return devices_;
-  }
 
-  void set_apps_for_testing(std::vector<SharingApp> apps) {
-    apps_ = std::move(apps);
-  }
-  void set_devices_for_testing(
-      std::vector<std::unique_ptr<syncer::DeviceInfo>> devices) {
-    devices_ = std::move(devices);
-  }
   void MaybeShowErrorDialog();
 
   // Called by the SharingDialogView when the help text got clicked.
@@ -129,13 +109,16 @@
       const syncer::DeviceInfo& device,
       chrome_browser_sharing::SharingMessage sharing_message);
 
+  // Prepares a new dialog data.
+  virtual SharingDialogData CreateDialogData(SharingDialogType dialog_type);
+
  private:
   // Updates the omnibox icon if available.
   void UpdateIcon();
   // Closes the current dialog if there is one.
   void CloseDialog();
   // Shows a new SharingDialog and closes the old one.
-  void ShowNewDialog();
+  void ShowNewDialog(SharingDialogData dialog_data);
 
   base::string16 GetTargetDeviceName() const;
 
@@ -153,10 +136,6 @@
   SharingSendMessageResult send_result_ = SharingSendMessageResult::kSuccessful;
   std::string target_device_name_;
 
-  // Currently used apps and devices since the last call to UpdateAndShowDialog.
-  std::vector<SharingApp> apps_;
-  std::vector<std::unique_ptr<syncer::DeviceInfo>> devices_;
-
   // ID of the last shown dialog used to ignore events from old dialogs.
   int last_dialog_id_ = 0;
 
diff --git a/chrome/browser/signin/chrome_signin_helper.cc b/chrome/browser/signin/chrome_signin_helper.cc
index c276278..1a35bf4 100644
--- a/chrome/browser/signin/chrome_signin_helper.cc
+++ b/chrome/browser/signin/chrome_signin_helper.cc
@@ -192,24 +192,22 @@
     return;
 
   // The only allowed operations are:
-  // - Going Incognito.
-  // - Displaying the Account Manager for managing accounts.
-  // - Displaying a reauthentication window: Enterprise GSuite Accounts could
-  // have been forced through an online in-browser sign-in for sensitive
-  // webpages, thereby decreasing their session validity. After their session
-  // expires, they will receive a "Mirror" re-authentication request for all
-  // Google web properties.
+  // 1. Going Incognito.
+  // 2. Displaying a reauthentication window: Enterprise GSuite Accounts could
+  //    have been forced through an online in-browser sign-in for sensitive
+  //    webpages, thereby decreasing their session validity. After their session
+  //    expires, they will receive a "Mirror" re-authentication request for all
+  //    Google web properties.
+  // 3. Displaying the Account Manager for managing accounts.
 
+  // 1. Going incognito.
   if (service_type == GAIA_SERVICE_TYPE_INCOGNITO) {
     chrome::NewIncognitoWindow(profile);
     return;
   }
 
-  if (manage_accounts_params.email.empty()) {
-    // Display Account Manager for managing accounts.
-    chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(
-        profile, chrome::kAccountManagerSubPage);
-  } else {
+  // 2. Displaying a reauthentication window
+  if (!manage_accounts_params.email.empty()) {
     // Do not display the re-authentication dialog if this event was triggered
     // by supervision being enabled for an account.  In this situation, a
     // complete signout is required.
@@ -222,7 +220,12 @@
     // Display a re-authentication dialog.
     chromeos::InlineLoginHandlerDialogChromeOS::Show(
         manage_accounts_params.email);
+    return;
   }
+
+  // 3. Displaying the Account Manager for managing accounts.
+  chrome::SettingsWindowManager::GetInstance()->ShowOSSettings(
+      profile, chrome::kAccountManagerSubPage);
   return;
 
 #else   // !defined(OS_CHROMEOS)
diff --git a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc
index c7d2a5f6..b4a2f4c 100644
--- a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc
+++ b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.cc
@@ -19,6 +19,7 @@
 #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h"
 #include "extensions/buildflags/buildflags.h"
 #include "google_apis/gaia/gaia_auth_util.h"
+#include "mojo/public/cpp/bindings/binding.h"
 #include "net/base/net_errors.h"
 
 namespace signin {
@@ -36,7 +37,7 @@
   static void StartProxying(
       Profile* profile,
       content::WebContents::Getter web_contents_getter,
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       network::mojom::URLLoaderFactoryPtrInfo target_factory) {
     auto* self = static_cast<BrowserContextData*>(
         profile->GetUserData(kBrowserContextUserDataKey));
@@ -47,8 +48,8 @@
 
     auto delegate = std::make_unique<HeaderModificationDelegateImpl>(profile);
     auto proxy = std::make_unique<ProxyingURLLoaderFactory>(
-        std::move(delegate), std::move(web_contents_getter), std::move(request),
-        std::move(target_factory),
+        std::move(delegate), std::move(web_contents_getter),
+        std::move(receiver), std::move(target_factory),
         base::BindOnce(&BrowserContextData::RemoveProxy,
                        self->weak_factory_.GetWeakPtr()));
     self->proxies_.emplace(std::move(proxy));
@@ -395,10 +396,10 @@
 ProxyingURLLoaderFactory::ProxyingURLLoaderFactory(
     std::unique_ptr<HeaderModificationDelegate> delegate,
     content::WebContents::Getter web_contents_getter,
-    network::mojom::URLLoaderFactoryRequest loader_request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
     network::mojom::URLLoaderFactoryPtrInfo target_factory,
     DisconnectCallback on_disconnect) {
-  DCHECK(proxy_bindings_.empty());
+  DCHECK(proxy_receivers_.empty());
   DCHECK(!target_factory_.is_bound());
   DCHECK(!delegate_);
   DCHECK(!web_contents_getter_);
@@ -412,8 +413,8 @@
   target_factory_.set_connection_error_handler(base::BindOnce(
       &ProxyingURLLoaderFactory::OnTargetFactoryError, base::Unretained(this)));
 
-  proxy_bindings_.AddBinding(this, std::move(loader_request));
-  proxy_bindings_.set_connection_error_handler(base::BindRepeating(
+  proxy_receivers_.Add(this, std::move(loader_receiver));
+  proxy_receivers_.set_disconnect_handler(base::BindRepeating(
       &ProxyingURLLoaderFactory::OnProxyBindingError, base::Unretained(this)));
 }
 
@@ -486,20 +487,20 @@
 }
 
 void ProxyingURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest loader_request) {
-  proxy_bindings_.AddBinding(this, std::move(loader_request));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver) {
+  proxy_receivers_.Add(this, std::move(loader_receiver));
 }
 
 void ProxyingURLLoaderFactory::OnTargetFactoryError() {
   // Stop calls to CreateLoaderAndStart() when |target_factory_| is invalid.
   target_factory_.reset();
-  proxy_bindings_.CloseAllBindings();
+  proxy_receivers_.Clear();
 
   MaybeDestroySelf();
 }
 
 void ProxyingURLLoaderFactory::OnProxyBindingError() {
-  if (proxy_bindings_.empty())
+  if (proxy_receivers_.empty())
     target_factory_.reset();
 
   MaybeDestroySelf();
diff --git a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.h b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.h
index 8c67af0..f907bc8 100644
--- a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.h
+++ b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory.h
@@ -10,7 +10,8 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted_delete_on_sequence.h"
 #include "content/public/browser/web_contents.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
 #include <memory>
@@ -38,7 +39,7 @@
   ProxyingURLLoaderFactory(
       std::unique_ptr<HeaderModificationDelegate> delegate,
       content::WebContents::Getter web_contents_getter,
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       network::mojom::URLLoaderFactoryPtrInfo target_factory,
       DisconnectCallback on_disconnect);
   ~ProxyingURLLoaderFactory() override;
@@ -63,7 +64,8 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest loader_request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+                 loader_receiver) override;
 
  private:
   friend class base::DeleteHelper<ProxyingURLLoaderFactory>;
@@ -81,7 +83,7 @@
   std::unique_ptr<HeaderModificationDelegate> delegate_;
   content::WebContents::Getter web_contents_getter_;
 
-  mojo::BindingSet<network::mojom::URLLoaderFactory> proxy_bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> proxy_receivers_;
   std::set<std::unique_ptr<InProgressRequest>, base::UniquePtrComparator>
       requests_;
   network::mojom::URLLoaderFactoryPtr target_factory_;
diff --git a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory_unittest.cc b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory_unittest.cc
index b96f352..bc98f0b 100644
--- a/chrome/browser/signin/chrome_signin_proxying_url_loader_factory_unittest.cc
+++ b/chrome/browser/signin/chrome_signin_proxying_url_loader_factory_unittest.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/signin/chrome_signin_helper.h"
 #include "chrome/browser/signin/header_modification_delegate.h"
 #include "content/public/test/browser_task_environment.h"
+#include "mojo/public/cpp/bindings/binding.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "services/network/public/cpp/simple_url_loader.h"
 #include "services/network/test/test_url_loader_factory.h"
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc
index bcb1535b..f2956e5 100644
--- a/chrome/browser/sync/chrome_sync_client.cc
+++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -415,6 +415,17 @@
   return BookmarkUndoServiceFactory::GetForProfile(profile_);
 }
 
+syncer::TrustedVaultClient* ChromeSyncClient::GetTrustedVaultClient() {
+#if defined(OS_ANDROID)
+  // TODO(crbug.com/1012659): Instantiate a client for Android.
+  NOTIMPLEMENTED();
+#else
+  // TODO(crbug.com/1012660): Instantiate a generic client for other platforms.
+  NOTIMPLEMENTED();
+#endif  // defined(OS_ANDROID)
+  return nullptr;
+}
+
 invalidation::InvalidationService* ChromeSyncClient::GetInvalidationService() {
   invalidation::ProfileInvalidationProvider* provider =
       invalidation::ProfileInvalidationProviderFactory::GetForProfile(profile_);
diff --git a/chrome/browser/sync/chrome_sync_client.h b/chrome/browser/sync/chrome_sync_client.h
index a85b52e..f4cbc01 100644
--- a/chrome/browser/sync/chrome_sync_client.h
+++ b/chrome/browser/sync/chrome_sync_client.h
@@ -51,6 +51,7 @@
   base::Closure GetPasswordStateChangedCallback() override;
   syncer::DataTypeController::TypeVector CreateDataTypeControllers(
       syncer::SyncService* sync_service) override;
+  syncer::TrustedVaultClient* GetTrustedVaultClient() override;
   invalidation::InvalidationService* GetInvalidationService() override;
   BookmarkUndoService* GetBookmarkUndoService() override;
   scoped_refptr<syncer::ExtensionsActivity> GetExtensionsActivity() override;
diff --git a/chrome/browser/sync/profile_sync_service_factory_unittest.cc b/chrome/browser/sync/profile_sync_service_factory_unittest.cc
index 14955926..409272c 100644
--- a/chrome/browser/sync/profile_sync_service_factory_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_factory_unittest.cc
@@ -45,7 +45,7 @@
 
   // Returns the collection of default datatypes.
   std::vector<syncer::ModelType> DefaultDatatypes() {
-    static_assert(42 == syncer::ModelType::NUM_ENTRIES,
+    static_assert(39 == syncer::ModelType::NUM_ENTRIES,
                   "When adding a new type, you probably want to add it here as "
                   "well (assuming it is already enabled).");
 
diff --git a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
index 6044fcf..efd3bf7 100644
--- a/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_bookmarks_sync_test.cc
@@ -796,7 +796,7 @@
 #define MAYBE_ApplyRemoteCreationWithValidGUID ApplyRemoteCreationWithValidGUID
 #endif
 IN_PROC_BROWSER_TEST_P(SingleClientBookmarksSyncTest,
-                       ApplyRemoteCreationWithValidGUID) {
+                       MAYBE_ApplyRemoteCreationWithValidGUID) {
   // This test is only relevant for USS code path.
   if (!base::FeatureList::IsEnabled(switches::kSyncUSSBookmarks))
     return;
@@ -865,8 +865,15 @@
       GetBookmarkBarNode(kSingleProfileIndex)->children()[0].get()->guid());
 }
 
+#if defined(THREAD_SANITIZER) || defined(ADDRESS_SANITIZER)
+#define MAYBE_ApplyRemoteCreationWithoutValidGUIDOrOCII \
+  DISABLED_ApplyRemoteCreationWithoutValidGUIDOrOCII
+#else
+#define MAYBE_ApplyRemoteCreationWithoutValidGUIDOrOCII \
+  ApplyRemoteCreationWithoutValidGUIDOrOCII
+#endif
 IN_PROC_BROWSER_TEST_P(SingleClientBookmarksSyncTest,
-                       ApplyRemoteCreationWithoutValidGUIDOrOCII) {
+                       MAYBE_ApplyRemoteCreationWithoutValidGUIDOrOCII) {
   // This test is only relevant for USS code path.
   if (!base::FeatureList::IsEnabled(switches::kSyncUSSBookmarks))
     return;
diff --git a/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc b/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc
index 5f67c3a0..5f96aa4 100644
--- a/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc
@@ -152,7 +152,7 @@
                        ShouldDecryptWithKeystoreNigori) {
   const std::vector<std::string>& keystore_keys =
       GetFakeServer()->GetKeystoreKeys();
-  ASSERT_TRUE(keystore_keys.size() == 1);
+  ASSERT_EQ(keystore_keys.size(), size_t{1});
   const KeyParams kKeystoreKeyParams = KeystoreKeyParams(keystore_keys.back());
   SetNigoriInFakeServer(GetFakeServer(),
                         BuildKeystoreNigoriSpecifics(
@@ -169,6 +169,33 @@
   EXPECT_TRUE(WaitForPasswordForms({password_form}));
 }
 
+// Tests that client can decrypt passwords, encrypted with default key, while
+// Nigori node is in backward-compatible keystore mode (i.e. default key isn't
+// a keystore key, but keystore decryptor token contains this key and encrypted
+// with a keystore key).
+IN_PROC_BROWSER_TEST_P(SingleClientNigoriSyncTestWithUssTests,
+                       ShouldDecryptWithBackwardCompatibleKeystoreNigori) {
+  const std::vector<std::string>& keystore_keys =
+      GetFakeServer()->GetKeystoreKeys();
+  ASSERT_EQ(keystore_keys.size(), size_t{1});
+  const KeyParams kKeystoreKeyParams = KeystoreKeyParams(keystore_keys.back());
+  const KeyParams kDefaultKeyParams = {
+      syncer::KeyDerivationParams::CreateForPbkdf2(), "password"};
+  SetNigoriInFakeServer(
+      GetFakeServer(),
+      BuildKeystoreNigoriSpecifics(
+          /*keybag_keys_params=*/{kDefaultKeyParams, kKeystoreKeyParams},
+          /*keystore_decryptor_params*/ {kDefaultKeyParams},
+          /*keystore_key_params=*/kKeystoreKeyParams));
+  const autofill::PasswordForm password_form =
+      passwords_helper::CreateTestPasswordForm(0);
+  passwords_helper::InjectEncryptedServerPassword(
+      password_form, kDefaultKeyParams.password,
+      kDefaultKeyParams.derivation_params, GetFakeServer());
+  ASSERT_TRUE(SetupSync());
+  EXPECT_TRUE(WaitForPasswordForms({password_form}));
+}
+
 INSTANTIATE_TEST_SUITE_P(USS,
                          SingleClientNigoriSyncTestWithUssTests,
                          ::testing::Values(false, true));
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillBridge.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillBridge.java
index b0376631..3609eddc 100644
--- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillBridge.java
+++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillBridge.java
@@ -51,8 +51,10 @@
     }
 
     @CalledByNative
-    private void showCredentials(String formattedUrl, Credential[] credentials) {
-        mTouchToFillComponent.showCredentials(formattedUrl, Arrays.asList(credentials));
+    private void showCredentials(
+            String formattedUrl, boolean isOriginSecure, Credential[] credentials) {
+        mTouchToFillComponent.showCredentials(
+                formattedUrl, isOriginSecure, Arrays.asList(credentials));
     }
 
     @Override
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillCoordinator.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillCoordinator.java
index 6fb0199..9236cda 100644
--- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillCoordinator.java
+++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillCoordinator.java
@@ -34,8 +34,9 @@
     }
 
     @Override
-    public void showCredentials(String formattedUrl, List<Credential> credentials) {
-        mMediator.showCredentials(formattedUrl, credentials);
+    public void showCredentials(
+            String formattedUrl, boolean isOriginSecure, List<Credential> credentials) {
+        mMediator.showCredentials(formattedUrl, isOriginSecure, credentials);
     }
 
     /**
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillMediator.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillMediator.java
index d1fa39f3c..ccc945ff 100644
--- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillMediator.java
+++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillMediator.java
@@ -6,6 +6,7 @@
 
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CREDENTIAL_LIST;
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FORMATTED_URL;
+import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ORIGIN_SECURE;
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE;
 
 import org.chromium.chrome.browser.touch_to_fill.data.Credential;
@@ -27,9 +28,11 @@
         mModel = model;
     }
 
-    void showCredentials(String formattedUrl, List<Credential> credentials) {
+    void showCredentials(
+            String formattedUrl, boolean isOriginSecure, List<Credential> credentials) {
         assert credentials != null;
         mModel.set(FORMATTED_URL, formattedUrl);
+        mModel.set(ORIGIN_SECURE, isOriginSecure);
         mModel.set(VISIBLE, true);
         mModel.get(CREDENTIAL_LIST).clear();
         mModel.get(CREDENTIAL_LIST).addAll(credentials);
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillProperties.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillProperties.java
index 09c1630..4a132dbf 100644
--- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillProperties.java
+++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillProperties.java
@@ -16,6 +16,8 @@
             new PropertyModel.WritableBooleanPropertyKey("visible");
     static final PropertyModel.WritableObjectPropertyKey<String> FORMATTED_URL =
             new PropertyModel.WritableObjectPropertyKey<>("formatted_url");
+    static final PropertyModel.WritableBooleanPropertyKey ORIGIN_SECURE =
+            new PropertyModel.WritableBooleanPropertyKey("origin_secure");
     static final PropertyModel.ReadableObjectPropertyKey<ListModel<Credential>> CREDENTIAL_LIST =
             new PropertyModel.ReadableObjectPropertyKey<>("credential_list");
     static final PropertyModel.ReadableObjectPropertyKey<ViewEventListener> VIEW_EVENT_LISTENER =
@@ -23,8 +25,10 @@
 
     static PropertyModel createDefaultModel(ViewEventListener listener) {
         return new PropertyModel
-                .Builder(VISIBLE, FORMATTED_URL, CREDENTIAL_LIST, VIEW_EVENT_LISTENER)
+                .Builder(
+                        VISIBLE, FORMATTED_URL, ORIGIN_SECURE, CREDENTIAL_LIST, VIEW_EVENT_LISTENER)
                 .with(VISIBLE, false)
+                .with(ORIGIN_SECURE, false)
                 .with(CREDENTIAL_LIST, new ListModel<>())
                 .with(VIEW_EVENT_LISTENER, listener)
                 .build();
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java
index 9d8758e..22c75c4 100644
--- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java
+++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillView.java
@@ -84,13 +84,23 @@
     }
 
     /**
-     * Renders the given url into the subtitle.
+     * Renders the given secure url into the subtitle.
      * @param formattedUrl A {@link String} containing a URL already formatted to display.
      */
-    void setFormattedUrl(String formattedUrl) {
+    void setSecureSubtitle(String formattedUrl) {
         TextView sheetSubtitleText = mContentView.findViewById(R.id.touch_to_fill_sheet_subtitle);
-        sheetSubtitleText.setText(String.format(
-                mContext.getString(R.string.touch_to_fill_sheet_subtitle), formattedUrl));
+        sheetSubtitleText.setText(formattedUrl);
+    }
+
+    /**
+     * Renders the given non-secure url into the subtitle.
+     * @param formattedUrl A {@link String} containing a URL already formatted to display.
+     */
+    void setNonSecureSubtitle(String formattedUrl) {
+        TextView sheetSubtitleText = mContentView.findViewById(R.id.touch_to_fill_sheet_subtitle);
+        String subtitleText = String.format(
+                mContext.getString(R.string.touch_to_fill_sheet_subtitle_not_secure), formattedUrl);
+        sheetSubtitleText.setText(subtitleText);
     }
 
     void setCredentialListAdapter(ListAdapter adapter) {
diff --git a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java
index d6ab53b..9c4ab49 100644
--- a/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java
+++ b/chrome/browser/touch_to_fill/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewBinder.java
@@ -6,6 +6,7 @@
 
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CREDENTIAL_LIST;
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FORMATTED_URL;
+import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ORIGIN_SECURE;
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VIEW_EVENT_LISTENER;
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE;
 import static org.chromium.chrome.browser.util.UrlUtilities.stripScheme;
@@ -67,8 +68,12 @@
             view.setEventListener(model.get(VIEW_EVENT_LISTENER));
         } else if (propertyKey == VISIBLE) {
             view.setVisible(model.get(VISIBLE));
-        } else if (propertyKey == FORMATTED_URL) {
-            view.setFormattedUrl(model.get(FORMATTED_URL));
+        } else if (propertyKey == FORMATTED_URL || propertyKey == ORIGIN_SECURE) {
+            if (model.get(ORIGIN_SECURE)) {
+                view.setSecureSubtitle(model.get(FORMATTED_URL));
+            } else {
+                view.setNonSecureSubtitle(model.get(FORMATTED_URL));
+            }
         } else if (propertyKey == CREDENTIAL_LIST) {
             // No binding required. Single items are bound via bindCredentialView.
         } else {
diff --git a/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings.grd b/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings.grd
index 7c63bd8..890840e 100644
--- a/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings.grd
+++ b/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings.grd
@@ -110,8 +110,8 @@
       <message name="IDS_TOUCH_TO_FILL_SHEET_TITLE" desc="Header for Touch To Fill sheet where users can pick a credential to fill into a form to.">
         Choose an account
       </message>
-      <message name="IDS_TOUCH_TO_FILL_SHEET_SUBTITLE" desc="Subtitle for Touch To Fill sheet where users can pick a credential to fill into a form to.">
-        for <ph name="SITE_NAME">%1$s<ex>airbnb.com</ex></ph>
+      <message name="IDS_TOUCH_TO_FILL_SHEET_SUBTITLE_NOT_SECURE" desc="Subtitle for Touch To Fill sheet when the website is not secure. Note that similarly to the omnibox 'not secure' in this case primarily refers to HTTPS connection security. So prefer translations with a connotation of 'not private' (someone can intercept your communication with the site) rather than 'not trustworthy' (which would be a judgment of site reputation).">
+        <ph name="SITE_NAME">%1$s<ex>airbnb.com</ex> (not secure)</ph>
       </message>
       <message name="IDS_TOUCH_TO_FILL_CONTENT_DESCRIPTION" desc="Accessibility string read when the Touch To Fill bottom sheet is opened. It describes the bottom sheet where a user can pick a credential to fill into a password form.">
         List of credentials to be filled on touch.
diff --git a/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings_grd/IDS_TOUCH_TO_FILL_SHEET_SUBTITLE.png.sha1 b/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings_grd/IDS_TOUCH_TO_FILL_SHEET_SUBTITLE.png.sha1
deleted file mode 100644
index f21889cc1..0000000
--- a/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings_grd/IDS_TOUCH_TO_FILL_SHEET_SUBTITLE.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-5c2d04c928c95b168528a69cc3f53e433c66eb7d
\ No newline at end of file
diff --git a/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings_grd/IDS_TOUCH_TO_FILL_SHEET_SUBTITLE_NOT_SECURE.png.sha1 b/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings_grd/IDS_TOUCH_TO_FILL_SHEET_SUBTITLE_NOT_SECURE.png.sha1
new file mode 100644
index 0000000..6d557ef9
--- /dev/null
+++ b/chrome/browser/touch_to_fill/android/internal/java/strings/android_touch_to_fill_strings_grd/IDS_TOUCH_TO_FILL_SHEET_SUBTITLE_NOT_SECURE.png.sha1
@@ -0,0 +1 @@
+f8bf7acd009478ac664f46db2219f42687fcf7a8
\ No newline at end of file
diff --git a/chrome/browser/touch_to_fill/android/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillComponent.java b/chrome/browser/touch_to_fill/android/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillComponent.java
index fc4bcab6..3445d58 100644
--- a/chrome/browser/touch_to_fill/android/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillComponent.java
+++ b/chrome/browser/touch_to_fill/android/java/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillComponent.java
@@ -44,7 +44,8 @@
     /**
      * Displays the given credentials in a new bottom sheet.
      * @param formattedUrl A {@link String} that contains the URL to display credentials for.
+     * @param isOriginSecure A {@link boolean} that indicates whether the current origin is secure.
      * @param credentials A list of {@link Credential}s that will be displayed.
      */
-    void showCredentials(String formattedUrl, List<Credential> credentials);
+    void showCredentials(String formattedUrl, boolean isOriginSecure, List<Credential> credentials);
 }
diff --git a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java
index 517dd9a..b15ad440 100644
--- a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java
+++ b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillIntegrationTest.java
@@ -24,6 +24,7 @@
 import org.mockito.MockitoAnnotations;
 
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.RetryOnFailure;
 import org.chromium.base.test.util.ScalableTimeout;
 import org.chromium.chrome.browser.ChromeSwitches;
@@ -73,9 +74,11 @@
 
     @Test
     @MediumTest
+    @DisabledTest(message = "crbug.com/1012221")
     public void testClickingSuggestionsTriggersCallback() {
-        runOnUiThreadBlocking(
-                () -> { mTouchToFill.showCredentials(EXAMPLE_URL, Arrays.asList(ANA, BOB)); });
+        runOnUiThreadBlocking(() -> {
+            mTouchToFill.showCredentials(EXAMPLE_URL, true, Arrays.asList(ANA, BOB));
+        });
         pollUiThread(() -> getBottomSheetState() == SheetState.FULL);
 
         pollUiThread(() -> getCredentials().getChildAt(1) != null);
@@ -88,8 +91,9 @@
     @Test
     @MediumTest
     public void testBackDismissesAndCallsCallback() {
-        runOnUiThreadBlocking(
-                () -> { mTouchToFill.showCredentials(EXAMPLE_URL, Arrays.asList(ANA, BOB)); });
+        runOnUiThreadBlocking(() -> {
+            mTouchToFill.showCredentials(EXAMPLE_URL, true, Arrays.asList(ANA, BOB));
+        });
         pollUiThread(() -> getBottomSheetState() == SheetState.FULL);
 
         Espresso.pressBack();
@@ -111,4 +115,4 @@
         pollUiThread(() -> mActivityTestRule.getActivity().getBottomSheet() != null);
         return mActivityTestRule.getActivity().getBottomSheet().getSheetState();
     }
-}
\ No newline at end of file
+}
diff --git a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java
index d3498f7..b64ab2be 100644
--- a/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java
+++ b/chrome/browser/touch_to_fill/android/javatests/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillViewTest.java
@@ -13,6 +13,7 @@
 
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CREDENTIAL_LIST;
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FORMATTED_URL;
+import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ORIGIN_SECURE;
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE;
 import static org.chromium.content_public.browser.test.util.CriteriaHelper.pollUiThread;
 
@@ -93,17 +94,21 @@
     public void testSubtitleUrlChangedByModel() {
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             mModel.set(FORMATTED_URL, "www.example.org");
+            mModel.set(ORIGIN_SECURE, true);
             mModel.set(VISIBLE, true);
         });
         pollUiThread(() -> getBottomSheetState() == SheetState.FULL);
         TextView subtitle =
                 mTouchToFillView.getContentView().findViewById(R.id.touch_to_fill_sheet_subtitle);
 
-        assertThat(subtitle.getText(), is(getFormattedSubtitle("www.example.org")));
+        assertThat(subtitle.getText(), is("www.example.org"));
 
-        TestThreadUtils.runOnUiThreadBlocking(() -> mModel.set(FORMATTED_URL, "m.example.org"));
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            mModel.set(FORMATTED_URL, "m.example.org");
+            mModel.set(ORIGIN_SECURE, false);
+        });
 
-        assertThat(subtitle.getText(), is(getFormattedSubtitle("m.example.org")));
+        assertThat(subtitle.getText(), is(getFormattedNotSecureSubtitle("m.example.org")));
     }
 
     @Test
@@ -171,8 +176,8 @@
         return mActivityTestRule.getActivity();
     }
 
-    private String getFormattedSubtitle(String url) {
-        return getActivity().getString(R.string.touch_to_fill_sheet_subtitle, url);
+    private String getFormattedNotSecureSubtitle(String url) {
+        return getActivity().getString(R.string.touch_to_fill_sheet_subtitle_not_secure, url);
     }
 
     private @SheetState int getBottomSheetState() {
@@ -200,4 +205,4 @@
         return verify(mMockListener,
                 timeout(ScalableTimeout.scaleTimeout(CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL)));
     }
-}
\ No newline at end of file
+}
diff --git a/chrome/browser/touch_to_fill/android/junit/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillControllerTest.java b/chrome/browser/touch_to_fill/android/junit/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillControllerTest.java
index 9cd0b06..06f91dc 100644
--- a/chrome/browser/touch_to_fill/android/junit/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillControllerTest.java
+++ b/chrome/browser/touch_to_fill/android/junit/src/org/chromium/chrome/browser/touch_to_fill/TouchToFillControllerTest.java
@@ -12,6 +12,7 @@
 
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.CREDENTIAL_LIST;
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.FORMATTED_URL;
+import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.ORIGIN_SECURE;
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VIEW_EVENT_LISTENER;
 import static org.chromium.chrome.browser.touch_to_fill.TouchToFillProperties.VISIBLE;
 
@@ -62,17 +63,19 @@
         assertNotNull(mModel.get(VIEW_EVENT_LISTENER));
         assertThat(mModel.get(VISIBLE), is(false));
         assertThat(mModel.get(FORMATTED_URL), is(nullValue()));
+        assertThat(mModel.get(ORIGIN_SECURE), is(false));
     }
 
     @Test
     public void testShowCredentialsSetsFormattedUrl() {
-        mMediator.showCredentials(TEST_URL, Arrays.asList(ANA, CARL, BOB));
+        mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL, BOB));
         assertThat(mModel.get(FORMATTED_URL), is(TEST_URL));
+        assertThat(mModel.get(ORIGIN_SECURE), is(true));
     }
 
     @Test
     public void testShowCredentialsSetsCredentialList() {
-        mMediator.showCredentials(TEST_URL, Arrays.asList(ANA, CARL, BOB));
+        mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL, BOB));
         assertThat(mModel.get(CREDENTIAL_LIST).size(), is(3));
         assertThat(mModel.get(CREDENTIAL_LIST).get(0), is(ANA));
         assertThat(mModel.get(CREDENTIAL_LIST).get(1), is(CARL));
@@ -81,25 +84,25 @@
 
     @Test
     public void testClearsCredentialListWhenShowingAgain() {
-        mMediator.showCredentials(TEST_URL, Collections.singletonList(ANA));
+        mMediator.showCredentials(TEST_URL, true, Collections.singletonList(ANA));
         assertThat(mModel.get(CREDENTIAL_LIST).size(), is(1));
         assertThat(mModel.get(CREDENTIAL_LIST).get(0), is(ANA));
 
         // Showing the sheet a second time should replace all changed credentials.
-        mMediator.showCredentials(TEST_URL, Collections.singletonList(BOB));
+        mMediator.showCredentials(TEST_URL, true, Collections.singletonList(BOB));
         assertThat(mModel.get(CREDENTIAL_LIST).size(), is(1));
         assertThat(mModel.get(CREDENTIAL_LIST).get(0), is(BOB));
     }
 
     @Test
     public void testShowCredentialsSetsVisibile() {
-        mMediator.showCredentials(TEST_URL, Arrays.asList(ANA, CARL, BOB));
+        mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL, BOB));
         assertThat(mModel.get(VISIBLE), is(true));
     }
 
     @Test
     public void testCallsCallbackAndHidesOnSelectingItem() {
-        mMediator.showCredentials(TEST_URL, Arrays.asList(ANA, CARL));
+        mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL));
         mMediator.onSelectItemAt(1);
         verify(mMockDelegate).onCredentialSelected(CARL);
         assertThat(mModel.get(VISIBLE), is(false));
@@ -107,7 +110,7 @@
 
     @Test
     public void testCallsDelegateAndHidesOnDismiss() {
-        mMediator.showCredentials(TEST_URL, Arrays.asList(ANA, CARL));
+        mMediator.showCredentials(TEST_URL, true, Arrays.asList(ANA, CARL));
         mMediator.onDismissed();
         verify(mMockDelegate).onDismissed();
         assertThat(mModel.get(VISIBLE), is(false));
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 1b90366c..3448382 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
@@ -38,7 +38,8 @@
                                Java_Credential_getPassword(env, credential)),
       GURL(ConvertJavaStringToUTF8(
           env, Java_Credential_getOriginUrl(env, credential))),
-      Java_Credential_isPublicSuffixMatch(env, credential));
+      CredentialPair::IsPublicSuffixMatch(
+          Java_Credential_isPublicSuffixMatch(env, credential)));
 }
 
 }  // namespace
@@ -56,10 +57,8 @@
 
 void TouchToFillViewImpl::Show(
     base::StringPiece16 formatted_url,
-    base::span<const password_manager::CredentialPair> credentials,
-    ShowCallback callback) {
-  callback_ = std::move(callback);
-
+    IsOriginSecure is_origin_secure,
+    base::span<const password_manager::CredentialPair> credentials) {
   // Serialize the |credentials| span into a Java array and instruct the bridge
   // to show it together with |formatted_url| to the user.
   JNIEnv* env = AttachCurrentThread();
@@ -73,22 +72,27 @@
         ConvertUTF16ToJavaString(env, credential.password),
         ConvertUTF16ToJavaString(env, GetDisplayUsername(credential)),
         ConvertUTF8ToJavaString(env, credential.origin_url.spec()),
-        credential.is_public_suffix_match);
+        credential.is_public_suffix_match.value());
   }
 
   Java_TouchToFillBridge_showCredentials(
       env, java_object_, ConvertUTF16ToJavaString(env, formatted_url),
-      credential_array);
+      is_origin_secure.value(), credential_array);
+}
+
+void TouchToFillViewImpl::OnCredentialSelected(
+    const CredentialPair& credential) {
+  controller_->OnCredentialSelected(credential);
 }
 
 void TouchToFillViewImpl::OnDismiss() {
-  // TODO(crbug.com/957532): Implement.
+  controller_->OnDismiss();
 }
 
 void TouchToFillViewImpl::OnCredentialSelected(
     JNIEnv* env,
     const JavaParamRef<jobject>& credential) {
-  std::move(callback_).Run(ConvertJavaCredential(env, credential));
+  OnCredentialSelected(ConvertJavaCredential(env, credential));
 }
 
 void TouchToFillViewImpl::OnDismiss(JNIEnv* env) {
diff --git a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h
index c08ca52..356770f 100644
--- a/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h
+++ b/chrome/browser/touch_to_fill/android/touch_to_fill_view_impl.h
@@ -19,9 +19,12 @@
   ~TouchToFillViewImpl() override;
 
   // TouchToFillView:
-  void Show(base::StringPiece16 formatted_url,
-            base::span<const password_manager::CredentialPair> credentials,
-            ShowCallback callback) override;
+  void Show(
+      base::StringPiece16 formatted_url,
+      IsOriginSecure is_origin_secure,
+      base::span<const password_manager::CredentialPair> credentials) override;
+  void OnCredentialSelected(
+      const password_manager::CredentialPair& credential) override;
   void OnDismiss() override;
 
   // Called from Java via JNI:
@@ -33,7 +36,6 @@
  private:
   TouchToFillController* controller_ = nullptr;
   base::android::ScopedJavaGlobalRef<jobject> java_object_;
-  ShowCallback callback_;
 };
 
 #endif  // CHROME_BROWSER_TOUCH_TO_FILL_ANDROID_TOUCH_TO_FILL_VIEW_IMPL_H_
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_view.h b/chrome/browser/touch_to_fill/touch_to_fill_view.h
index 64e6c77..26232763 100644
--- a/chrome/browser/touch_to_fill/touch_to_fill_view.h
+++ b/chrome/browser/touch_to_fill/touch_to_fill_view.h
@@ -8,6 +8,7 @@
 #include "base/callback_forward.h"
 #include "base/containers/span.h"
 #include "base/strings/string_piece_forward.h"
+#include "base/util/type_safety/strong_alias.h"
 
 namespace password_manager {
 struct CredentialPair;
@@ -17,8 +18,7 @@
 // To Fill controller with the Android frontend.
 class TouchToFillView {
  public:
-  using ShowCallback =
-      base::OnceCallback<void(const password_manager::CredentialPair&)>;
+  using IsOriginSecure = util::StrongAlias<class IsOriginSecureTag, bool>;
 
   TouchToFillView() = default;
   TouchToFillView(const TouchToFillView&) = delete;
@@ -27,11 +27,18 @@
 
   // Instructs Touch To Fill to show the provided |credentials| to the user.
   // |formatted_url| contains a human friendly version of the current origin.
-  // Invokes |callback| once the user chose a credential.
+  // |is_origin_secure| indicates whether the current frame origin is secure.
+  // After user interaction either OnCredentialSelected() or OnDismiss() gets
+  // invoked.
   virtual void Show(
       base::StringPiece16 formatted_url,
-      base::span<const password_manager::CredentialPair> credentials,
-      ShowCallback callback) = 0;
+      IsOriginSecure is_origin_secure,
+      base::span<const password_manager::CredentialPair> credentials) = 0;
+
+  // Invoked in case the user chooses an entry from the credential list
+  // presented to them.
+  virtual void OnCredentialSelected(
+      const password_manager::CredentialPair& credential) = 0;
 
   // Invoked if the user dismissed the Touch To Fill sheet without choosing a
   // credential.
diff --git a/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc b/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc
index 1fc3ff4..a6b03f36 100644
--- a/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc
+++ b/chrome/browser/tracing/chrome_tracing_delegate_browsertest.cc
@@ -159,9 +159,16 @@
       base::Closure(), content::BackgroundTracingManager::NO_DATA_FILTERING));
 }
 
-// Flaky. See https://crbug.com/723933 and https://crbug.com/1012218.
+// Flaky on Linux and Windows. See https://crbug.com/723933.
+#if defined(OS_LINUX) || defined(OS_WIN)
+#define MAYBE_BackgroundTracingThrottleTimeElapsed \
+  DISABLED_BackgroundTracingThrottleTimeElapsed
+#else
+#define MAYBE_BackgroundTracingThrottleTimeElapsed \
+  BackgroundTracingThrottleTimeElapsed
+#endif
 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest,
-                       DISABLED_BackgroundTracingThrottleTimeElapsed) {
+                       MAYBE_BackgroundTracingThrottleTimeElapsed) {
   base::RunLoop wait_for_upload;
 
   EXPECT_TRUE(StartPreemptiveScenario(
@@ -217,12 +224,18 @@
       base::Closure(), content::BackgroundTracingManager::ANONYMIZE_DATA));
 }
 
+#if defined(OS_MACOSX) && defined(ADDRESS_SANITIZER)
 // Flaky on ASAN on Mac. See https://crbug.com/674497.
-// Flaky in general. See https://crbug.com/1012218.
+#define MAYBE_NewIncognitoSessionBlockingTraceFinalization \
+  DISABLED_NewIncognitoSessionBlockingTraceFinalization
+#else
+#define MAYBE_NewIncognitoSessionBlockingTraceFinalization \
+  NewIncognitoSessionBlockingTraceFinalization
+#endif
 // If we need a PII-stripped trace, any new OTR session during tracing should
 // block the finalization of the trace.
 IN_PROC_BROWSER_TEST_F(ChromeTracingDelegateBrowserTest,
-                       DISABLED_NewIncognitoSessionBlockingTraceFinalization) {
+                       MAYBE_NewIncognitoSessionBlockingTraceFinalization) {
   EXPECT_TRUE(StartPreemptiveScenario(
       base::Closure(), content::BackgroundTracingManager::ANONYMIZE_DATA));
 
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 4d01ecf..9f4b861 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -513,6 +513,7 @@
     "//components/subresource_filter/content/browser",
     "//components/subresource_filter/core/browser",
     "//components/sync",
+    "//components/sync/driver:resources",
     "//components/sync_preferences",
     "//components/sync_sessions",
     "//components/tracing:startup_tracing",
diff --git a/chrome/browser/ui/app_list/arc/arc_app_test.cc b/chrome/browser/ui/app_list/arc/arc_app_test.cc
index 6038261f5..1efec68 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_test.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_test.cc
@@ -122,17 +122,16 @@
       arc::SetArcPlayStoreEnabledForProfile(profile_, true);
     if (!arc::IsArcPlayStoreEnabledPreferenceManagedForProfile(profile_))
       EXPECT_TRUE(arc_session_manager_->enable_requested());
-
-    app_instance_ = std::make_unique<arc::FakeAppInstance>(arc_app_list_pref_);
-    arc_service_manager_->arc_bridge_service()->app()->SetInstance(
-        app_instance_.get());
-
-    // TODO(khmel): Resolve this gracefully. Set of default app tests does not
-    // expect waiting in ArcAppTest setup.
-    if (wait_default_apps_)
-      WaitForInstanceReady(arc_service_manager_->arc_bridge_service()->app());
   }
 
+  app_instance_ = std::make_unique<arc::FakeAppInstance>(arc_app_list_pref_);
+  arc_service_manager_->arc_bridge_service()->app()->SetInstance(
+      app_instance_.get());
+  // TODO(khmel): Resolve this gracefully. Set of default app tests does not
+  // expect waiting in ArcAppTest setup.
+  if (wait_default_apps_)
+    WaitForInstanceReady(arc_service_manager_->arc_bridge_service()->app());
+
   // Ensure that the singleton apps::ArcApps is constructed.
   if (base::FeatureList::IsEnabled(features::kAppServiceAsh))
     apps::ArcAppsFactory::GetForProfile(profile_);
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.cc b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
index 961b7839..996b6f3 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_utils.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
@@ -252,8 +252,6 @@
 const char kPlayStoreActivity[] = "com.android.vending.AssetBrowserActivity";
 const char kSettingsAppId[] = "mconboelelhjpkbdhhiijkgcimoangdj";
 const char kInitialStartParam[] = "S.org.chromium.arc.start_type=initialStart";
-const char kRequestStartTimeParamTemplate[] =
-    "S.org.chromium.arc.request.start=%ld";
 constexpr char kSettingsAppPackage[] = "com.android.settings";
 const char kSettingsAppDomainUrlActivity[] =
     "com.android.settings.Settings$ManageDomainUrlsActivity";
@@ -337,7 +335,6 @@
 
   ArcAppListPrefs* prefs = ArcAppListPrefs::Get(context);
   std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = prefs->GetApp(app_id);
-  base::Optional<std::string> launch_intent_to_send = std::move(launch_intent);
   if (app_info && !app_info->ready) {
     if (!IsArcPlayStoreEnabledForProfile(profile)) {
       if (prefs->IsDefault(app_id)) {
@@ -382,9 +379,8 @@
     // chrome_controller may be null in tests.
     if (chrome_controller) {
       chrome_controller->GetShelfSpinnerController()->AddSpinnerToShelf(
-          app_id,
-          std::make_unique<ArcShelfSpinnerItemController>(
-              app_id, event_flags, user_action, GetValidDisplayId(display_id)));
+          app_id, std::make_unique<ArcShelfSpinnerItemController>(
+                      app_id, event_flags, GetValidDisplayId(display_id)));
 
       // On some boards, ARC is booted with a restricted set of resources by
       // default to avoid slowing down Chrome's user session restoration.
@@ -394,18 +390,10 @@
     }
     prefs->SetLastLaunchTime(app_id);
     return true;
-  } else if (app_id == kPlayStoreAppId && !launch_intent_to_send) {
-    // Record launch request time in order to track Play Store default launch
-    // performance.
-    launch_intent_to_send = GetLaunchIntent(
-        kPlayStorePackage, kPlayStoreActivity,
-        {base::StringPrintf(
-            kRequestStartTimeParamTemplate,
-            (base::TimeTicks::Now() - base::TimeTicks()).InMilliseconds())});
   }
 
   arc::ArcBootPhaseMonitorBridge::RecordFirstAppLaunchDelayUMA(context);
-  return Launch(context, app_id, launch_intent_to_send, event_flags,
+  return Launch(context, app_id, launch_intent, event_flags,
                 GetValidDisplayId(display_id));
 }
 
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.h b/chrome/browser/ui/app_list/arc/arc_app_utils.h
index 2143054..88b1662e 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_utils.h
+++ b/chrome/browser/ui/app_list/arc/arc_app_utils.h
@@ -40,7 +40,6 @@
 extern const char kPlayStoreActivity[];
 extern const char kSettingsAppId[];
 extern const char kInitialStartParam[];
-extern const char kRequestStartTimeParamTemplate[];
 extern const char kSettingsAppDomainUrlActivity[];
 
 // Represents unparsed intent.
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc
index 8fa067b6..26b668f9 100644
--- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc
@@ -512,8 +512,19 @@
   app_window->SetController(controller);
   app_window->set_shelf_id(shelf_id);
 
-  if (app_window_info->app_shelf_id().app_id() == arc::kPlayStoreAppId)
-    HandlePlayStoreLaunch(app_window_info);
+  if (!opt_in_management_check_start_time_.is_null() &&
+      app_window_info->app_shelf_id().app_id() == arc::kPlayStoreAppId) {
+    arc::Intent intent;
+    if (arc::ParseIntent(app_window_info->launch_intent(), &intent) &&
+        intent.HasExtraParam(arc::kInitialStartParam)) {
+      DCHECK(!arc::IsRobotOrOfflineDemoAccountMode());
+      arc::UpdatePlayStoreShowTime(
+          base::Time::Now() - opt_in_management_check_start_time_,
+          owner()->profile());
+      VLOG(1) << "Play Store is initially shown.";
+    }
+    opt_in_management_check_start_time_ = base::Time();
+  }
 }
 
 void ArcAppWindowLauncherController::UnregisterApp(
@@ -528,34 +539,3 @@
   app_window->SetController(nullptr);
   app_window_info->set_app_window(nullptr);
 }
-
-void ArcAppWindowLauncherController::HandlePlayStoreLaunch(
-    AppWindowInfo* app_window_info) {
-  arc::Intent intent;
-  if (!arc::ParseIntent(app_window_info->launch_intent(), &intent))
-    return;
-
-  if (!opt_in_management_check_start_time_.is_null()) {
-    if (intent.HasExtraParam(arc::kInitialStartParam)) {
-      DCHECK(!arc::IsRobotOrOfflineDemoAccountMode());
-      arc::UpdatePlayStoreShownTimeDeprecated(
-          base::Time::Now() - opt_in_management_check_start_time_,
-          owner()->profile());
-      VLOG(1) << "Play Store is initially shown.";
-    }
-    opt_in_management_check_start_time_ = base::Time();
-    return;
-  }
-
-  for (const auto& param : intent.extra_params()) {
-    int64_t start_request_ms;
-    if (sscanf(param.c_str(), arc::kRequestStartTimeParamTemplate,
-               &start_request_ms) != 1)
-      continue;
-    const base::TimeDelta launch_time =
-        base::TimeTicks::Now() - base::TimeTicks() -
-        base::TimeDelta::FromMilliseconds(start_request_ms);
-    DCHECK_GE(launch_time, base::TimeDelta());
-    arc::UpdatePlayStoreLaunchTime(launch_time);
-  }
-}
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h
index 903051e..0a5ad03 100644
--- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h
+++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h
@@ -91,7 +91,6 @@
 
   void RegisterApp(AppWindowInfo* app_window_info);
   void UnregisterApp(AppWindowInfo* app_window_info);
-  void HandlePlayStoreLaunch(AppWindowInfo* app_window_info);
 
   AppWindowInfo* GetAppWindowInfoForTask(int task_id);
   ArcAppWindow* GetAppWindowForTask(int task_id);
diff --git a/chrome/browser/ui/ash/launcher/arc_shelf_spinner_item_controller.cc b/chrome/browser/ui/ash/launcher/arc_shelf_spinner_item_controller.cc
index 2b5ad56..3e6f5f9 100644
--- a/chrome/browser/ui/ash/launcher/arc_shelf_spinner_item_controller.cc
+++ b/chrome/browser/ui/ash/launcher/arc_shelf_spinner_item_controller.cc
@@ -5,17 +5,16 @@
 #include "chrome/browser/ui/ash/launcher/arc_shelf_spinner_item_controller.h"
 
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
 #include "chrome/browser/ui/ash/launcher/shelf_spinner_controller.h"
 #include "components/arc/metrics/arc_metrics_constants.h"
 
 ArcShelfSpinnerItemController::ArcShelfSpinnerItemController(
     const std::string& arc_app_id,
     int event_flags,
-    arc::UserInteractionType user_interaction_type,
     int64_t display_id)
     : ShelfSpinnerItemController(arc_app_id),
       event_flags_(event_flags),
-      user_interaction_type_(user_interaction_type),
       display_id_(display_id) {
   arc::ArcSessionManager* arc_session_manager = arc::ArcSessionManager::Get();
   // arc::ArcSessionManager might not be set in tests.
@@ -58,7 +57,7 @@
 
   // Close() destroys this object, so start launching the app first.
   arc::LaunchApp(observed_profile_, arc_app_id, event_flags_,
-                 user_interaction_type_, display_id_);
+                 arc::UserInteractionType::APP_STARTED_FROM_SHELF, display_id_);
   Close();
 }
 
diff --git a/chrome/browser/ui/ash/launcher/arc_shelf_spinner_item_controller.h b/chrome/browser/ui/ash/launcher/arc_shelf_spinner_item_controller.h
index c253d22..07a160d 100644
--- a/chrome/browser/ui/ash/launcher/arc_shelf_spinner_item_controller.h
+++ b/chrome/browser/ui/ash/launcher/arc_shelf_spinner_item_controller.h
@@ -11,10 +11,8 @@
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
 #include "chrome/browser/chromeos/arc/session/arc_session_manager.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
-#include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
 #include "chrome/browser/ui/ash/launcher/shelf_spinner_item_controller.h"
 
 // ArcShelfSpinnerItemController displays the icon of the ARC app that
@@ -26,7 +24,6 @@
  public:
   ArcShelfSpinnerItemController(const std::string& arc_app_id,
                                 int event_flags,
-                                arc::UserInteractionType user_interaction_type,
                                 int64_t display_id);
 
   ~ArcShelfSpinnerItemController() override;
@@ -47,9 +44,6 @@
   // be propagated to the launch event once the app is actually launched.
   const int event_flags_;
 
-  // Stores how this action was initiated.
-  const arc::UserInteractionType user_interaction_type_;
-
   const int64_t display_id_;
 
   // Unowned
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
index eea93a6..f6f9a75 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_unittest.cc
@@ -33,7 +33,6 @@
 #include "base/location.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
-#include "base/metrics/statistics_recorder.h"
 #include "base/run_loop.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/utf_string_conversions.h"
@@ -4344,69 +4343,6 @@
       arc::kPlayStoreAppId));
 }
 
-TEST_F(ChromeLauncherControllerArcDefaultAppsTest, PlayStoreLaunchMetric) {
-  extension_service_->AddExtension(arc_support_host_.get());
-  arc_test_.SetUp(profile());
-  ArcAppListPrefs* const prefs = arc_test_.arc_app_list_prefs();
-
-  InitLauncherController();
-  EnablePlayStore(true);
-
-  // Play Store available now as a default app but is not ready yet.
-  std::unique_ptr<ArcAppListPrefs::AppInfo> app_info =
-      prefs->GetApp(arc::kPlayStoreAppId);
-  ASSERT_TRUE(app_info);
-  EXPECT_FALSE(app_info->ready);
-
-  constexpr char kHistogramName[] = "Arc.PlayStoreLaunch.TimeDelta";
-
-  // Launch Play Store in deferred mode.
-  arc::LaunchApp(profile(), arc::kPlayStoreAppId, ui::EF_LEFT_MOUSE_BUTTON,
-                 arc::UserInteractionType::NOT_USER_INITIATED);
-  // This is deferred launch, no actual intents are delivered to ARC.
-  EXPECT_EQ(0U, arc_test_.app_instance()->launch_intents().size());
-  arc::mojom::AppInfo app;
-  app.activity = arc::kPlayStoreActivity;
-  app.package_name = arc::kPlayStorePackage;
-  const base::TimeTicks app_ready_ticks = base::TimeTicks::Now();
-  arc_test_.app_instance()->SendRefreshAppList({app});
-  ASSERT_EQ(1U, arc_test_.app_instance()->launch_intents().size());
-  std::string play_store_window_id("org.chromium.arc.1");
-  views::Widget* play_store_window = CreateArcWindow(play_store_window_id);
-  arc_test_.app_instance()->SendTaskCreated(
-      1, app, arc_test_.app_instance()->launch_intents()[0]);
-  const base::TimeTicks app_launched_ticks = base::TimeTicks::Now();
-  EXPECT_TRUE(
-      launcher_controller_->GetItem(ash::ShelfID(arc::kPlayStoreAppId)));
-  // UMA is reported since app becomes ready.
-  base::HistogramBase* const histogram =
-      base::StatisticsRecorder::FindHistogram(kHistogramName);
-  ASSERT_TRUE(histogram);
-  // Recorded time should not be longer than
-  // app_launched_ticks - app_ready_ticks, the indication that app launch time
-  // was recorded since app became ready.
-  std::unique_ptr<base::HistogramSamples> samples = histogram->SnapshotDelta();
-  ASSERT_EQ(1, samples->TotalCount());
-  EXPECT_GE((app_launched_ticks - app_ready_ticks).InMilliseconds(),
-            samples->sum());
-  play_store_window->Close();
-
-  // Launch Play Store in app-ready mode.
-  arc::LaunchApp(profile(), arc::kPlayStoreAppId, ui::EF_LEFT_MOUSE_BUTTON,
-                 arc::UserInteractionType::NOT_USER_INITIATED);
-  ASSERT_EQ(2U, arc_test_.app_instance()->launch_intents().size());
-  play_store_window_id = "org.chromium.arc.2";
-  play_store_window = CreateArcWindow(play_store_window_id);
-  arc_test_.app_instance()->SendTaskCreated(
-      2, app, arc_test_.app_instance()->launch_intents()[1]);
-  EXPECT_TRUE(
-      launcher_controller_->GetItem(ash::ShelfID(arc::kPlayStoreAppId)));
-  // UMA is reported for app-ready launch. Note, previous call of SnapshotDelta
-  // resets samples, so we expect here only one recorded.
-  EXPECT_EQ(1, histogram->SnapshotDelta()->TotalCount());
-  play_store_window->Close();
-}
-
 // Tests that the Play Store is not visible in AOSP image and visible in default
 // images.
 TEST_P(ChromeLauncherControllerPlayStoreAvailabilityTest, Visible) {
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h
index 134df162..45f90f8cc 100644
--- a/chrome/browser/ui/browser_window.h
+++ b/chrome/browser/ui/browser_window.h
@@ -13,6 +13,7 @@
 #include "build/build_config.h"
 #include "chrome/browser/apps/intent_helper/apps_navigation_types.h"
 #include "chrome/browser/lifetime/browser_close_manager.h"
+#include "chrome/browser/sharing/sharing_dialog_data.h"
 #include "chrome/browser/signin/chrome_signin_helper.h"
 #include "chrome/browser/translate/chrome_translate_client.h"
 #include "chrome/browser/ui/bookmarks/bookmark_bar.h"
@@ -40,7 +41,6 @@
 class FindBar;
 class GURL;
 class LocationBar;
-class SharingUiController;
 class StatusBubble;
 class ToolbarActionsBar;
 
@@ -333,7 +333,7 @@
 
   // Shows the dialog for a sharing feature.
   virtual SharingDialog* ShowSharingDialog(content::WebContents* contents,
-                                           SharingUiController* controller) = 0;
+                                           SharingDialogData data) = 0;
 
   // Shows the Update Recommended dialog box.
   virtual void ShowUpdateChromeDialog() = 0;
diff --git a/chrome/browser/ui/views/extensions/extension_dialog.cc b/chrome/browser/ui/views/extensions/extension_dialog.cc
index 852a8ab..1fa7f0b 100644
--- a/chrome/browser/ui/views/extensions/extension_dialog.cc
+++ b/chrome/browser/ui/views/extensions/extension_dialog.cc
@@ -39,6 +39,8 @@
     std::unique_ptr<extensions::ExtensionViewHost> host,
     ExtensionDialogObserver* observer)
     : host_(std::move(host)), observer_(observer) {
+  DialogDelegate::set_use_custom_frame(false);
+
   AddRef();  // Balanced in DeleteDelegate();
 
   registrar_.Add(this,
@@ -220,10 +222,6 @@
   return GetExtensionView();
 }
 
-bool ExtensionDialog::ShouldUseCustomFrame() const {
-  return false;
-}
-
 /////////////////////////////////////////////////////////////////////////////
 // content::NotificationObserver overrides.
 
diff --git a/chrome/browser/ui/views/extensions/extension_dialog.h b/chrome/browser/ui/views/extensions/extension_dialog.h
index 72ebb8c..c31dcbe 100644
--- a/chrome/browser/ui/views/extensions/extension_dialog.h
+++ b/chrome/browser/ui/views/extensions/extension_dialog.h
@@ -79,7 +79,6 @@
   views::Widget* GetWidget() override;
   const views::Widget* GetWidget() const override;
   views::View* GetContentsView() override;
-  bool ShouldUseCustomFrame() const override;
 
   // content::NotificationObserver overrides.
   void Observe(int type,
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 24da581..1a53315 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1305,11 +1305,11 @@
 
 SharingDialog* BrowserView::ShowSharingDialog(
     content::WebContents* web_contents,
-    SharingUiController* controller) {
+    SharingDialogData data) {
   auto* dialog_view =
       new SharingDialogView(toolbar_button_provider()->GetAnchorView(
                                 PageActionIconType::kSharedClipboard),
-                            web_contents, controller);
+                            web_contents, std::move(data));
 
   views::BubbleDialogDelegateView::CreateBubble(dialog_view)->Show();
 
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index 596b244b..be4510d 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -356,7 +356,7 @@
   bool IsToolbarVisible() const override;
   bool IsToolbarShowing() const override;
   SharingDialog* ShowSharingDialog(content::WebContents* contents,
-                                   SharingUiController* controller) override;
+                                   SharingDialogData data) override;
   void ShowUpdateChromeDialog() override;
   void ShowIntentPickerBubble(
       std::vector<IntentPickerBubbleView::AppInfo> app_info,
diff --git a/chrome/browser/ui/views/hung_renderer_view.cc b/chrome/browser/ui/views/hung_renderer_view.cc
index 5ccb318..ace95a5 100644
--- a/chrome/browser/ui/views/hung_renderer_view.cc
+++ b/chrome/browser/ui/views/hung_renderer_view.cc
@@ -270,6 +270,11 @@
 
 HungRendererDialogView::HungRendererDialogView()
     : info_label_(nullptr), hung_pages_table_(nullptr), initialized_(false) {
+#if defined(OS_WIN)
+  // Never use the custom frame when Aero Glass is disabled. See
+  // https://crbug.com/323278
+  DialogDelegate::set_use_custom_frame(ui::win::IsAeroGlassEnabled());
+#endif
   set_margins(ChromeLayoutProvider::Get()->GetDialogInsetsForContentType(
       views::TEXT, views::CONTROL));
   chrome::RecordDialogCreation(chrome::DialogIdentifier::HUNG_RENDERER);
@@ -410,16 +415,6 @@
   return Accept();
 }
 
-bool HungRendererDialogView::ShouldUseCustomFrame() const {
-#if defined(OS_WIN)
-  // Use the old dialog style without Aero glass, otherwise the dialog will be
-  // visually constrained to browser window bounds. See http://crbug.com/323278
-  return ui::win::IsAeroGlassEnabled();
-#else
-  return views::DialogDelegateView::ShouldUseCustomFrame();
-#endif
-}
-
 ///////////////////////////////////////////////////////////////////////////////
 // HungRendererDialogView, HungPagesTableModel::Delegate overrides:
 
diff --git a/chrome/browser/ui/views/hung_renderer_view.h b/chrome/browser/ui/views/hung_renderer_view.h
index 290a4f1e..226ca28 100644
--- a/chrome/browser/ui/views/hung_renderer_view.h
+++ b/chrome/browser/ui/views/hung_renderer_view.h
@@ -171,7 +171,6 @@
   bool Cancel() override;
   bool Accept() override;
   bool Close() override;
-  bool ShouldUseCustomFrame() const override;
 
   // HungPagesTableModel::Delegate overrides:
   void TabUpdated() override;
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc
index d8bfa15..faf9391 100644
--- a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc
+++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc
@@ -113,12 +113,17 @@
 }  // namespace
 
 AvatarToolbarButton::AvatarToolbarButton(Browser* browser)
+    : AvatarToolbarButton(browser, nullptr) {}
+
+AvatarToolbarButton::AvatarToolbarButton(Browser* browser,
+                                         ToolbarIconContainerView* parent)
     : ToolbarButton(nullptr),
 #if !defined(OS_CHROMEOS)
       error_controller_(this, browser->profile()),
 #endif  // !defined(OS_CHROMEOS)
       browser_(browser),
-      profile_(browser_->profile()) {
+      profile_(browser_->profile()),
+      parent_(parent) {
   profile_observer_.Add(&GetProfileAttributesStorage());
 
   State state = GetState();
@@ -169,10 +174,19 @@
   UpdateText();
 
   md_observer_.Add(ui::MaterialDesignController::GetInstance());
+
+  // TODO(crbug.com/922525): DCHECK(parent_) instead of the if, once we always
+  // have a parent.
+  if (parent_)
+    parent_->AddObserver(this);
 }
 
 AvatarToolbarButton::~AvatarToolbarButton() {
   BrowserList::RemoveObserver(this);
+
+  // TODO(crbug.com/922525): Remove the if, once we always have a parent.
+  if (parent_)
+    parent_->RemoveObserver(this);
 }
 
 void AvatarToolbarButton::UpdateIcon() {
@@ -272,10 +286,7 @@
 
 void AvatarToolbarButton::NotifyClick(const ui::Event& event) {
   Button::NotifyClick(event);
-  if (identity_animation_state_ ==
-      IdentityAnimationState::kShowingUntilNoLongerHoveredOrFocused) {
-    HideIdentityAnimationWhenNotHoveredOrFocused();
-  }
+  MaybeHideIdentityAnimation();
   // TODO(bsep): Other toolbar buttons have ToolbarView as a listener and let it
   // call ExecuteCommandWithDisposition on their behalf. Unfortunately, it's not
   // possible to plumb IsKeyEvent through, so this has to be a special case.
@@ -286,18 +297,12 @@
 }
 
 void AvatarToolbarButton::OnMouseExited(const ui::MouseEvent& event) {
-  if (identity_animation_state_ ==
-      IdentityAnimationState::kShowingUntilNoLongerHoveredOrFocused) {
-    HideIdentityAnimationWhenNotHoveredOrFocused();
-  }
+  MaybeHideIdentityAnimation();
   ToolbarButton::OnMouseExited(event);
 }
 
 void AvatarToolbarButton::OnBlur() {
-  if (identity_animation_state_ ==
-      IdentityAnimationState::kShowingUntilNoLongerHoveredOrFocused) {
-    HideIdentityAnimationWhenNotHoveredOrFocused();
-  }
+  MaybeHideIdentityAnimation();
   ToolbarButton::OnBlur();
 }
 
@@ -394,42 +399,51 @@
   PreferredSizeChanged();
 }
 
+void AvatarToolbarButton::OnHighlightChanged() {
+  DCHECK(parent_);
+  MaybeHideIdentityAnimation();
+}
+
 void AvatarToolbarButton::ShowIdentityAnimation() {
   DCHECK_EQ(identity_animation_state_,
             IdentityAnimationState::kWaitingForImage);
-  identity_animation_state_ = IdentityAnimationState::kShowing;
+  identity_animation_state_ = IdentityAnimationState::kShowingUntilTimeout;
 
   UpdateText();
 
   // Hide the pill after a while.
   base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
-      base::BindOnce(
-          &AvatarToolbarButton::HideIdentityAnimationWhenNotHoveredOrFocused,
-          weak_ptr_factory_.GetWeakPtr()),
+      base::BindOnce(&AvatarToolbarButton::OnIdentityAnimationTimeout,
+                     weak_ptr_factory_.GetWeakPtr()),
       kIdentityAnimationDuration);
 }
 
-void AvatarToolbarButton::HideIdentityAnimationWhenNotHoveredOrFocused() {
-  // No-op if it has been reset already.
-  if (identity_animation_state_ == IdentityAnimationState::kNotShowing)
-    return;
-
-  // Keep email visible while hovering or being focused.
-  if (IsMouseHovered() || HasFocus()) {
-    // TODO(crbug.com/967317): Include also the case when some other button from
-    // the parent container is shown and hovered / focused.
-    identity_animation_state_ =
-        IdentityAnimationState::kShowingUntilNoLongerHoveredOrFocused;
-    return;
-  }
-  HideIdentityAnimation();
+void AvatarToolbarButton::OnIdentityAnimationTimeout() {
+  DCHECK_EQ(identity_animation_state_,
+            IdentityAnimationState::kShowingUntilTimeout);
+  identity_animation_state_ =
+      IdentityAnimationState::kShowingUntilNoLongerInUse;
+  MaybeHideIdentityAnimation();
 }
 
-void AvatarToolbarButton::HideIdentityAnimation() {
-  DCHECK_NE(identity_animation_state_, IdentityAnimationState::kNotShowing);
-  identity_animation_state_ = IdentityAnimationState::kNotShowing;
+void AvatarToolbarButton::MaybeHideIdentityAnimation() {
+  // No-op if not showing or if the timeout hasn't passed, yet.
+  if (identity_animation_state_ !=
+      IdentityAnimationState::kShowingUntilNoLongerInUse) {
+    return;
+  }
 
+  // Keep identity visible if this button is in use (hovered or has focus) or
+  // if |parent_| is in use (which makes it highlighted). We should not move
+  // things around when the user wants to click on |this| or another button in
+  // |parent_|.
+  if (this->IsMouseHovered() || this->HasFocus() ||
+      (parent_ && parent_->IsHighlighted())) {
+    return;
+  }
+
+  identity_animation_state_ = IdentityAnimationState::kNotShowing;
   // Update the text to the pre-shown state. This also makes sure that we now
   // reflect changes that happened while the identity pill was shown.
   UpdateText();
@@ -530,9 +544,10 @@
     return State::kGenericProfile;
   }
 
-  if (identity_animation_state_ == IdentityAnimationState::kShowing ||
+  if (identity_animation_state_ ==
+          IdentityAnimationState::kShowingUntilTimeout ||
       identity_animation_state_ ==
-          IdentityAnimationState::kShowingUntilNoLongerHoveredOrFocused) {
+          IdentityAnimationState::kShowingUntilNoLongerInUse) {
     return State::kAnimatedUserIdentity;
   }
 
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button.h b/chrome/browser/ui/views/profiles/avatar_toolbar_button.h
index b3cbf7e..9868624a 100644
--- a/chrome/browser/ui/views/profiles/avatar_toolbar_button.h
+++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button.h
@@ -15,6 +15,7 @@
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_list_observer.h"
 #include "chrome/browser/ui/views/toolbar/toolbar_button.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
 #include "ui/base/material_design/material_design_controller.h"
 #include "ui/base/material_design/material_design_controller_observer.h"
@@ -27,9 +28,13 @@
                             public BrowserListObserver,
                             public ProfileAttributesStorage::Observer,
                             public signin::IdentityManager::Observer,
-                            public ui::MaterialDesignControllerObserver {
+                            public ui::MaterialDesignControllerObserver,
+                            ToolbarIconContainerView::Observer {
  public:
+  // TODO(crbug.com/922525): Remove this constructor when this button always has
+  // ToolbarIconContainerView as a parent.
   explicit AvatarToolbarButton(Browser* browser);
+  AvatarToolbarButton(Browser* browser, ToolbarIconContainerView* parent);
   ~AvatarToolbarButton() override;
 
   void UpdateIcon();
@@ -55,8 +60,8 @@
   enum class IdentityAnimationState {
     kNotShowing,
     kWaitingForImage,
-    kShowing,
-    kShowingUntilNoLongerHoveredOrFocused
+    kShowingUntilTimeout,
+    kShowingUntilNoLongerInUse
   };
 
   // ToolbarButton:
@@ -97,9 +102,12 @@
   // ui::MaterialDesignControllerObserver:
   void OnTouchUiChanged() override;
 
+  // ToolbarIconContainerView::Observer:
+  void OnHighlightChanged() override;
+
   void ShowIdentityAnimation();
-  void HideIdentityAnimationWhenNotHoveredOrFocused();
-  void HideIdentityAnimation();
+  void OnIdentityAnimationTimeout();
+  void MaybeHideIdentityAnimation();
 
   base::string16 GetAvatarTooltipText() const;
   base::string16 GetProfileName() const;
@@ -126,6 +134,7 @@
 
   Browser* const browser_;
   Profile* const profile_;
+  ToolbarIconContainerView* const parent_;
 
   // Whether the avatar highlight animation is visible. If true, hide avatar
   // button sync paused/error state and update highlight color.
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button_unittest.cc b/chrome/browser/ui/views/profiles/avatar_toolbar_button_unittest.cc
index a93e574..01c1b77 100644
--- a/chrome/browser/ui/views/profiles/avatar_toolbar_button_unittest.cc
+++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button_unittest.cc
@@ -8,6 +8,7 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/test_with_browser_view.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.h"
 #include "ui/base/theme_provider.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/views/widget/widget.h"
@@ -18,7 +19,8 @@
 #if !defined(OS_CHROMEOS)
 
 TEST_F(AvatarToolbarButtonTest, HighlightMeetsMinimumContrast) {
-  auto button = std::make_unique<AvatarToolbarButton>(browser());
+  auto parent = std::make_unique<ToolbarIconContainerView>(browser());
+  auto button = std::make_unique<AvatarToolbarButton>(browser(), parent.get());
   button->set_owned_by_client();
 
   browser_view()->GetWidget()->GetContentsView()->AddChildView(button.get());
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view.cc b/chrome/browser/ui/views/profiles/profile_menu_view.cc
index 04fb6bf..0cc9528 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view.cc
@@ -178,17 +178,17 @@
     BuildSyncInfo();
     BuildAccountFeatureButtons();
     BuildAutofillButtons();
-    BuildProfileFeatureButtons();
   } else if (profile->IsIncognitoProfile()) {
     BuildIncognitoIdentity();
-    BuildAutofillButtons();
-  } else {
-    DCHECK(profile->IsGuestSession());
+  } else if (profile->IsGuestSession()) {
     BuildGuestIdentity();
+  } else {
+    NOTREACHED();
   }
 
   BuildProfileHeading();
   BuildSelectableProfiles();
+  BuildProfileFeatureButtons();
 }
 
 void ProfileMenuView::OnAvatarMenuChanged(
@@ -517,27 +517,25 @@
     sync_ui_util::AvatarSyncErrorType error =
         sync_ui_util::GetMessagesForAvatarSyncError(
             browser()->profile(), &description_string_id, &button_string_id);
-    switch (error) {
-      case sync_ui_util::NO_SYNC_ERROR:
-        SetSyncInfo(
-            GetSyncIcon(),
-            /*description=*/base::string16(),
-            l10n_util::GetStringUTF16(IDS_SETTINGS_SYNC_ADVANCED_PAGE_TITLE),
-            base::BindRepeating(&ProfileMenuView::OnSyncSettingsButtonClicked,
-                                base::Unretained(this)));
-        break;
-      case sync_ui_util::MANAGED_USER_UNRECOVERABLE_ERROR:
-      case sync_ui_util::UNRECOVERABLE_ERROR:
-      case sync_ui_util::UPGRADE_CLIENT_ERROR:
-      case sync_ui_util::PASSPHRASE_ERROR:
-      case sync_ui_util::SETTINGS_UNCONFIRMED_ERROR:
-      case sync_ui_util::AUTH_ERROR:
-        SetSyncInfo(
-            GetSyncIcon(), l10n_util::GetStringUTF16(description_string_id),
-            l10n_util::GetStringUTF16(button_string_id),
-            base::BindRepeating(&ProfileMenuView::OnSyncErrorButtonClicked,
-                                base::Unretained(this), error));
-        break;
+
+    if (error == sync_ui_util::NO_SYNC_ERROR) {
+      SetSyncInfo(
+          GetSyncIcon(),
+          /*description=*/base::string16(),
+          l10n_util::GetStringUTF16(IDS_PROFILES_OPEN_SYNC_SETTINGS_BUTTON),
+          base::BindRepeating(&ProfileMenuView::OnSyncSettingsButtonClicked,
+                              base::Unretained(this)));
+    } else {
+      // Overwrite error description with short version for the menu.
+      description_string_id = (error == sync_ui_util::AUTH_ERROR)
+                                  ? IDS_PROFILES_DICE_SYNC_PAUSED_TITLE
+                                  : IDS_SYNC_ERROR_USER_MENU_TITLE;
+
+      SetSyncInfo(
+          GetSyncIcon(), l10n_util::GetStringUTF16(description_string_id),
+          l10n_util::GetStringUTF16(button_string_id),
+          base::BindRepeating(&ProfileMenuView::OnSyncErrorButtonClicked,
+                              base::Unretained(this), error));
     }
     return;
   }
@@ -594,7 +592,8 @@
 }
 
 void ProfileMenuView::BuildProfileHeading() {
-  SetProfileHeading(l10n_util::GetStringUTF16(IDS_PROFILES_OPTIONS_GROUP_NAME));
+  SetProfileHeading(
+      l10n_util::GetStringUTF16(IDS_PROFILES_OTHER_PROFILES_TITLE));
 }
 
 void ProfileMenuView::BuildSelectableProfiles() {
@@ -611,6 +610,14 @@
         base::BindRepeating(&ProfileMenuView::OnOtherProfileSelected,
                             base::Unretained(this), profile_entry->GetPath()));
   }
+
+  if (!browser()->profile()->IsGuestSession()) {
+    AddSelectableProfile(
+        profiles::GetGuestAvatar(),
+        l10n_util::GetStringUTF16(IDS_GUEST_PROFILE_NAME),
+        base::BindRepeating(&ProfileMenuView::OnGuestProfileButtonClicked,
+                            base::Unretained(this)));
+  }
 }
 
 void ProfileMenuView::BuildProfileFeatureButtons() {
@@ -621,12 +628,6 @@
                           base::Unretained(this)));
 
   AddProfileFeatureButton(
-      profiles::GetGuestAvatar(),
-      l10n_util::GetStringUTF16(IDS_GUEST_PROFILE_NAME),
-      base::BindRepeating(&ProfileMenuView::OnGuestProfileButtonClicked,
-                          base::Unretained(this)));
-
-  AddProfileFeatureButton(
       ImageForMenu(kAddIcon, /*icon_to_image_ratio=*/0.75),
       l10n_util::GetStringUTF16(IDS_ADD),
       base::BindRepeating(&ProfileMenuView::OnAddNewProfileButtonClicked,
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
index 360843d..3f61b4f 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
@@ -928,11 +928,13 @@
  public:
   // List of actionable items in the correct order as they appear in the menu.
   // If a new button is added to the menu, it should also be added to this list.
-  static constexpr ProfileMenuView::ActionableItem kOrderedActionableItems[2] =
-      {ProfileMenuView::ActionableItem::kOtherProfileButton,
+  static constexpr ProfileMenuView::ActionableItem kOrderedActionableItems[4] =
+      {ProfileMenuView::ActionableItem::kManageProfilesButton,
+       ProfileMenuView::ActionableItem::kOtherProfileButton,
+       ProfileMenuView::ActionableItem::kAddNewProfileButton,
        // The first button is added again to finish the cycle and test that
        // there are no other buttons at the end.
-       ProfileMenuView::ActionableItem::kOtherProfileButton};
+       ProfileMenuView::ActionableItem::kManageProfilesButton};
 
   ProfileMenuClickTest_GuestProfile() = default;
 
@@ -948,9 +950,7 @@
 constexpr ProfileMenuView::ActionableItem
     ProfileMenuClickTest_GuestProfile::kOrderedActionableItems[];
 
-// TODO(crbug.com/1012167): Flaky.
-IN_PROC_BROWSER_TEST_P(ProfileMenuClickTest_GuestProfile,
-                       DISABLED_SetupAndRunTest) {
+IN_PROC_BROWSER_TEST_P(ProfileMenuClickTest_GuestProfile, SetupAndRunTest) {
   profiles::SwitchToGuestProfile(ProfileManager::CreateCallback());
   ui_test_utils::WaitForBrowserToOpen();
   Profile* guest = g_browser_process->profile_manager()->GetProfileByPath(
diff --git a/chrome/browser/ui/views/profiles/user_manager_view.cc b/chrome/browser/ui/views/profiles/user_manager_view.cc
index 41d414d..2d4b0178 100644
--- a/chrome/browser/ui/views/profiles/user_manager_view.cc
+++ b/chrome/browser/ui/views/profiles/user_manager_view.cc
@@ -68,6 +68,8 @@
     const std::string& email_address,
     const GURL& url)
     : parent_(parent), web_view_(web_view), email_address_(email_address) {
+  DialogDelegate::set_use_custom_frame(false);
+
   AddChildView(web_view_);
   SetLayoutManager(std::make_unique<views::FillLayout>());
 
@@ -99,10 +101,6 @@
   return true;
 }
 
-bool UserManagerProfileDialogDelegate::ShouldUseCustomFrame() const {
-  return false;
-}
-
 ui::ModalType UserManagerProfileDialogDelegate::GetModalType() const {
   return ui::MODAL_TYPE_WINDOW;
 }
@@ -300,6 +298,7 @@
     : web_view_(nullptr),
       delegate_(nullptr),
       user_manager_started_showing_(base::Time()) {
+  DialogDelegate::set_use_custom_frame(false);
   keep_alive_ = std::make_unique<ScopedKeepAlive>(
       KeepAliveOrigin::USER_MANAGER_VIEW, KeepAliveRestartOption::DISABLED);
   chrome::RecordDialogCreation(chrome::DialogIdentifier::USER_MANAGER);
@@ -473,10 +472,6 @@
     g_user_manager_view = nullptr;
 }
 
-bool UserManagerView::ShouldUseCustomFrame() const {
-  return false;
-}
-
 void UserManagerView::DisplayErrorMessage() {
   if (delegate_)
     delegate_->DisplayErrorMessage();
diff --git a/chrome/browser/ui/views/profiles/user_manager_view.h b/chrome/browser/ui/views/profiles/user_manager_view.h
index e96b370..4524cc9 100644
--- a/chrome/browser/ui/views/profiles/user_manager_view.h
+++ b/chrome/browser/ui/views/profiles/user_manager_view.h
@@ -48,7 +48,6 @@
   bool CanResize() const override;
   bool CanMaximize() const override;
   bool CanMinimize() const override;
-  bool ShouldUseCustomFrame() const override;
   ui::ModalType GetModalType() const override;
   void DeleteDelegate() override;
   base::string16 GetWindowTitle() const override;
@@ -128,7 +127,6 @@
   base::string16 GetWindowTitle() const override;
   int GetDialogButtons() const override;
   void WindowClosing() override;
-  bool ShouldUseCustomFrame() const override;
 
   views::WebView* web_view_;
 
diff --git a/chrome/browser/ui/views/sharing/sharing_dialog_view.cc b/chrome/browser/ui/views/sharing/sharing_dialog_view.cc
index ff7805f..80d5739 100644
--- a/chrome/browser/ui/views/sharing/sharing_dialog_view.cc
+++ b/chrome/browser/ui/views/sharing/sharing_dialog_view.cc
@@ -75,14 +75,29 @@
       time_in_days);
 }
 
+std::unique_ptr<views::StyledLabel> CreateHelpText(
+    const SharingDialogData& data,
+    views::StyledLabelListener* listener) {
+  DCHECK_NE(0, data.help_text_id);
+  DCHECK_NE(0, data.help_link_text_id);
+  const base::string16 link = l10n_util::GetStringUTF16(data.help_link_text_id);
+  size_t offset;
+  const base::string16 text =
+      l10n_util::GetStringFUTF16(data.help_text_id, link, &offset);
+  auto label = std::make_unique<views::StyledLabel>(text, listener);
+  views::StyledLabel::RangeStyleInfo link_style =
+      views::StyledLabel::RangeStyleInfo::CreateForLink();
+  label->AddStyleRange(gfx::Range(offset, offset + link.length()), link_style);
+  return label;
+}
+
 }  // namespace
 
 SharingDialogView::SharingDialogView(views::View* anchor_view,
                                      content::WebContents* web_contents,
-                                     SharingUiController* controller)
+                                     SharingDialogData data)
     : LocationBarBubbleDelegateView(anchor_view, web_contents),
-      controller_(controller),
-      send_failed_(controller->HasSendFailed()) {}
+      data_(std::move(data)) {}
 
 SharingDialogView::~SharingDialogView() = default;
 
@@ -90,11 +105,6 @@
   CloseBubble();
 }
 
-std::unique_ptr<views::StyledLabel> SharingDialogView::CreateHelpText(
-    views::StyledLabelListener* listener) {
-  return controller_->GetHelpTextLabel(listener);
-}
-
 int SharingDialogView::GetDialogButtons() const {
   return ui::DIALOG_BUTTON_NONE;
 }
@@ -103,27 +113,18 @@
   if (GetDialogType() != SharingDialogType::kDialogWithoutDevicesWithApp)
     return nullptr;
 
-  return CreateHelpText(this);
+  return CreateHelpText(data_, this);
 }
 
 void SharingDialogView::StyledLabelLinkClicked(views::StyledLabel* label,
                                                const gfx::Range& range,
                                                int event_flags) {
-  controller_->OnHelpTextClicked(GetDialogType());
+  std::move(data_.help_callback).Run(GetDialogType());
+  CloseBubble();
 }
 
 SharingDialogType SharingDialogView::GetDialogType() const {
-  if (send_failed_)
-    return SharingDialogType::kErrorDialog;
-
-  bool has_devices = !controller_->devices().empty();
-  bool has_apps = !controller_->apps().empty();
-
-  if (has_devices)
-    return SharingDialogType::kDialogWithDevicesMaybeApps;
-
-  return has_apps ? SharingDialogType::kDialogWithoutDevicesWithApp
-                  : SharingDialogType::kEducationalDialog;
+  return data_.type;
 }
 
 void SharingDialogView::Init() {
@@ -136,7 +137,7 @@
       provider->GetDialogInsetsForContentType(views::TEXT, views::TEXT);
 
   SharingDialogType type = GetDialogType();
-  LogSharingDialogShown(controller_->GetFeatureMetricsPrefix(), type);
+  LogSharingDialogShown(data_.prefix, type);
 
   switch (type) {
     case SharingDialogType::kErrorDialog:
@@ -166,28 +167,25 @@
 
 void SharingDialogView::ButtonPressed(views::Button* sender,
                                       const ui::Event& event) {
+  DCHECK(data_.device_callback);
+  DCHECK(data_.app_callback);
   if (!sender || sender->tag() < 0)
     return;
   size_t index = static_cast<size_t>(sender->tag());
-  const std::vector<std::unique_ptr<syncer::DeviceInfo>>& devices =
-      controller_->devices();
-  const std::vector<SharingApp>& apps = controller_->apps();
-  DCHECK(index < devices.size() + apps.size());
+  DCHECK(index < data_.devices.size() + data_.apps.size());
 
-  if (index < devices.size()) {
-    LogSharingSelectedDeviceIndex(controller_->GetFeatureMetricsPrefix(),
-                                  kSharingUiDialog, index);
-    controller_->OnDeviceChosen(*devices[index]);
+  if (index < data_.devices.size()) {
+    LogSharingSelectedDeviceIndex(data_.prefix, kSharingUiDialog, index);
+    std::move(data_.device_callback).Run(*data_.devices[index]);
     CloseBubble();
     return;
   }
 
-  index -= devices.size();
+  index -= data_.devices.size();
 
-  if (index < apps.size()) {
-    LogSharingSelectedAppIndex(controller_->GetFeatureMetricsPrefix(),
-                               kSharingUiDialog, index);
-    controller_->OnAppChosen(apps[index]);
+  if (index < data_.apps.size()) {
+    LogSharingSelectedAppIndex(data_.prefix, kSharingUiDialog, index);
+    std::move(data_.app_callback).Run(data_.apps[index]);
     CloseBubble();
   }
 }
@@ -197,7 +195,9 @@
   if (!frame_view)
     return;
 
-  int image_id = controller_->GetHeaderImageId();
+  int image_id = GetNativeTheme()->ShouldUseDarkColors()
+                     ? data_.header_image_dark
+                     : data_.header_image_light;
   if (!image_id) {
     // Clear any previously set header image.
     frame_view->SetHeaderView(nullptr);
@@ -229,33 +229,26 @@
   if (!button_icons_.size())
     return;
 
-  const std::vector<std::unique_ptr<syncer::DeviceInfo>>& devices =
-      controller_->devices();
-  const std::vector<SharingApp>& apps = controller_->apps();
-  DCHECK_EQ(devices.size() + apps.size(), button_icons_.size());
+  DCHECK_EQ(data_.devices.size() + data_.apps.size(), button_icons_.size());
 
   size_t button_index = 0;
-  for (const auto& device : devices) {
+  for (const auto& device : data_.devices) {
     button_icons_[button_index]->SetImage(
         CreateDeviceIcon(device->device_type()));
     button_index++;
   }
-  for (const auto& app : apps) {
+  for (const auto& app : data_.apps) {
     button_icons_[button_index]->SetImage(CreateAppIcon(app));
     button_index++;
   }
 }
 
 void SharingDialogView::InitListView() {
-  const std::vector<std::unique_ptr<syncer::DeviceInfo>>& devices =
-      controller_->devices();
-  const std::vector<SharingApp>& apps = controller_->apps();
   int tag = 0;
 
   // Devices:
-  LogSharingDevicesToShow(controller_->GetFeatureMetricsPrefix(),
-                          kSharingUiDialog, devices.size());
-  for (const auto& device : devices) {
+  LogSharingDevicesToShow(data_.prefix, kSharingUiDialog, data_.devices.size());
+  for (const auto& device : data_.devices) {
     auto icon = CreateIconView(CreateDeviceIcon(device->device_type()));
     button_icons_.push_back(icon.get());
     auto dialog_button = std::make_unique<HoverButton>(
@@ -267,9 +260,8 @@
   }
 
   // Apps:
-  LogSharingAppsToShow(controller_->GetFeatureMetricsPrefix(), kSharingUiDialog,
-                       apps.size());
-  for (const auto& app : apps) {
+  LogSharingAppsToShow(data_.prefix, kSharingUiDialog, data_.apps.size());
+  for (const auto& app : data_.apps) {
     auto icon = CreateIconView(CreateAppIcon(app));
     button_icons_.push_back(icon.get());
     auto dialog_button =
@@ -282,11 +274,11 @@
 }
 
 void SharingDialogView::InitEmptyView() {
-  AddChildView(CreateHelpText(this));
+  AddChildView(CreateHelpText(data_, this));
 }
 
 void SharingDialogView::InitErrorView() {
-  auto label = std::make_unique<views::Label>(controller_->GetErrorDialogText(),
+  auto label = std::make_unique<views::Label>(data_.error_text,
                                               views::style::CONTEXT_LABEL,
                                               views::style::STYLE_SECONDARY);
   label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
@@ -305,20 +297,19 @@
 }
 
 base::string16 SharingDialogView::GetWindowTitle() const {
-  switch (GetDialogType()) {
-    case SharingDialogType::kErrorDialog:
-      return controller_->GetErrorDialogTitle();
-    case SharingDialogType::kEducationalDialog:
-      return controller_->GetEducationWindowTitleText();
-    case SharingDialogType::kDialogWithoutDevicesWithApp:
-    case SharingDialogType::kDialogWithDevicesMaybeApps:
-      return controller_->GetTitle();
-  }
+  return data_.title;
+}
+
+void SharingDialogView::WebContentsDestroyed() {
+  LocationBarBubbleDelegateView::WebContentsDestroyed();
+  // Call the close callback here already so we can log metrics for closed
+  // dialogs before the controller is destroyed.
+  WindowClosing();
 }
 
 void SharingDialogView::WindowClosing() {
-  if (web_contents())
-    controller_->OnDialogClosed(this);
+  if (data_.close_callback)
+    std::move(data_.close_callback).Run(this);
 }
 
 // static
diff --git a/chrome/browser/ui/views/sharing/sharing_dialog_view.h b/chrome/browser/ui/views/sharing/sharing_dialog_view.h
index cf75b7a..15b55a7 100644
--- a/chrome/browser/ui/views/sharing/sharing_dialog_view.h
+++ b/chrome/browser/ui/views/sharing/sharing_dialog_view.h
@@ -9,7 +9,7 @@
 #include <vector>
 
 #include "chrome/browser/sharing/sharing_dialog.h"
-#include "chrome/browser/sharing/sharing_ui_controller.h"
+#include "chrome/browser/sharing/sharing_dialog_data.h"
 #include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/styled_label_listener.h"
@@ -20,7 +20,6 @@
 class View;
 }  // namespace views
 
-class Browser;
 class HoverButton;
 enum class SharingDialogType;
 
@@ -32,7 +31,7 @@
   // Bubble will be anchored to |anchor_view|.
   SharingDialogView(views::View* anchor_view,
                     content::WebContents* web_contents,
-                    SharingUiController* controller);
+                    SharingDialogData data);
 
   ~SharingDialogView() override;
 
@@ -43,6 +42,7 @@
   bool ShouldShowCloseButton() const override;
   base::string16 GetWindowTitle() const override;
   void WindowClosing() override;
+  void WebContentsDestroyed() override;
   int GetDialogButtons() const override;
   std::unique_ptr<views::View> CreateFootnoteView() override;
   gfx::Size CalculatePreferredSize() const override;
@@ -58,8 +58,6 @@
   void ButtonPressed(views::Button* sender, const ui::Event& event) override;
 
   static views::BubbleDialogDelegateView* GetAsBubble(SharingDialog* dialog);
-  std::unique_ptr<views::StyledLabel> CreateHelpText(
-      views::StyledLabelListener* listener);
 
  private:
   friend class SharingDialogViewTest;
@@ -83,13 +81,12 @@
   // Populates the dialog view containing error help text.
   void InitErrorView();
 
-  SharingUiController* controller_ = nullptr;
+  SharingDialogData data_;
+
   // References to device and app buttons views.
   std::vector<HoverButton*> dialog_buttons_;
   // References to device and app button icons.
   std::vector<views::ImageView*> button_icons_;
-  Browser* browser_ = nullptr;
-  bool send_failed_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(SharingDialogView);
 };
diff --git a/chrome/browser/ui/views/sharing/sharing_dialog_view_unittest.cc b/chrome/browser/ui/views/sharing/sharing_dialog_view_unittest.cc
index 576ad26..3779374 100644
--- a/chrome/browser/ui/views/sharing/sharing_dialog_view_unittest.cc
+++ b/chrome/browser/ui/views/sharing/sharing_dialog_view_unittest.cc
@@ -4,46 +4,31 @@
 
 #include "chrome/browser/ui/views/sharing/sharing_dialog_view.h"
 
-#include <map>
 #include <memory>
 #include <string>
 
 #include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/simple_test_clock.h"
-#include "chrome/browser/sharing/click_to_call/click_to_call_ui_controller.h"
+#include "base/test/bind_test_util.h"
 #include "chrome/browser/sharing/sharing_app.h"
 #include "chrome/browser/sharing/sharing_metrics.h"
 #include "chrome/browser/ui/views/hover_button.h"
-#include "chrome/test/base/testing_profile.h"
 #include "chrome/test/views/chrome_views_test_base.h"
-#include "components/send_tab_to_self/target_device_info.h"
 #include "components/sync_device_info/device_info.h"
 #include "components/vector_icons/vector_icons.h"
-#include "content/public/test/web_contents_tester.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/events/event_utils.h"
+#include "ui/strings/grit/ui_strings.h"
 
 namespace {
 
-class ClickToCallUiControllerMock : public ClickToCallUiController {
- public:
-  explicit ClickToCallUiControllerMock(content::WebContents* web_contents)
-      : ClickToCallUiController(web_contents) {}
-  ~ClickToCallUiControllerMock() override = default;
-
-  MOCK_METHOD1(OnDeviceChosen, void(const syncer::DeviceInfo& device));
-  MOCK_METHOD1(OnAppChosen, void(const SharingApp& app));
-  MOCK_METHOD1(OnHelpTextClicked, void(SharingDialogType dialog_type));
-};
-
 class SharingDialogViewMock : public SharingDialogView {
  public:
   SharingDialogViewMock(views::View* anchor_view,
                         content::WebContents* web_contents,
-                        ClickToCallUiController* controller)
-      : SharingDialogView(anchor_view, web_contents, controller) {}
+                        SharingDialogData data)
+      : SharingDialogView(anchor_view, web_contents, std::move(data)) {}
   ~SharingDialogViewMock() override = default;
 
   // The delegate cannot find widget since it is created from a null profile.
@@ -67,19 +52,12 @@
   void SetUp() override {
     ChromeViewsTestBase::SetUp();
 
-    profile_ = std::make_unique<TestingProfile>();
-    web_contents_ = content::WebContentsTester::CreateTestWebContents(
-        profile_.get(), nullptr);
-
     // Create an anchor for the bubble.
     views::Widget::InitParams params =
         CreateParams(views::Widget::InitParams::TYPE_WINDOW);
     params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
     anchor_widget_ = std::make_unique<views::Widget>();
     anchor_widget_->Init(std::move(params));
-
-    controller_ =
-        std::make_unique<ClickToCallUiControllerMock>(web_contents_.get());
   }
 
   void TearDown() override {
@@ -112,25 +90,55 @@
     return apps;
   }
 
-  std::unique_ptr<SharingDialogView> CreateDialogView(int devices, int apps) {
-    controller_->set_devices_for_testing(CreateDevices(devices));
-    controller_->set_apps_for_testing(CreateApps(apps));
-
+  std::unique_ptr<SharingDialogView> CreateDialogView(
+      SharingDialogData dialog_data) {
     auto dialog = std::make_unique<SharingDialogViewMock>(
         anchor_widget_->GetContentsView(), /*web_contents=*/nullptr,
-        controller_.get());
+        std::move(dialog_data));
     dialog->Init();
     return dialog;
   }
 
-  std::unique_ptr<TestingProfile> profile_;
-  std::unique_ptr<content::WebContents> web_contents_;
+  SharingDialogData CreateDialogData(int devices, int apps) {
+    SharingDialogData data;
+
+    if (devices)
+      data.type = SharingDialogType::kDialogWithDevicesMaybeApps;
+    else if (apps)
+      data.type = SharingDialogType::kDialogWithoutDevicesWithApp;
+    else
+      data.type = SharingDialogType::kEducationalDialog;
+
+    data.prefix = SharingFeatureName::kClickToCall;
+    data.devices = CreateDevices(devices);
+    data.apps = CreateApps(apps);
+
+    data.help_text_id =
+        IDS_BROWSER_SHARING_CLICK_TO_CALL_DIALOG_HELP_TEXT_NO_DEVICES;
+    data.help_link_text_id =
+        IDS_BROWSER_SHARING_CLICK_TO_CALL_DIALOG_TROUBLESHOOT_LINK;
+
+    data.help_callback = base::BindLambdaForTesting(
+        [&](SharingDialogType type) { help_callback.Call(type); });
+    data.device_callback =
+        base::BindLambdaForTesting([&](const syncer::DeviceInfo& device) {
+          device_callback.Call(device);
+        });
+    data.app_callback = base::BindLambdaForTesting(
+        [&](const SharingApp& app) { app_callback.Call(app); });
+
+    return data;
+  }
+
   std::unique_ptr<views::Widget> anchor_widget_;
-  std::unique_ptr<ClickToCallUiControllerMock> controller_;
+  testing::MockFunction<void(SharingDialogType)> help_callback;
+  testing::MockFunction<void(const syncer::DeviceInfo&)> device_callback;
+  testing::MockFunction<void(const SharingApp&)> app_callback;
 };
 
 TEST_F(SharingDialogViewTest, PopulateDialogView) {
-  auto dialog = CreateDialogView(/*devices=*/3, /*apps=*/2);
+  auto dialog_data = CreateDialogData(/*devices=*/3, /*apps=*/2);
+  auto dialog = CreateDialogView(std::move(dialog_data));
 
   EXPECT_EQ(5UL, dialog->dialog_buttons_.size());
 }
@@ -142,9 +150,10 @@
       /*last_updated_timestamp=*/base::Time::Now(),
       /*send_tab_to_self_receiving_enabled=*/false,
       /*sharing_info=*/base::nullopt);
-  EXPECT_CALL(*controller_.get(), OnDeviceChosen(DeviceEquals(&device_info)));
+  EXPECT_CALL(device_callback, Call(DeviceEquals(&device_info)));
 
-  auto dialog = CreateDialogView(/*devices=*/3, /*apps=*/2);
+  auto dialog_data = CreateDialogData(/*devices=*/3, /*apps=*/2);
+  auto dialog = CreateDialogView(std::move(dialog_data));
 
   const ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
                              ui::EventTimeForNow(), 0, 0);
@@ -156,9 +165,10 @@
 TEST_F(SharingDialogViewTest, AppPressed) {
   SharingApp app(&vector_icons::kOpenInNewIcon, gfx::Image(),
                  base::UTF8ToUTF16("app0"), std::string());
-  EXPECT_CALL(*controller_.get(), OnAppChosen(AppEquals(&app)));
+  EXPECT_CALL(app_callback, Call(AppEquals(&app)));
 
-  auto dialog = CreateDialogView(/*devices=*/3, /*apps=*/2);
+  auto dialog_data = CreateDialogData(/*devices=*/3, /*apps=*/2);
+  auto dialog = CreateDialogView(std::move(dialog_data));
 
   const ui::MouseEvent event(ui::ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
                              ui::EventTimeForNow(), 0, 0);
@@ -169,30 +179,30 @@
 }
 
 TEST_F(SharingDialogViewTest, HelpTextClickedEmpty) {
-  EXPECT_CALL(*controller_.get(),
-              OnHelpTextClicked(SharingDialogType::kEducationalDialog));
+  EXPECT_CALL(help_callback, Call(SharingDialogType::kEducationalDialog));
 
-  auto dialog = CreateDialogView(/*devices=*/0, /*apps=*/0);
+  auto dialog_data = CreateDialogData(/*devices=*/0, /*apps=*/0);
+  auto dialog = CreateDialogView(std::move(dialog_data));
 
   dialog->StyledLabelLinkClicked(/*label=*/nullptr, /*range=*/{},
                                  /*event_flags=*/0);
 }
 
 TEST_F(SharingDialogViewTest, HelpTextClickedOnlyApps) {
-  EXPECT_CALL(
-      *controller_.get(),
-      OnHelpTextClicked(SharingDialogType::kDialogWithoutDevicesWithApp));
+  EXPECT_CALL(help_callback,
+              Call(SharingDialogType::kDialogWithoutDevicesWithApp));
 
-  auto dialog = CreateDialogView(/*devices=*/0, /*apps=*/1);
+  auto dialog_data = CreateDialogData(/*devices=*/0, /*apps=*/1);
+  auto dialog = CreateDialogView(std::move(dialog_data));
 
   dialog->StyledLabelLinkClicked(/*label=*/nullptr, /*range=*/{},
                                  /*event_flags=*/0);
 }
 
 TEST_F(SharingDialogViewTest, ThemeChangedEmptyList) {
-  controller_->set_send_result_for_testing(
-      SharingSendMessageResult::kDeviceNotFound);
-  auto dialog = CreateDialogView(/*devices=*/1, /*apps=*/1);
+  auto dialog_data = CreateDialogData(/*devices=*/1, /*apps=*/1);
+  dialog_data.type = SharingDialogType::kErrorDialog;
+  auto dialog = CreateDialogView(std::move(dialog_data));
 
   EXPECT_EQ(SharingDialogType::kErrorDialog, dialog->GetDialogType());
 
diff --git a/chrome/browser/ui/views/task_manager_view.cc b/chrome/browser/ui/views/task_manager_view.cc
index e1067bd..03955be 100644
--- a/chrome/browser/ui/views/task_manager_view.cc
+++ b/chrome/browser/ui/views/task_manager_view.cc
@@ -241,10 +241,6 @@
   table_model_->StoreColumnsSettings();
 }
 
-bool TaskManagerView::ShouldUseCustomFrame() const {
-  return false;
-}
-
 void TaskManagerView::GetGroupRange(int model_index, views::GroupRange* range) {
   table_model_->GetRowsGroupRange(model_index, &range->start, &range->length);
 }
@@ -301,6 +297,7 @@
     : tab_table_(nullptr),
       tab_table_parent_(nullptr),
       is_always_on_top_(false) {
+  DialogDelegate::set_use_custom_frame(false);
   Init();
   chrome::RecordDialogCreation(chrome::DialogIdentifier::TASK_MANAGER);
 }
diff --git a/chrome/browser/ui/views/task_manager_view.h b/chrome/browser/ui/views/task_manager_view.h
index 822e31b..502197766 100644
--- a/chrome/browser/ui/views/task_manager_view.h
+++ b/chrome/browser/ui/views/task_manager_view.h
@@ -68,7 +68,6 @@
   base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
   bool IsDialogButtonEnabled(ui::DialogButton button) const override;
   void WindowClosing() override;
-  bool ShouldUseCustomFrame() const override;
 
   // views::TableGrouper:
   void GetGroupRange(int model_index, views::GroupRange* range) override;
diff --git a/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.cc b/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.cc
index 9fcf99a..1eb66b4 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_account_icon_container_view.cc
@@ -24,7 +24,7 @@
     Browser* browser)
     : ToolbarIconContainerView(
           /*uses_highlight=*/!browser->profile()->IsIncognitoProfile()),
-      avatar_(new AvatarToolbarButton(browser)),
+      avatar_(new AvatarToolbarButton(browser, this)),
       browser_(browser) {
   PageActionIconContainerView::Params params;
   params.types_enabled = {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc
index 26fa472..7cb442b2 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.cc
@@ -41,6 +41,14 @@
   AddChildView(main_button_);
 }
 
+void ToolbarIconContainerView::AddObserver(Observer* obs) {
+  observers_.AddObserver(obs);
+}
+
+void ToolbarIconContainerView::RemoveObserver(const Observer* obs) {
+  observers_.RemoveObserver(obs);
+}
+
 void ToolbarIconContainerView::OnHighlightChanged(
     views::Button* observed_button,
     bool highlighted) {
@@ -115,11 +123,22 @@
 }
 
 void ToolbarIconContainerView::UpdateHighlight() {
+  bool showing_before = highlight_animation_.IsShowing();
+
   if (ShouldDisplayHighlight()) {
     highlight_animation_.Show();
   } else {
     highlight_animation_.Hide();
   }
+
+  if (showing_before == highlight_animation_.IsShowing())
+    return;
+  for (Observer& observer : observers_)
+    observer.OnHighlightChanged();
+}
+
+bool ToolbarIconContainerView::IsHighlighted() {
+  return ShouldDisplayHighlight();
 }
 
 void ToolbarIconContainerView::SetHighlightBorder() {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h
index 4f228b8e..755e16c 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h
+++ b/chrome/browser/ui/views/toolbar/toolbar_icon_container_view.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_VIEWS_TOOLBAR_TOOLBAR_ICON_CONTAINER_VIEW_H_
 
 #include "base/macros.h"
+#include "base/observer_list.h"
 #include "ui/gfx/animation/animation_delegate.h"
 #include "ui/views/controls/button/button.h"
 #include "ui/views/controls/button/button_observer.h"
@@ -17,6 +18,11 @@
                                  public views::ButtonObserver,
                                  public views::ViewObserver {
  public:
+  class Observer : public base::CheckedObserver {
+   public:
+    virtual void OnHighlightChanged() = 0;
+  };
+
   explicit ToolbarIconContainerView(bool uses_highlight);
   ~ToolbarIconContainerView() override;
 
@@ -26,6 +32,11 @@
   // Adds the RHS child as well as setting its margins.
   void AddMainButton(views::Button* main_button);
 
+  void AddObserver(Observer* obs);
+  void RemoveObserver(const Observer* obs);
+
+  bool IsHighlighted();
+
   // views::ButtonObserver:
   void OnHighlightChanged(views::Button* observed_button,
                           bool highlighted) override;
@@ -68,6 +79,8 @@
   // Fade-in/out animation for the highlight border.
   gfx::SlideAnimation highlight_animation_{this};
 
+  base::ObserverList<Observer> observers_;
+
   DISALLOW_COPY_AND_ASSIGN(ToolbarIconContainerView);
 };
 
diff --git a/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc b/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc
index b37722fe..6f05880e 100644
--- a/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc
+++ b/chrome/browser/ui/web_applications/test/web_app_browsertest_util.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/web_applications/components/web_app_tab_helper.h"
 #include "chrome/common/web_application_info.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 
 namespace web_app {
 
@@ -76,7 +77,8 @@
 
 ExternalInstallOptions CreateInstallOptions(const GURL& url) {
   ExternalInstallOptions install_options(
-      url, LaunchContainer::kWindow, ExternalInstallSource::kInternalDefault);
+      url, blink::mojom::DisplayMode::kStandalone,
+      ExternalInstallSource::kInternalDefault);
   // Avoid creating real shortcuts in tests.
   install_options.add_to_applications_menu = false;
   install_options.add_to_desktop = false;
diff --git a/chrome/browser/ui/webui/settings/profile_info_handler.cc b/chrome/browser/ui/webui/settings/profile_info_handler.cc
index ec91b3e..acacc20 100644
--- a/chrome/browser/ui/webui/settings/profile_info_handler.cc
+++ b/chrome/browser/ui/webui/settings/profile_info_handler.cc
@@ -152,7 +152,10 @@
   if (g_browser_process->profile_manager()
           ->GetProfileAttributesStorage()
           .GetProfileAttributesWithPath(profile_->GetPath(), &entry)) {
-    name = base::UTF16ToUTF8(entry->GetName());
+    name = base::UTF16ToUTF8(
+        base::FeatureList::IsEnabled(kConcatenateGaiaAndProfileName)
+            ? entry->GetLocalProfileName()
+            : entry->GetName());
     // TODO(crbug.com/710660): return chrome://theme/IDR_PROFILE_AVATAR_*
     // and update theme_source.cc to get high res avatar icons. This does less
     // work here, sends less over IPC, and is more stable with returned results.
diff --git a/chrome/browser/ui/webui/sync_internals_ui.cc b/chrome/browser/ui/webui/sync_internals_ui.cc
index d4d1835..ed5f6af 100644
--- a/chrome/browser/ui/webui/sync_internals_ui.cc
+++ b/chrome/browser/ui/webui/sync_internals_ui.cc
@@ -9,7 +9,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/webui/sync_internals_message_handler.h"
 #include "chrome/common/url_constants.h"
-#include "components/grit/components_resources.h"
+#include "components/grit/sync_driver_resources.h"
 #include "components/sync/driver/about_sync_util.h"
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn
index ef657e95..45a661d 100644
--- a/chrome/browser/vr/BUILD.gn
+++ b/chrome/browser/vr/BUILD.gn
@@ -243,7 +243,6 @@
     "service/browser_xr_runtime.h",
     "service/gvr_consent_helper.cc",
     "service/gvr_consent_helper.h",
-    "service/interface_set.h",
     "service/vr_service_impl.cc",
     "service/vr_service_impl.h",
     "service/xr_device_service.cc",
diff --git a/chrome/browser/vr/service/browser_xr_runtime.cc b/chrome/browser/vr/service/browser_xr_runtime.cc
index a3c1889..68976a88 100644
--- a/chrome/browser/vr/service/browser_xr_runtime.cc
+++ b/chrome/browser/vr/service/browser_xr_runtime.cc
@@ -372,7 +372,7 @@
 
 void BrowserXRRuntime::StopImmersiveSession() {
   if (immersive_session_controller_) {
-    immersive_session_controller_ = nullptr;
+    immersive_session_controller_.reset();
     presenting_service_ = nullptr;
 
     for (BrowserXRRuntimeObserver& observer : observers_) {
@@ -471,12 +471,14 @@
     device::mojom::XRRuntimeSessionOptionsPtr options,
     RequestSessionCallback callback,
     device::mojom::XRSessionPtr session,
-    device::mojom::XRSessionControllerPtr immersive_session_controller) {
+    mojo::PendingRemote<device::mojom::XRSessionController>
+        immersive_session_controller) {
   if (session && service) {
     if (options->immersive) {
       presenting_service_ = service.get();
-      immersive_session_controller_ = std::move(immersive_session_controller);
-      immersive_session_controller_.set_connection_error_handler(base::BindOnce(
+      immersive_session_controller_.Bind(
+          std::move(immersive_session_controller));
+      immersive_session_controller_.set_disconnect_handler(base::BindOnce(
           &BrowserXRRuntime::OnImmersiveSessionError, base::Unretained(this)));
 
       // Notify observers that we have started presentation.
@@ -492,7 +494,8 @@
     if (session) {
       // The service has been removed, but we still got a session, so make
       // sure to clean up this weird state.
-      immersive_session_controller_ = std::move(immersive_session_controller);
+      immersive_session_controller_.Bind(
+          std::move(immersive_session_controller));
       StopImmersiveSession();
     }
   }
diff --git a/chrome/browser/vr/service/browser_xr_runtime.h b/chrome/browser/vr/service/browser_xr_runtime.h
index 40988995..5c694358 100644
--- a/chrome/browser/vr/service/browser_xr_runtime.h
+++ b/chrome/browser/vr/service/browser_xr_runtime.h
@@ -15,6 +15,8 @@
 #include "device/vr/public/mojom/vr_service.mojom.h"
 #include "device/vr/vr_device.h"
 #include "mojo/public/cpp/bindings/associated_binding.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
 
 namespace content {
 class WebContents;
@@ -111,13 +113,15 @@
       device::mojom::XRRuntimeSessionOptionsPtr options,
       RequestSessionCallback callback,
       device::mojom::XRSessionPtr session,
-      device::mojom::XRSessionControllerPtr immersive_session_controller);
+      mojo::PendingRemote<device::mojom::XRSessionController>
+          immersive_session_controller);
   void OnImmersiveSessionError();
   void OnInitialized();
 
   device::mojom::XRDeviceId id_;
   device::mojom::XRRuntimePtr runtime_;
-  device::mojom::XRSessionControllerPtr immersive_session_controller_;
+  mojo::Remote<device::mojom::XRSessionController>
+      immersive_session_controller_;
 
   std::set<VRServiceImpl*> services_;
   device::mojom::VRDisplayInfoPtr display_info_;
diff --git a/chrome/browser/vr/service/interface_set.h b/chrome/browser/vr/service/interface_set.h
deleted file mode 100644
index 4a0d5adb..0000000
--- a/chrome/browser/vr/service/interface_set.h
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_VR_SERVICE_INTERFACE_SET_H_
-#define CHROME_BROWSER_VR_SERVICE_INTERFACE_SET_H_
-
-#include <set>
-
-#include "base/bind.h"
-#include "base/callback.h"
-
-namespace vr {
-
-// Class used to store mojo InterfacePtrs. It will auto-manage its contents
-// (ex. on connection error, the InterfacePtr will be removed from the set).
-// The class is heavily based on mojo::InterfacePtrSet, but because
-// mojo::InterfacePtrSet does not notify on removal of the interface from the
-// collection, it cannot be used for some of the scenarios.
-// TODO(https://crbug.com/965668) - remove this class and use InterfacePtrSet
-// once it starts exposing required functionality.
-template <typename InterfacePtr>
-class InterfaceSet {
- public:
-  ~InterfaceSet() {
-    for (auto& it : interface_ptrs_) {
-      it.second.reset();
-    }
-  }
-
-  // Add |interface_ptr| to the set. Returns id that can be used to identify
-  // added pointer. The error handler that might have been registered on
-  // |interface_ptr| will be replaced. Instead, to get notified on connection
-  // error, please register a connection error handler with InterfaceSet.
-  size_t AddPtr(InterfacePtr interface_ptr) {
-    size_t id = next_id_++;
-
-    auto it = interface_ptrs_.emplace(id, std::move(interface_ptr));
-    it.first->second.set_connection_error_handler(base::BindOnce(
-        &InterfaceSet::HandleConnectionError, base::Unretained(this),
-        id));  // Unretained is safe as this class owns the Ptrs.
-
-    return id;
-  }
-
-  template <typename FunctionType>
-  void ForAllPtrs(FunctionType function) {
-    for (const auto& it : interface_ptrs_) {
-      function(it.second.get());
-    }
-  }
-
-  // Registers a function that will be called when some InterfacePtr gets
-  // disconnected. When connection error is detected on one of the InterfacePtrs
-  // in the collection, the registered handler will be called with an id of that
-  // InterfacePtr.
-  void set_connection_error_handler(
-      base::RepeatingCallback<void(size_t)> error_handler) {
-    error_handler_ = std::move(error_handler);
-  }
-
- private:
-  void HandleConnectionError(size_t id) {
-    auto it = interface_ptrs_.find(id);
-
-    DCHECK(it != interface_ptrs_.end());
-
-    interface_ptrs_.erase(it);
-
-    error_handler_.Run(id);
-  }
-
-  size_t next_id_ = 0;
-  std::unordered_map<size_t, InterfacePtr> interface_ptrs_;
-  base::RepeatingCallback<void(size_t)> error_handler_;
-};
-
-}  // namespace vr
-
-#endif  // CHROME_BROWSER_VR_SERVICE_INTERFACE_SET_H_
diff --git a/chrome/browser/vr/service/isolated_device_provider.cc b/chrome/browser/vr/service/isolated_device_provider.cc
index 5f44f633..692382b 100644
--- a/chrome/browser/vr/service/isolated_device_provider.cc
+++ b/chrome/browser/vr/service/isolated_device_provider.cc
@@ -38,8 +38,9 @@
 
 void IsolatedVRDeviceProvider::OnDeviceAdded(
     device::mojom::XRRuntimePtr device,
-    device::mojom::IsolatedXRGamepadProviderFactoryPtr gamepad_factory,
-    device::mojom::XRCompositorHostPtr compositor_host,
+    mojo::PendingRemote<device::mojom::IsolatedXRGamepadProviderFactory>
+        gamepad_factory,
+    mojo::PendingRemote<device::mojom::XRCompositorHost> compositor_host,
     device::mojom::XRDeviceId device_id) {
   add_device_callback_.Run(device_id, nullptr, std::move(device));
 
diff --git a/chrome/browser/vr/service/isolated_device_provider.h b/chrome/browser/vr/service/isolated_device_provider.h
index ee81855..ffe78d2 100644
--- a/chrome/browser/vr/service/isolated_device_provider.h
+++ b/chrome/browser/vr/service/isolated_device_provider.h
@@ -9,6 +9,7 @@
 #include "device/vr/public/mojom/isolated_xr_service.mojom.h"
 #include "device/vr/vr_device.h"
 #include "device/vr/vr_device_provider.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 
@@ -39,8 +40,9 @@
   // IsolatedXRRuntimeProviderClient
   void OnDeviceAdded(
       device::mojom::XRRuntimePtr device,
-      device::mojom::IsolatedXRGamepadProviderFactoryPtr gamepad_factory,
-      device::mojom::XRCompositorHostPtr compositor_host,
+      mojo::PendingRemote<device::mojom::IsolatedXRGamepadProviderFactory>
+          gamepad_factory,
+      mojo::PendingRemote<device::mojom::XRCompositorHost> compositor_host,
       device::mojom::XRDeviceId device_id) override;
   void OnDeviceRemoved(device::mojom::XRDeviceId id) override;
   void OnDevicesEnumerated() override;
diff --git a/chrome/browser/vr/service/vr_service_impl.cc b/chrome/browser/vr/service/vr_service_impl.cc
index f653c71d..864ddee7 100644
--- a/chrome/browser/vr/service/vr_service_impl.cc
+++ b/chrome/browser/vr/service/vr_service_impl.cc
@@ -113,7 +113,7 @@
   runtime_manager_ = XRRuntimeManager::GetOrCreateInstance();
   runtime_manager_->AddService(this);
 
-  magic_window_controllers_.set_connection_error_handler(base::BindRepeating(
+  magic_window_controllers_.set_disconnect_handler(base::BindRepeating(
       &VRServiceImpl::OnInlineSessionDisconnected,
       base::Unretained(this)));  // Unretained is OK since the collection is
                                  // owned by VRServiceImpl.
@@ -217,10 +217,8 @@
       immersive_runtime->UpdateListeningForActivate(this);
   }
 
-  magic_window_controllers_.ForAllPtrs(
-      [focused](device::mojom::XRSessionController* controller) {
-        controller->SetFrameDataRestricted(!focused);
-      });
+  for (const auto& controller : magic_window_controllers_)
+    controller->SetFrameDataRestricted(!focused);
 }
 
 // static
@@ -236,7 +234,8 @@
     device::mojom::VRService::RequestSessionCallback callback,
     const std::set<device::mojom::XRSessionFeature>& enabled_features,
     device::mojom::XRSessionPtr session,
-    device::mojom::XRSessionControllerPtr controller) {
+    mojo::PendingRemote<device::mojom::XRSessionController>
+        pending_controller) {
   if (!session) {
     std::move(callback).Run(
         device::mojom::RequestSessionResult::NewFailureReason(
@@ -244,22 +243,25 @@
     return;
   }
 
+  mojo::Remote<device::mojom::XRSessionController> controller(
+      std::move(pending_controller));
   // Start giving out magic window data if we are focused.
   controller->SetFrameDataRestricted(!in_focused_frame_);
 
-  auto id = magic_window_controllers_.AddPtr(std::move(controller));
+  auto id = magic_window_controllers_.Add(std::move(controller));
 
   // Note: We might be recording an inline session that was created by WebVR.
-  GetSessionMetricsHelper()->RecordInlineSessionStart(id);
+  GetSessionMetricsHelper()->RecordInlineSessionStart(id.GetUnsafeValue());
 
   OnSessionCreated(session_runtime_id, std::move(callback), enabled_features,
                    std::move(session));
 }
 
-void VRServiceImpl::OnInlineSessionDisconnected(size_t session_id) {
+void VRServiceImpl::OnInlineSessionDisconnected(
+    mojo::RemoteSetElementId session_id) {
   // Notify metrics helper that inline session was stopped.
   auto* metrics_helper = GetSessionMetricsHelper();
-  metrics_helper->RecordInlineSessionStop(session_id);
+  metrics_helper->RecordInlineSessionStop(session_id.GetUnsafeValue());
 }
 
 SessionMetricsHelper* VRServiceImpl::GetSessionMetricsHelper() {
@@ -513,8 +515,9 @@
     runtime->RequestSession(this, std::move(runtime_options),
                             std::move(immersive_callback));
   } else {
-    base::OnceCallback<void(device::mojom::XRSessionPtr,
-                            device::mojom::XRSessionControllerPtr)>
+    base::OnceCallback<void(
+        device::mojom::XRSessionPtr,
+        mojo::PendingRemote<device::mojom::XRSessionController>)>
         non_immersive_callback =
             base::BindOnce(&VRServiceImpl::OnInlineSessionCreated,
                            weak_ptr_factory_.GetWeakPtr(), session_runtime_id,
diff --git a/chrome/browser/vr/service/vr_service_impl.h b/chrome/browser/vr/service/vr_service_impl.h
index f5a2237..b7513f6 100644
--- a/chrome/browser/vr/service/vr_service_impl.h
+++ b/chrome/browser/vr/service/vr_service_impl.h
@@ -14,7 +14,6 @@
 #include "base/util/type_safety/pass_key.h"
 
 #include "chrome/browser/vr/metrics/session_metrics_helper.h"
-#include "chrome/browser/vr/service/interface_set.h"
 #include "chrome/browser/vr/service/xr_consent_prompt_level.h"
 #include "chrome/browser/vr/vr_export.h"
 #include "content/public/browser/web_contents_observer.h"
@@ -76,7 +75,7 @@
   // Called when inline session gets disconnected. |session_id| is the value
   // returned by |magic_window_controllers_| when adding session controller to
   // it.
-  void OnInlineSessionDisconnected(size_t session_id);
+  void OnInlineSessionDisconnected(mojo::RemoteSetElementId session_id);
 
   // Notifications/calls from BrowserXRRuntime:
   void OnExitPresent();
@@ -122,7 +121,7 @@
       device::mojom::VRService::RequestSessionCallback callback,
       const std::set<device::mojom::XRSessionFeature>& enabled_features,
       device::mojom::XRSessionPtr session,
-      device::mojom::XRSessionControllerPtr controller);
+      mojo::PendingRemote<device::mojom::XRSessionController> controller);
 
   void OnSessionCreated(
       device::mojom::XRDeviceId session_runtime_id,
@@ -157,7 +156,7 @@
   mojo::Remote<device::mojom::VRServiceClient> service_client_;
   content::RenderFrameHost* render_frame_host_;
   mojo::SelfOwnedReceiverRef<VRService> receiver_;
-  InterfaceSet<device::mojom::XRSessionControllerPtr> magic_window_controllers_;
+  mojo::RemoteSet<device::mojom::XRSessionController> magic_window_controllers_;
   device::mojom::XRVisibilityState visibility_state_ =
       device::mojom::XRVisibilityState::VISIBLE;
 
diff --git a/chrome/browser/vr/service/vr_ui_host.h b/chrome/browser/vr/service/vr_ui_host.h
index 664409145..f92a738 100644
--- a/chrome/browser/vr/service/vr_ui_host.h
+++ b/chrome/browser/vr/service/vr_ui_host.h
@@ -8,6 +8,7 @@
 #include "chrome/browser/vr/vr_export.h"
 #include "device/vr/public/mojom/isolated_xr_service.mojom.h"
 #include "device/vr/public/mojom/vr_service.mojom.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 
 namespace vr {
 
@@ -21,9 +22,9 @@
  public:
   virtual ~VRUiHost() = 0;
 
-  using Factory =
-      std::unique_ptr<VRUiHost>(device::mojom::XRDeviceId device_id,
-                                device::mojom::XRCompositorHostPtr compositor);
+  using Factory = std::unique_ptr<VRUiHost>(
+      device::mojom::XRDeviceId device_id,
+      mojo::PendingRemote<device::mojom::XRCompositorHost> compositor);
 
   static void SetFactory(Factory* factory);
   static Factory* GetFactory();
diff --git a/chrome/browser/vr/speech_recognizer_unittest.cc b/chrome/browser/vr/speech_recognizer_unittest.cc
index b49b84e7..8309fc0 100644
--- a/chrome/browser/vr/speech_recognizer_unittest.cc
+++ b/chrome/browser/vr/speech_recognizer_unittest.cc
@@ -20,6 +20,7 @@
 #include "content/public/browser/speech_recognition_manager.h"
 #include "content/public/browser/speech_recognition_session_config.h"
 #include "content/public/browser/speech_recognition_session_context.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/test/test_url_loader_factory.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -54,8 +55,9 @@
 
   // network::mojom::URLLoaderFactory:
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
-    test_url_loader_factory_.Clone(std::move(request));
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
+    test_url_loader_factory_.Clone(std::move(receiver));
   }
 
   void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader,
diff --git a/chrome/browser/vr/ui_host/vr_ui_host_impl.cc b/chrome/browser/vr/ui_host/vr_ui_host_impl.cc
index 0864736c..799300b 100644
--- a/chrome/browser/vr/ui_host/vr_ui_host_impl.cc
+++ b/chrome/browser/vr/ui_host/vr_ui_host_impl.cc
@@ -122,8 +122,9 @@
     *active_capture_state_model_ = CapturingStateModel();
 }
 
-VRUiHostImpl::VRUiHostImpl(device::mojom::XRDeviceId device_id,
-                           device::mojom::XRCompositorHostPtr compositor)
+VRUiHostImpl::VRUiHostImpl(
+    device::mojom::XRDeviceId device_id,
+    mojo::PendingRemote<device::mojom::XRCompositorHost> compositor)
     : compositor_(std::move(compositor)),
       main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
       triggered_capturing_transience_(&triggered_capturing_state_model_) {
@@ -156,7 +157,7 @@
 // static
 std::unique_ptr<VRUiHost> VRUiHostImpl::Create(
     device::mojom::XRDeviceId device_id,
-    device::mojom::XRCompositorHostPtr compositor) {
+    mojo::PendingRemote<device::mojom::XRCompositorHost> compositor) {
   DVLOG(1) << __func__;
   return std::make_unique<VRUiHostImpl>(device_id, std::move(compositor));
 }
diff --git a/chrome/browser/vr/ui_host/vr_ui_host_impl.h b/chrome/browser/vr/ui_host/vr_ui_host_impl.h
index 4a00105..8e4564f 100644
--- a/chrome/browser/vr/ui_host/vr_ui_host_impl.h
+++ b/chrome/browser/vr/ui_host/vr_ui_host_impl.h
@@ -17,6 +17,7 @@
 #include "chrome/browser/vr/service/vr_ui_host.h"
 #include "components/bubble/bubble_manager.h"
 #include "content/public/browser/web_contents.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/device/public/mojom/geolocation_config.mojom.h"
 
@@ -33,13 +34,13 @@
                      public DesktopMediaPickerManager::DialogObserver {
  public:
   VRUiHostImpl(device::mojom::XRDeviceId device_id,
-               device::mojom::XRCompositorHostPtr compositor);
+               mojo::PendingRemote<device::mojom::XRCompositorHost> compositor);
   ~VRUiHostImpl() override;
 
   // Factory for use with VRUiHost::{Set,Get}Factory
   static std::unique_ptr<VRUiHost> Create(
       device::mojom::XRDeviceId device_id,
-      device::mojom::XRCompositorHostPtr compositor);
+      mojo::PendingRemote<device::mojom::XRCompositorHost> compositor);
 
  private:
   // This class manages the transience of each of a CapturingStateModel's flags.
@@ -102,7 +103,7 @@
   void InitCapturingStates();
   void PollCapturingState();
 
-  device::mojom::XRCompositorHostPtr compositor_;
+  mojo::Remote<device::mojom::XRCompositorHost> compositor_;
   std::unique_ptr<VRBrowserRendererThreadWin> ui_rendering_thread_;
   device::mojom::VRDisplayInfoPtr info_;
   content::WebContents* web_contents_ = nullptr;
diff --git a/chrome/browser/web_applications/components/external_install_options.cc b/chrome/browser/web_applications/components/external_install_options.cc
index f6f9433..2dd6f58 100644
--- a/chrome/browser/web_applications/components/external_install_options.cc
+++ b/chrome/browser/web_applications/components/external_install_options.cc
@@ -14,11 +14,9 @@
 
 ExternalInstallOptions::ExternalInstallOptions(
     const GURL& url,
-    LaunchContainer launch_container,
+    blink::mojom::DisplayMode display_mode,
     ExternalInstallSource install_source)
-    : url(url),
-      launch_container(launch_container),
-      install_source(install_source) {}
+    : url(url), display_mode(display_mode), install_source(install_source) {}
 
 ExternalInstallOptions::~ExternalInstallOptions() = default;
 
@@ -33,13 +31,13 @@
 
 bool ExternalInstallOptions::operator==(
     const ExternalInstallOptions& other) const {
-  return std::tie(url, launch_container, install_source,
-                  add_to_applications_menu, add_to_desktop,
-                  add_to_quick_launch_bar, override_previous_user_uninstall,
-                  bypass_service_worker_check, require_manifest,
-                  force_reinstall, wait_for_windows_closed, install_placeholder,
-                  reinstall_placeholder, uninstall_and_replace) ==
-         std::tie(other.url, other.launch_container, other.install_source,
+  return std::tie(url, display_mode, install_source, add_to_applications_menu,
+                  add_to_desktop, add_to_quick_launch_bar,
+                  override_previous_user_uninstall, bypass_service_worker_check,
+                  require_manifest, force_reinstall, wait_for_windows_closed,
+                  install_placeholder, reinstall_placeholder,
+                  uninstall_and_replace) ==
+         std::tie(other.url, other.display_mode, other.install_source,
                   other.add_to_applications_menu, other.add_to_desktop,
                   other.add_to_quick_launch_bar,
                   other.override_previous_user_uninstall,
@@ -51,8 +49,8 @@
 
 std::ostream& operator<<(std::ostream& out,
                          const ExternalInstallOptions& install_options) {
-  return out << "url: " << install_options.url << "\n launch_container: "
-             << static_cast<int32_t>(install_options.launch_container)
+  return out << "url: " << install_options.url << "\n display_mode: "
+             << static_cast<int32_t>(install_options.display_mode)
              << "\n install_source: "
              << static_cast<int32_t>(install_options.install_source)
              << "\n add_to_applications_menu: "
@@ -80,7 +78,7 @@
     const ExternalInstallOptions& install_options) {
   InstallManager::InstallParams params;
 
-  params.launch_container = install_options.launch_container;
+  params.display_mode = install_options.display_mode;
 
   params.add_to_applications_menu = install_options.add_to_applications_menu;
   params.add_to_desktop = install_options.add_to_desktop;
diff --git a/chrome/browser/web_applications/components/external_install_options.h b/chrome/browser/web_applications/components/external_install_options.h
index e9cc7fc..d0af92fb 100644
--- a/chrome/browser/web_applications/components/external_install_options.h
+++ b/chrome/browser/web_applications/components/external_install_options.h
@@ -9,16 +9,16 @@
 
 #include "chrome/browser/web_applications/components/install_manager.h"
 #include "chrome/browser/web_applications/components/web_app_helpers.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 #include "url/gurl.h"
 
 namespace web_app {
 
 enum class ExternalInstallSource;
-enum class LaunchContainer;
 
 struct ExternalInstallOptions {
   ExternalInstallOptions(const GURL& url,
-                         LaunchContainer launch_container,
+                         blink::mojom::DisplayMode display_mode,
                          ExternalInstallSource install_source);
   ~ExternalInstallOptions();
   ExternalInstallOptions(const ExternalInstallOptions& other);
@@ -28,7 +28,7 @@
   bool operator==(const ExternalInstallOptions& other) const;
 
   GURL url;
-  LaunchContainer launch_container;
+  blink::mojom::DisplayMode display_mode;
   ExternalInstallSource install_source;
 
   // If true, a shortcut is added to the Applications folder on macOS, and Start
diff --git a/chrome/browser/web_applications/components/install_manager.h b/chrome/browser/web_applications/components/install_manager.h
index f1d60d8..e46c6ba 100644
--- a/chrome/browser/web_applications/components/install_manager.h
+++ b/chrome/browser/web_applications/components/install_manager.h
@@ -13,6 +13,7 @@
 #include "chrome/browser/web_applications/components/web_app_install_utils.h"
 #include "chrome/browser/web_applications/components/web_app_url_loader.h"
 #include "third_party/blink/public/common/manifest/manifest.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 
 enum class WebappInstallSource;
 struct WebApplicationInfo;
@@ -88,7 +89,8 @@
 
   // These params are a subset of ExternalInstallOptions.
   struct InstallParams {
-    LaunchContainer launch_container = LaunchContainer::kDefault;
+    blink::mojom::DisplayMode display_mode =
+        blink::mojom::DisplayMode::kUndefined;
 
     bool add_to_applications_menu = true;
     bool add_to_desktop = true;
diff --git a/chrome/browser/web_applications/components/manifest_update_manager_browsertest.cc b/chrome/browser/web_applications/components/manifest_update_manager_browsertest.cc
index f1ebd46..6a9c2581 100644
--- a/chrome/browser/web_applications/components/manifest_update_manager_browsertest.cc
+++ b/chrome/browser/web_applications/components/manifest_update_manager_browsertest.cc
@@ -26,6 +26,7 @@
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
 #include "third_party/blink/public/common/manifest/manifest.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 #include "third_party/skia/include/core/SkColor.h"
 
 namespace web_app {
@@ -424,7 +425,7 @@
   // placeholder app.
   base::RunLoop run_loop;
   ExternalInstallOptions install_options(
-      app_url, LaunchContainer::kWindow,
+      app_url, blink::mojom::DisplayMode::kStandalone,
       ExternalInstallSource::kExternalPolicy);
   install_options.add_to_applications_menu = false;
   install_options.add_to_desktop = false;
diff --git a/chrome/browser/web_applications/components/pending_app_manager_unittest.cc b/chrome/browser/web_applications/components/pending_app_manager_unittest.cc
index 929df3a4..010f4fb 100644
--- a/chrome/browser/web_applications/components/pending_app_manager_unittest.cc
+++ b/chrome/browser/web_applications/components/pending_app_manager_unittest.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/web_applications/components/web_app_constants.h"
 #include "chrome/browser/web_applications/test/test_pending_app_manager.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 
 namespace web_app {
 
@@ -30,7 +31,7 @@
     std::vector<ExternalInstallOptions> install_options_list;
     for (const auto& url : urls) {
       install_options_list.emplace_back(
-          url, LaunchContainer::kWindow,
+          url, blink::mojom::DisplayMode::kStandalone,
           ExternalInstallSource::kInternalDefault);
     }
 
@@ -80,10 +81,10 @@
 
   std::vector<ExternalInstallOptions> install_options_list;
   install_options_list.emplace_back(GURL("https://foo.example"),
-                                    LaunchContainer::kWindow,
+                                    blink::mojom::DisplayMode::kStandalone,
                                     ExternalInstallSource::kInternalDefault);
   install_options_list.emplace_back(GURL("https://bar.example"),
-                                    LaunchContainer::kWindow,
+                                    blink::mojom::DisplayMode::kStandalone,
                                     ExternalInstallSource::kInternalDefault);
 
   pending_app_manager->SynchronizeInstalledApps(
@@ -107,7 +108,7 @@
   {
     std::vector<ExternalInstallOptions> install_options_list;
     install_options_list.emplace_back(GURL("https://foo.example"),
-                                      LaunchContainer::kWindow,
+                                      blink::mojom::DisplayMode::kStandalone,
                                       ExternalInstallSource::kInternalDefault);
     base::RunLoop run_loop;
     pending_app_manager->SynchronizeInstalledApps(
diff --git a/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc b/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc
index 7b934b0..a2c9ede 100644
--- a/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc
+++ b/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc
@@ -22,6 +22,7 @@
 #include "components/prefs/pref_service.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 
 namespace web_app {
 
@@ -41,18 +42,19 @@
          default_launch_container->GetString() ==
              kDefaultLaunchContainerTabValue);
 
-  LaunchContainer launch_container;
+  blink::mojom::DisplayMode display_mode;
   if (!default_launch_container) {
-    launch_container = LaunchContainer::kTab;
+    display_mode = blink::mojom::DisplayMode::kBrowser;
   } else if (default_launch_container->GetString() ==
              kDefaultLaunchContainerTabValue) {
-    launch_container = LaunchContainer::kTab;
+    display_mode = blink::mojom::DisplayMode::kBrowser;
   } else {
-    launch_container = LaunchContainer::kWindow;
+    // TODO(crbug.com/1009909): Support Minimal UI.
+    display_mode = blink::mojom::DisplayMode::kStandalone;
   }
 
   ExternalInstallOptions install_options{
-      GURL(url.GetString()), launch_container,
+      GURL(url.GetString()), display_mode,
       ExternalInstallSource::kExternalPolicy};
 
   install_options.add_to_applications_menu = true;
diff --git a/chrome/browser/web_applications/components/web_app_constants.h b/chrome/browser/web_applications/components/web_app_constants.h
index 61d2419..8d4190e 100644
--- a/chrome/browser/web_applications/components/web_app_constants.h
+++ b/chrome/browser/web_applications/components/web_app_constants.h
@@ -28,16 +28,6 @@
 };
 }  // namespace Source
 
-// How the app will be launched after installation.
-enum class LaunchContainer {
-  // When `kDefault` is used, the app will launch in a window if the site is
-  // "installable" (also referred to as Progressive Web App) and in a tab if
-  // the site is not "installable".
-  kDefault,
-  kTab,
-  kWindow,
-};
-
 // The result of an attempted web app installation, uninstallation or update.
 //
 // This is an enum, instead of a struct with multiple fields (e.g. one field for
diff --git a/chrome/browser/web_applications/extensions/install_manager_bookmark_app_unittest.cc b/chrome/browser/web_applications/extensions/install_manager_bookmark_app_unittest.cc
index aa82eb9..c947bf2 100644
--- a/chrome/browser/web_applications/extensions/install_manager_bookmark_app_unittest.cc
+++ b/chrome/browser/web_applications/extensions/install_manager_bookmark_app_unittest.cc
@@ -41,6 +41,7 @@
 #include "extensions/common/extension_icon_set.h"
 #include "extensions/common/manifest_handlers/icons_handler.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "url/gurl.h"
@@ -536,7 +537,7 @@
                                            /*is_installable=*/true);
 
     web_app::InstallManager::InstallParams params;
-    params.launch_container = web_app::LaunchContainer::kTab;
+    params.display_mode = blink::mojom::DisplayMode::kBrowser;
 
     const Extension* extension =
         InstallWebAppWithParams(WebappInstallSource::INTERNAL_DEFAULT, params);
@@ -549,7 +550,7 @@
                                            /*is_installable=*/false);
 
     web_app::InstallManager::InstallParams params;
-    params.launch_container = web_app::LaunchContainer::kWindow;
+    params.display_mode = blink::mojom::DisplayMode::kStandalone;
 
     const Extension* extension =
         InstallWebAppWithParams(WebappInstallSource::INTERNAL_DEFAULT, params);
diff --git a/chrome/browser/web_applications/extensions/pending_app_install_task_unittest.cc b/chrome/browser/web_applications/extensions/pending_app_install_task_unittest.cc
index 1ecb5e3..6ea9823 100644
--- a/chrome/browser/web_applications/extensions/pending_app_install_task_unittest.cc
+++ b/chrome/browser/web_applications/extensions/pending_app_install_task_unittest.cc
@@ -43,6 +43,7 @@
 #include "content/public/test/test_utils.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/common/manifest/manifest.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 #include "url/gurl.h"
 
 namespace web_app {
@@ -377,7 +378,7 @@
 TEST_F(PendingAppInstallTaskTest,
        WebAppOrShortcutFromContents_InstallationSucceeds) {
   auto task = GetInstallationTaskWithTestMocks(
-      {kWebAppUrl, LaunchContainer::kDefault,
+      {kWebAppUrl, blink::mojom::DisplayMode::kUndefined,
        ExternalInstallSource::kInternalDefault});
 
   base::RunLoop run_loop;
@@ -415,7 +416,7 @@
 TEST_F(PendingAppInstallTaskTest,
        WebAppOrShortcutFromContents_InstallationFails) {
   auto task = GetInstallationTaskWithTestMocks(
-      {kWebAppUrl, LaunchContainer::kWindow,
+      {kWebAppUrl, blink::mojom::DisplayMode::kStandalone,
        ExternalInstallSource::kInternalDefault});
   data_retriever()->SetRendererWebApplicationInfo(nullptr);
 
@@ -442,7 +443,7 @@
 TEST_F(PendingAppInstallTaskTest,
        WebAppOrShortcutFromContents_NoDesktopShortcut) {
   ExternalInstallOptions install_options(
-      kWebAppUrl, LaunchContainer::kWindow,
+      kWebAppUrl, blink::mojom::DisplayMode::kStandalone,
       ExternalInstallSource::kInternalDefault);
   install_options.add_to_desktop = false;
   auto task = GetInstallationTaskWithTestMocks(std::move(install_options));
@@ -471,7 +472,7 @@
 TEST_F(PendingAppInstallTaskTest,
        WebAppOrShortcutFromContents_NoQuickLaunchBarShortcut) {
   ExternalInstallOptions install_options(
-      kWebAppUrl, LaunchContainer::kWindow,
+      kWebAppUrl, blink::mojom::DisplayMode::kStandalone,
       ExternalInstallSource::kInternalDefault);
   install_options.add_to_quick_launch_bar = false;
   auto task = GetInstallationTaskWithTestMocks(std::move(install_options));
@@ -500,7 +501,7 @@
     PendingAppInstallTaskTest,
     WebAppOrShortcutFromContents_NoDesktopShortcutAndNoQuickLaunchBarShortcut) {
   ExternalInstallOptions install_options(
-      kWebAppUrl, LaunchContainer::kWindow,
+      kWebAppUrl, blink::mojom::DisplayMode::kStandalone,
       ExternalInstallSource::kInternalDefault);
   install_options.add_to_desktop = false;
   install_options.add_to_quick_launch_bar = false;
@@ -529,7 +530,7 @@
 TEST_F(PendingAppInstallTaskTest,
        WebAppOrShortcutFromContents_ForcedContainerWindow) {
   auto install_options =
-      ExternalInstallOptions(kWebAppUrl, LaunchContainer::kWindow,
+      ExternalInstallOptions(kWebAppUrl, blink::mojom::DisplayMode::kStandalone,
                              ExternalInstallSource::kInternalDefault);
   auto task = GetInstallationTaskWithTestMocks(std::move(install_options));
 
@@ -549,7 +550,7 @@
 TEST_F(PendingAppInstallTaskTest,
        WebAppOrShortcutFromContents_ForcedContainerTab) {
   auto install_options =
-      ExternalInstallOptions(kWebAppUrl, LaunchContainer::kTab,
+      ExternalInstallOptions(kWebAppUrl, blink::mojom::DisplayMode::kBrowser,
                              ExternalInstallSource::kInternalDefault);
   auto task = GetInstallationTaskWithTestMocks(std::move(install_options));
 
@@ -568,7 +569,7 @@
 
 TEST_F(PendingAppInstallTaskTest, WebAppOrShortcutFromContents_DefaultApp) {
   auto install_options =
-      ExternalInstallOptions(kWebAppUrl, LaunchContainer::kDefault,
+      ExternalInstallOptions(kWebAppUrl, blink::mojom::DisplayMode::kUndefined,
                              ExternalInstallSource::kInternalDefault);
   auto task = GetInstallationTaskWithTestMocks(std::move(install_options));
 
@@ -589,7 +590,7 @@
 
 TEST_F(PendingAppInstallTaskTest, WebAppOrShortcutFromContents_AppFromPolicy) {
   auto install_options =
-      ExternalInstallOptions(kWebAppUrl, LaunchContainer::kDefault,
+      ExternalInstallOptions(kWebAppUrl, blink::mojom::DisplayMode::kUndefined,
                              ExternalInstallSource::kExternalPolicy);
   auto task = GetInstallationTaskWithTestMocks(std::move(install_options));
 
@@ -609,7 +610,8 @@
 }
 
 TEST_F(PendingAppInstallTaskTest, InstallPlaceholder) {
-  ExternalInstallOptions options(kWebAppUrl, LaunchContainer::kWindow,
+  ExternalInstallOptions options(kWebAppUrl,
+                                 blink::mojom::DisplayMode::kStandalone,
                                  ExternalInstallSource::kExternalPolicy);
   options.install_placeholder = true;
   auto task = GetInstallationTaskWithTestMocks(std::move(options));
@@ -643,7 +645,8 @@
 // Tests that palceholders are correctly installed when the platform doesn't
 // support os shortcuts.
 TEST_F(PendingAppInstallTaskTest, InstallPlaceholderNoCreateOsShorcuts) {
-  ExternalInstallOptions options(kWebAppUrl, LaunchContainer::kWindow,
+  ExternalInstallOptions options(kWebAppUrl,
+                                 blink::mojom::DisplayMode::kStandalone,
                                  ExternalInstallSource::kExternalPolicy);
   options.install_placeholder = true;
   auto task = GetInstallationTaskWithTestMocks(std::move(options));
@@ -676,7 +679,8 @@
 }
 
 TEST_F(PendingAppInstallTaskTest, InstallPlaceholderTwice) {
-  ExternalInstallOptions options(kWebAppUrl, LaunchContainer::kWindow,
+  ExternalInstallOptions options(kWebAppUrl,
+                                 blink::mojom::DisplayMode::kStandalone,
                                  ExternalInstallSource::kExternalPolicy);
   options.install_placeholder = true;
   AppId placeholder_app_id;
@@ -715,7 +719,8 @@
 }
 
 TEST_F(PendingAppInstallTaskTest, ReinstallPlaceholderSucceeds) {
-  ExternalInstallOptions options(kWebAppUrl, LaunchContainer::kWindow,
+  ExternalInstallOptions options(kWebAppUrl,
+                                 blink::mojom::DisplayMode::kStandalone,
                                  ExternalInstallSource::kExternalPolicy);
   options.install_placeholder = true;
   AppId placeholder_app_id;
@@ -760,7 +765,8 @@
 }
 
 TEST_F(PendingAppInstallTaskTest, ReinstallPlaceholderFails) {
-  ExternalInstallOptions options(kWebAppUrl, LaunchContainer::kWindow,
+  ExternalInstallOptions options(kWebAppUrl,
+                                 blink::mojom::DisplayMode::kStandalone,
                                  ExternalInstallSource::kExternalPolicy);
   options.install_placeholder = true;
   AppId placeholder_app_id;
@@ -809,7 +815,8 @@
 }
 
 TEST_F(PendingAppInstallTaskTest, UninstallAndReplace) {
-  ExternalInstallOptions options = {kWebAppUrl, LaunchContainer::kDefault,
+  ExternalInstallOptions options = {kWebAppUrl,
+                                    blink::mojom::DisplayMode::kUndefined,
                                     ExternalInstallSource::kInternalDefault};
   AppId app_id;
   {
@@ -870,7 +877,7 @@
     base::RunLoop run_loop;
 
     ExternalInstallOptions install_options(
-        GURL(), LaunchContainer::kWindow,
+        GURL(), blink::mojom::DisplayMode::kStandalone,
         ExternalInstallSource::kInternalDefault);
     PendingAppInstallTask install_task(profile(), registrar(), ui_manager(),
                                        finalizer(), install_options);
@@ -888,7 +895,7 @@
 
 TEST_F(PendingAppInstallTaskTest, FailedWebContentsDestroyed) {
   ExternalInstallOptions install_options(
-      GURL(), LaunchContainer::kWindow,
+      GURL(), blink::mojom::DisplayMode::kStandalone,
       ExternalInstallSource::kInternalDefault);
   PendingAppInstallTask install_task(profile(), registrar(), ui_manager(),
                                      finalizer(), install_options);
diff --git a/chrome/browser/web_applications/extensions/system_web_app_manager_unittest.cc b/chrome/browser/web_applications/extensions/system_web_app_manager_unittest.cc
index 24c8109..2e9f676 100644
--- a/chrome/browser/web_applications/extensions/system_web_app_manager_unittest.cc
+++ b/chrome/browser/web_applications/extensions/system_web_app_manager_unittest.cc
@@ -32,6 +32,7 @@
 #include "extensions/browser/extension_registry.h"
 #include "extensions/common/extension_builder.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 #include "url/gurl.h"
 
 namespace web_app {
@@ -43,7 +44,8 @@
 const GURL kAppUrl3(content::GetWebUIURL("system-app3"));
 
 ExternalInstallOptions GetWindowedInstallOptions() {
-  ExternalInstallOptions options(kAppUrl1, LaunchContainer::kWindow,
+  ExternalInstallOptions options(kAppUrl1,
+                                 blink::mojom::DisplayMode::kStandalone,
                                  ExternalInstallSource::kSystemInstalled);
   options.add_to_applications_menu = false;
   options.add_to_desktop = false;
diff --git a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
index ee20fc4..fb4cba1 100644
--- a/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
+++ b/chrome/browser/web_applications/extensions/web_app_policy_manager_unittest.cc
@@ -29,6 +29,7 @@
 #include "extensions/common/extension_builder.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 #include "url/gurl.h"
 
 using sync_preferences::TestingPrefServiceSyncable;
@@ -50,7 +51,8 @@
 }
 
 ExternalInstallOptions GetWindowedInstallOptions() {
-  ExternalInstallOptions options(kWindowedUrl, LaunchContainer::kWindow,
+  ExternalInstallOptions options(kWindowedUrl,
+                                 blink::mojom::DisplayMode::kStandalone,
                                  ExternalInstallSource::kExternalPolicy);
   options.add_to_applications_menu = true;
   options.add_to_desktop = false;
@@ -70,7 +72,8 @@
 }
 
 ExternalInstallOptions GetTabbedInstallOptions() {
-  ExternalInstallOptions options(kTabbedUrl, LaunchContainer::kTab,
+  ExternalInstallOptions options(kTabbedUrl,
+                                 blink::mojom::DisplayMode::kBrowser,
                                  ExternalInstallSource::kExternalPolicy);
   options.add_to_applications_menu = true;
   options.add_to_desktop = false;
@@ -88,7 +91,8 @@
 }
 
 ExternalInstallOptions GetNoContainerInstallOptions() {
-  ExternalInstallOptions options(kNoContainerUrl, LaunchContainer::kTab,
+  ExternalInstallOptions options(kNoContainerUrl,
+                                 blink::mojom::DisplayMode::kBrowser,
                                  ExternalInstallSource::kExternalPolicy);
   options.add_to_applications_menu = true;
   options.add_to_desktop = false;
@@ -106,7 +110,8 @@
 }
 
 ExternalInstallOptions GetCreateDesktopShorcutDefaultInstallOptions() {
-  ExternalInstallOptions options(kNoContainerUrl, LaunchContainer::kTab,
+  ExternalInstallOptions options(kNoContainerUrl,
+                                 blink::mojom::DisplayMode::kBrowser,
                                  ExternalInstallSource::kExternalPolicy);
   options.add_to_applications_menu = true;
   options.add_to_desktop = false;
@@ -125,7 +130,8 @@
 }
 
 ExternalInstallOptions GetCreateDesktopShorcutFalseInstallOptions() {
-  ExternalInstallOptions options(kNoContainerUrl, LaunchContainer::kTab,
+  ExternalInstallOptions options(kNoContainerUrl,
+                                 blink::mojom::DisplayMode::kBrowser,
                                  ExternalInstallSource::kExternalPolicy);
   options.add_to_applications_menu = true;
   options.add_to_desktop = false;
@@ -144,7 +150,8 @@
 }
 
 ExternalInstallOptions GetCreateDesktopShorcutTrueInstallOptions() {
-  ExternalInstallOptions options(kNoContainerUrl, LaunchContainer::kTab,
+  ExternalInstallOptions options(kNoContainerUrl,
+                                 blink::mojom::DisplayMode::kBrowser,
                                  ExternalInstallSource::kExternalPolicy);
   options.add_to_applications_menu = true;
   options.add_to_desktop = true;
diff --git a/chrome/browser/web_applications/external_web_app_manager.cc b/chrome/browser/web_applications/external_web_app_manager.cc
index 50b98f6..de83d893 100644
--- a/chrome/browser/web_applications/external_web_app_manager.cc
+++ b/chrome/browser/web_applications/external_web_app_manager.cc
@@ -27,6 +27,7 @@
 #include "chrome/browser/web_applications/components/web_app_install_utils.h"
 #include "chrome/common/chrome_paths.h"
 #include "content/public/browser/browser_thread.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 #include "url/gurl.h"
 
 #if defined(OS_CHROMEOS)
@@ -171,12 +172,13 @@
       continue;
     }
     std::string launch_container_str = value->GetString();
-    auto launch_container = LaunchContainer::kTab;
+    auto display_mode = blink::mojom::DisplayMode::kBrowser;
     if (launch_container_str == kLaunchContainerTab) {
-      launch_container = LaunchContainer::kTab;
+      display_mode = blink::mojom::DisplayMode::kBrowser;
     } else if (launch_container_str == kLaunchContainerWindow) {
-      launch_container = LaunchContainer::kWindow;
+      display_mode = blink::mojom::DisplayMode::kStandalone;
     } else {
+      // TODO(crbug.com/1009909): Support Minimal UI.
       LOG(ERROR) << file.value() << " had an invalid " << kLaunchContainer;
       continue;
     }
@@ -207,7 +209,7 @@
     }
 
     ExternalInstallOptions install_options(
-        std::move(app_url), launch_container,
+        std::move(app_url), display_mode,
         ExternalInstallSource::kExternalDefault);
     install_options.add_to_applications_menu = create_shortcuts;
     install_options.add_to_desktop = create_shortcuts;
diff --git a/chrome/browser/web_applications/external_web_app_manager_unittest.cc b/chrome/browser/web_applications/external_web_app_manager_unittest.cc
index 87c50744..38d1123 100644
--- a/chrome/browser/web_applications/external_web_app_manager_unittest.cc
+++ b/chrome/browser/web_applications/external_web_app_manager_unittest.cc
@@ -24,6 +24,7 @@
 #include "components/account_id/account_id.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 #include "url/gurl.h"
 
 #if defined(OS_CHROMEOS)
@@ -189,7 +190,8 @@
   std::vector<ExternalInstallOptions> test_install_options_list;
   {
     ExternalInstallOptions install_options(
-        GURL("https://www.chromestatus.com/features"), LaunchContainer::kTab,
+        GURL("https://www.chromestatus.com/features"),
+        blink::mojom::DisplayMode::kBrowser,
         ExternalInstallSource::kExternalDefault);
     install_options.add_to_applications_menu = true;
     install_options.add_to_desktop = true;
@@ -200,7 +202,8 @@
   {
     ExternalInstallOptions install_options(
         GURL("https://events.google.com/io2016/?utm_source=web_app_manifest"),
-        LaunchContainer::kWindow, ExternalInstallSource::kExternalDefault);
+        blink::mojom::DisplayMode::kStandalone,
+        ExternalInstallSource::kExternalDefault);
     install_options.add_to_applications_menu = false;
     install_options.add_to_desktop = false;
     install_options.add_to_quick_launch_bar = false;
diff --git a/chrome/browser/web_applications/pending_app_install_task.cc b/chrome/browser/web_applications/pending_app_install_task.cc
index a6f3b92..4fe4a23 100644
--- a/chrome/browser/web_applications/pending_app_install_task.cc
+++ b/chrome/browser/web_applications/pending_app_install_task.cc
@@ -24,6 +24,7 @@
 #include "chrome/browser/web_applications/components/web_app_ui_manager.h"
 #include "chrome/common/web_application_info.h"
 #include "content/public/browser/browser_thread.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 
 namespace web_app {
 
@@ -174,12 +175,14 @@
   web_app_info.title = base::UTF8ToUTF16(install_options_.url.spec());
   web_app_info.app_url = install_options_.url;
 
-  switch (install_options_.launch_container) {
-    case LaunchContainer::kDefault:
-    case LaunchContainer::kTab:
+  switch (install_options_.display_mode) {
+    case blink::mojom::DisplayMode::kUndefined:
+    case blink::mojom::DisplayMode::kBrowser:
       web_app_info.open_as_window = false;
       break;
-    case LaunchContainer::kWindow:
+    case blink::mojom::DisplayMode::kMinimalUi:
+    case blink::mojom::DisplayMode::kStandalone:
+    case blink::mojom::DisplayMode::kFullscreen:
       web_app_info.open_as_window = true;
       break;
   }
diff --git a/chrome/browser/web_applications/pending_app_manager_impl_unittest.cc b/chrome/browser/web_applications/pending_app_manager_impl_unittest.cc
index fc3dfcd1..2bc4ebc 100644
--- a/chrome/browser/web_applications/pending_app_manager_impl_unittest.cc
+++ b/chrome/browser/web_applications/pending_app_manager_impl_unittest.cc
@@ -31,6 +31,7 @@
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 
 namespace web_app {
 
@@ -50,7 +51,8 @@
 ExternalInstallOptions GetFooInstallOptions(
     base::Optional<bool> override_previous_user_uninstall =
         base::Optional<bool>()) {
-  ExternalInstallOptions options(kFooWebAppUrl, LaunchContainer::kTab,
+  ExternalInstallOptions options(kFooWebAppUrl,
+                                 blink::mojom::DisplayMode::kBrowser,
                                  ExternalInstallSource::kExternalPolicy);
 
   if (override_previous_user_uninstall.has_value())
@@ -61,13 +63,15 @@
 }
 
 ExternalInstallOptions GetBarInstallOptions() {
-  ExternalInstallOptions options(kBarWebAppUrl, LaunchContainer::kWindow,
+  ExternalInstallOptions options(kBarWebAppUrl,
+                                 blink::mojom::DisplayMode::kStandalone,
                                  ExternalInstallSource::kExternalPolicy);
   return options;
 }
 
 ExternalInstallOptions GetQuxInstallOptions() {
-  ExternalInstallOptions options(kQuxWebAppUrl, LaunchContainer::kWindow,
+  ExternalInstallOptions options(kQuxWebAppUrl,
+                                 blink::mojom::DisplayMode::kStandalone,
                                  ExternalInstallSource::kExternalPolicy);
   return options;
 }
@@ -749,7 +753,8 @@
                                      WebAppUrlLoader::Result::kUrlLoaded);
 
   auto get_force_reinstall_info = []() {
-    ExternalInstallOptions options(kFooWebAppUrl, LaunchContainer::kWindow,
+    ExternalInstallOptions options(kFooWebAppUrl,
+                                   blink::mojom::DisplayMode::kStandalone,
                                    ExternalInstallSource::kExternalPolicy);
     options.force_reinstall = true;
     return options;
diff --git a/chrome/browser/web_applications/system_web_app_manager.cc b/chrome/browser/web_applications/system_web_app_manager.cc
index 5f5fc84..19833e4 100644
--- a/chrome/browser/web_applications/system_web_app_manager.cc
+++ b/chrome/browser/web_applications/system_web_app_manager.cc
@@ -25,6 +25,7 @@
 #include "components/prefs/pref_service.h"
 #include "components/version_info/version_info.h"
 #include "content/public/common/content_switches.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 
 #if defined(OS_CHROMEOS)
 #include "ash/public/cpp/app_list/internal_app_id_constants.h"
@@ -81,7 +82,7 @@
   DCHECK_EQ(content::kChromeUIScheme, info.install_url.scheme());
 
   web_app::ExternalInstallOptions install_options(
-      info.install_url, LaunchContainer::kWindow,
+      info.install_url, blink::mojom::DisplayMode::kStandalone,
       ExternalInstallSource::kSystemInstalled);
   install_options.add_to_applications_menu = false;
   install_options.add_to_desktop = false;
diff --git a/chrome/browser/web_applications/web_app_install_task.cc b/chrome/browser/web_applications/web_app_install_task.cc
index e0e0c5e..773b601f 100644
--- a/chrome/browser/web_applications/web_app_install_task.cc
+++ b/chrome/browser/web_applications/web_app_install_task.cc
@@ -22,6 +22,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/web_contents.h"
 #include "third_party/blink/public/common/manifest/manifest.h"
+#include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 #include "url/gurl.h"
 
 #if defined(OS_CHROMEOS)
@@ -447,9 +448,9 @@
   InstallFinalizer::FinalizeOptions finalize_options;
   finalize_options.install_source = install_source_;
   if (install_params_ &&
-      install_params_->launch_container != LaunchContainer::kDefault) {
+      install_params_->display_mode != blink::mojom::DisplayMode::kUndefined) {
     web_app_info_copy.open_as_window =
-        install_params_->launch_container == LaunchContainer::kWindow;
+        install_params_->display_mode != blink::mojom::DisplayMode::kBrowser;
   }
 
   install_finalizer_->FinalizeInstall(
diff --git a/chrome/browser/web_applications/web_app_install_task_unittest.cc b/chrome/browser/web_applications/web_app_install_task_unittest.cc
index 6d9d4495..c9d21e20 100644
--- a/chrome/browser/web_applications/web_app_install_task_unittest.cc
+++ b/chrome/browser/web_applications/web_app_install_task_unittest.cc
@@ -1094,13 +1094,13 @@
   run_loop.Run();
 }
 
-TEST_F(WebAppInstallTaskTest, InstallWebAppWithParams_LaunchContainer) {
+TEST_F(WebAppInstallTaskTest, InstallWebAppWithParams_DisplayMode) {
   {
     CreateDataToRetrieve(GURL("https://example.com/"),
                          /*open_as_window*/ false);
 
     InstallManager::InstallParams params;
-    params.launch_container = LaunchContainer::kDefault;
+    params.display_mode = blink::mojom::DisplayMode::kUndefined;
     auto app_id = InstallWebAppWithParams(params);
 
     EXPECT_EQ(blink::mojom::DisplayMode::kBrowser,
@@ -1110,7 +1110,7 @@
     CreateDataToRetrieve(GURL("https://example.org/"), /*open_as_window*/ true);
 
     InstallManager::InstallParams params;
-    params.launch_container = LaunchContainer::kDefault;
+    params.display_mode = blink::mojom::DisplayMode::kUndefined;
     auto app_id = InstallWebAppWithParams(params);
 
     EXPECT_EQ(blink::mojom::DisplayMode::kStandalone,
@@ -1120,7 +1120,7 @@
     CreateDataToRetrieve(GURL("https://example.au/"), /*open_as_window*/ true);
 
     InstallManager::InstallParams params;
-    params.launch_container = LaunchContainer::kTab;
+    params.display_mode = blink::mojom::DisplayMode::kBrowser;
     auto app_id = InstallWebAppWithParams(params);
 
     EXPECT_EQ(blink::mojom::DisplayMode::kBrowser,
@@ -1131,7 +1131,7 @@
                          /*open_as_window*/ false);
 
     InstallManager::InstallParams params;
-    params.launch_container = LaunchContainer::kWindow;
+    params.display_mode = blink::mojom::DisplayMode::kStandalone;
     auto app_id = InstallWebAppWithParams(params);
 
     EXPECT_EQ(blink::mojom::DisplayMode::kStandalone,
diff --git a/chrome/installer/mini_installer/BUILD.gn b/chrome/installer/mini_installer/BUILD.gn
index cc2bfe06..99a1bc7 100644
--- a/chrome/installer/mini_installer/BUILD.gn
+++ b/chrome/installer/mini_installer/BUILD.gn
@@ -226,6 +226,7 @@
         deps += [ "//tools/v8_context_snapshot" ]
       } else {
         inputs += [ "$root_out_dir/snapshot_blob.bin" ]
+        args += [ "--include_snapshotblob=1" ]
       }
     }
 
diff --git a/chrome/installer/mini_installer/chrome.release b/chrome/installer/mini_installer/chrome.release
index bdf0219..1f894b7 100644
--- a/chrome/installer/mini_installer/chrome.release
+++ b/chrome/installer/mini_installer/chrome.release
@@ -91,3 +91,9 @@
 WidevineCdm\_platform_specific\win_x86\widevinecdm.dll.sig: %(VersionDir)s\WidevineCdm\_platform_specific\win_x86\
 WidevineCdm\_platform_specific\win_x64\widevinecdm.dll: %(VersionDir)s\WidevineCdm\_platform_specific\win_x64\
 WidevineCdm\_platform_specific\win_x64\widevinecdm.dll.sig: %(VersionDir)s\WidevineCdm\_platform_specific\win_x64\
+
+[SNAPSHOTBLOB]
+# The snapshot_blob.bin V8 snapshot is needed in builds that don't use
+# v8_context_snapshot.bin, such as Linux-Windows cross-builds.
+# It has its own section here so that it's only included when necessary.
+snapshot_blob.bin: %(VersionDir)s\
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
index bf4ac9e..43b0f39 100644
--- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
+++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -1729,17 +1729,24 @@
   base::RunLoop().RunUntilIdle();
 }
 
-TEST_F(PasswordAutofillAgentTest, TryToShowTouchToFillShownOnlyOnce) {
+TEST_F(PasswordAutofillAgentTest, TouchToFillDismissed) {
   SimulateOnFillPasswordForm(fill_data_);
 
-  password_autofill_agent_->TryToShowTouchToFill(username_element_);
+  // Touch to fill will be shown multiple times until TouchToFillDismissed()
+  // gets called.
+  EXPECT_CALL(fake_driver_, ShowTouchToFill).Times(2);
+  EXPECT_TRUE(
+      password_autofill_agent_->TryToShowTouchToFill(username_element_));
+  EXPECT_TRUE(
+      password_autofill_agent_->TryToShowTouchToFill(password_element_));
   base::RunLoop().RunUntilIdle();
 
-  // Touch to fill is shown not more than one time per page load. Check that.
+  password_autofill_agent_->TouchToFillDismissed();
   EXPECT_FALSE(
       password_autofill_agent_->TryToShowTouchToFill(username_element_));
   EXPECT_FALSE(
       password_autofill_agent_->TryToShowTouchToFill(password_element_));
+  base::RunLoop().RunUntilIdle();
 
   // Reload the page and simulate fill.
   LoadHTML(kFormHTML);
diff --git a/chrome/renderer/loadtimes_extension_bindings.cc b/chrome/renderer/loadtimes_extension_bindings.cc
index 090b05b..89922874 100644
--- a/chrome/renderer/loadtimes_extension_bindings.cc
+++ b/chrome/renderer/loadtimes_extension_bindings.cc
@@ -7,9 +7,9 @@
 #include <math.h>
 
 #include "base/time/time.h"
-#include "content/public/renderer/document_state.h"
 #include "extensions/renderer/v8_helpers.h"
 #include "net/http/http_response_info.h"
+#include "third_party/blink/public/platform/web_url_response.h"
 #include "third_party/blink/public/web/web_local_frame.h"
 #include "third_party/blink/public/web/web_performance.h"
 #include "v8/include/v8.h"
@@ -18,7 +18,6 @@
 using blink::WebLocalFrame;
 using blink::WebNavigationType;
 using blink::WebPerformance;
-using content::DocumentState;
 
 // Values for CSI "tran" property
 const int kTransitionLink = 0;
@@ -132,11 +131,7 @@
     if (!document_loader) {
       return;
     }
-    DocumentState* document_state =
-        DocumentState::FromDocumentLoader(document_loader);
-    if (!document_state) {
-      return;
-    }
+    const blink::WebURLResponse& response = document_loader->GetResponse();
     WebPerformance web_performance = frame->Performance();
     // Though request time now tends to be used to describe the time that the
     // request for the main resource was issued, when chrome.loadTimes() was
@@ -174,16 +169,16 @@
     double first_paint_after_load_time = 0.0;
     std::string navigation_type =
         GetNavigationType(document_loader->GetNavigationType());
-    bool was_fetched_via_spdy = document_state->was_fetched_via_spdy();
-    bool was_alpn_negotiated = document_state->was_alpn_negotiated();
+    bool was_fetched_via_spdy = response.WasFetchedViaSPDY();
+    bool was_alpn_negotiated = response.WasAlpnNegotiated();
     std::string alpn_negotiated_protocol =
-        document_state->alpn_negotiated_protocol();
+        response.AlpnNegotiatedProtocol().Utf8();
     bool was_alternate_protocol_available =
-        document_state->was_alternate_protocol_available();
+        response.WasAlternateProtocolAvailable();
     std::string connection_info = net::HttpResponseInfo::ConnectionInfoToString(
-        document_state->connection_info());
+        response.ConnectionInfo());
 
-    // Important: |frame|, |document_loader| and |document_state| should not be
+    // Important: |frame| and |document_loader| should not be
     // referred to below this line, as JS setters below can invalidate these
     // pointers.
     v8::Isolate* isolate = args.GetIsolate();
diff --git a/chrome/test/base/test_browser_window.cc b/chrome/test/base/test_browser_window.cc
index 4b89caa9..7fcf156 100644
--- a/chrome/test/base/test_browser_window.cc
+++ b/chrome/test/base/test_browser_window.cc
@@ -206,7 +206,7 @@
 
 SharingDialog* TestBrowserWindow::ShowSharingDialog(
     content::WebContents* web_contents,
-    SharingUiController* controller) {
+    SharingDialogData data) {
   return nullptr;
 }
 
diff --git a/chrome/test/base/test_browser_window.h b/chrome/test/base/test_browser_window.h
index 6ea5d92..e2d1a97 100644
--- a/chrome/test/base/test_browser_window.h
+++ b/chrome/test/base/test_browser_window.h
@@ -127,7 +127,7 @@
   bool IsToolbarVisible() const override;
   bool IsToolbarShowing() const override;
   SharingDialog* ShowSharingDialog(content::WebContents* contents,
-                                   SharingUiController* controller) override;
+                                   SharingDialogData data) override;
   void ShowUpdateChromeDialog() override {}
   void ShowBookmarkBubble(const GURL& url, bool already_bookmarked) override {}
   qrcode_generator::QRCodeGeneratorBubbleView* ShowQRCodeGeneratorBubble(
diff --git a/chrome/test/base/testing_profile_manager.cc b/chrome/test/base/testing_profile_manager.cc
index 55a0c4f..92e96b6 100644
--- a/chrome/test/base/testing_profile_manager.cc
+++ b/chrome/test/base/testing_profile_manager.cc
@@ -121,7 +121,7 @@
   DCHECK(success);
   entry->SetAvatarIconIndex(avatar_id);
   entry->SetSupervisedUserId(supervised_user_id);
-  entry->SetName(user_name);
+  entry->SetLocalProfileName(user_name);
 
   testing_profiles_.insert(std::make_pair(profile_name, profile_ptr));
 
diff --git a/chrome/test/chromedriver/server/http_handler.cc b/chrome/test/chromedriver/server/http_handler.cc
index 228f29f..56e3b8dc 100644
--- a/chrome/test/chromedriver/server/http_handler.cc
+++ b/chrome/test/chromedriver/server/http_handler.cc
@@ -34,6 +34,7 @@
 #include "chrome/test/chromedriver/util.h"
 #include "chrome/test/chromedriver/version.h"
 #include "chrome/test/chromedriver/webauthn_commands.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "net/server/http_server_request_info.h"
 #include "net/server/http_server_response_info.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -96,7 +97,8 @@
                          traffic_annotation));
     }
   }
-  void Clone(network::mojom::URLLoaderFactoryRequest factory) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory)
+      override {
     NOTIMPLEMENTED();
   }
 
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py
index 2c57cac..bd48e145 100755
--- a/chrome/test/chromedriver/test/run_py_tests.py
+++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -78,6 +78,8 @@
     'ChromeDriverTest.testAlertOnNewWindow',
     # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2532
     'ChromeDriverPageLoadTimeoutTest.testRefreshWithPageLoadTimeout',
+    # https://bugs.chromium.org/p/chromium/issues/detail?id=1011225
+    'ChromeDriverTest.testActionsMultiTouchPoint',
 ]
 
 
diff --git a/chrome/test/data/webui/a11y/accessibility_audit_rules.js b/chrome/test/data/webui/a11y/accessibility_audit_rules.js
index 5079576..6c08d3e 100644
--- a/chrome/test/data/webui/a11y/accessibility_audit_rules.js
+++ b/chrome/test/data/webui/a11y/accessibility_audit_rules.js
@@ -52,7 +52,6 @@
   'frame-title',
   'heading-order',
   'hidden-content',
-  'href-no-hash',
   'html-has-lang',
   'html-lang-valid',
   'image-alt',
diff --git a/chrome/test/data/webui/extensions/a11y/extensions_a11y_test.js b/chrome/test/data/webui/extensions/a11y/extensions_a11y_test.js
index fcb77c0..11bc8789 100644
--- a/chrome/test/data/webui/extensions/a11y/extensions_a11y_test.js
+++ b/chrome/test/data/webui/extensions/a11y/extensions_a11y_test.js
@@ -56,6 +56,16 @@
         return parentNode && parentNode.host &&
             parentNode.host.tagName == 'CR-TOGGLE';
       },
+
+      // TODO(crbug.com/1002620): this filter can be removed after
+      // addressing the bug
+      'heading-order': function(nodeResult) {
+        // Filter out 'Heading levels do not increase by one' error when
+        // enumerating extensions
+        const expectedMarkup = '<div id="name" role="heading" aria-level="3" \
+class="clippable-flex-text">My extension 1</div>';
+        return nodeResult['html'] === expectedMarkup;
+      },
     };
   }
 
@@ -85,7 +95,13 @@
   name: 'NoExtensions',
 
   /** @override */
-  axeOptions: CrExtensionsA11yTest.axeOptions,
+  // TODO(crbug.com/1002627): when bug is addressed, this should be replaced
+  // with axeOptions: CrExtensionsA11yTest.axeOptions,
+  axeOptions: Object.assign({}, CrExtensionsA11yTest.axeOptions, {
+    'rules': Object.assign({}, CrExtensionsA11yTest.axeOptions.rules, {
+      'link-in-text-block': {enabled: false},
+    })
+  }),
 
   /** @override */
   violationFilter: CrExtensionsA11yTest.violationFilter,
diff --git a/chrome/test/data/webui/management/a11y/management_a11y_test.js b/chrome/test/data/webui/management/a11y/management_a11y_test.js
index a89088c..bc54861 100644
--- a/chrome/test/data/webui/management/a11y/management_a11y_test.js
+++ b/chrome/test/data/webui/management/a11y/management_a11y_test.js
@@ -31,6 +31,8 @@
         'skip-link': {enabled: false},
         // TODO(crbug.com/761461): enable after addressing flaky tests.
         'color-contrast': {enabled: false},
+        // TODO(crbug.com/1002623): remove this line after addressing bug
+        'link-in-text-block': {enabled: false},
       },
     };
   }
diff --git a/chrome/test/data/webui/settings/a11y/crostini_settings_subpage_a11y_test.js b/chrome/test/data/webui/settings/a11y/crostini_settings_subpage_a11y_test.js
index f9349f2..c2a8327 100644
--- a/chrome/test/data/webui/settings/a11y/crostini_settings_subpage_a11y_test.js
+++ b/chrome/test/data/webui/settings/a11y/crostini_settings_subpage_a11y_test.js
@@ -15,7 +15,7 @@
   /** @override */
   name: 'CROSTINI',
   /** @override */
-  axeOptions: SettingsAccessibilityTest.axeOptions,
+  axeOptions: SettingsAccessibilityTest.axeOptionsExcludeLinkInTextBlock,
   /** @override */
   setup: function() {
     settings.router.navigateTo(settings.routes.CROSTINI);
diff --git a/chrome/test/data/webui/settings/a11y/multidevice_a11y_test.js b/chrome/test/data/webui/settings/a11y/multidevice_a11y_test.js
index 1eb57f3..97c7759 100644
--- a/chrome/test/data/webui/settings/a11y/multidevice_a11y_test.js
+++ b/chrome/test/data/webui/settings/a11y/multidevice_a11y_test.js
@@ -32,7 +32,7 @@
   /** @override */
   name: 'MULTIDEVICE',
   /** @override */
-  axeOptions: SettingsAccessibilityTest.axeOptions,
+  axeOptions: SettingsAccessibilityTest.axeOptionsExcludeLinkInTextBlock,
   /** @override */
   setup: function() {
     settings.router.navigateTo(settings.routes.MULTIDEVICE);
diff --git a/chrome/test/data/webui/settings/a11y/multidevice_features_a11y_test.js b/chrome/test/data/webui/settings/a11y/multidevice_features_a11y_test.js
index 841c3feb..5a0f2a07 100644
--- a/chrome/test/data/webui/settings/a11y/multidevice_features_a11y_test.js
+++ b/chrome/test/data/webui/settings/a11y/multidevice_features_a11y_test.js
@@ -32,7 +32,7 @@
   /** @override */
   name: 'MULTIDEVICE_FEATURES_ACCESSIBILITY',
   /** @override */
-  axeOptions: SettingsAccessibilityTest.axeOptions,
+  axeOptions: SettingsAccessibilityTest.axeOptionsExcludeLinkInTextBlock,
   /** @override */
   setup: function() {
     settings.router.navigateTo(settings.routes.MULTIDEVICE_FEATURES);
diff --git a/chrome/test/data/webui/settings/a11y/settings_accessibility_test.js b/chrome/test/data/webui/settings/a11y/settings_accessibility_test.js
index 7d52614..b871ad8 100644
--- a/chrome/test/data/webui/settings/a11y/settings_accessibility_test.js
+++ b/chrome/test/data/webui/settings/a11y/settings_accessibility_test.js
@@ -28,6 +28,17 @@
   }
 };
 
+// TODO(crbug.com/1002627): This block prevents generation of a
+// link-in-text-block browser-test. This can be removed once the bug is
+// addressed, and usage should be replaced with
+// SettingsAccessibilityTest.axeOptions
+SettingsAccessibilityTest.axeOptionsExcludeLinkInTextBlock =
+    Object.assign({}, SettingsAccessibilityTest.axeOptions, {
+      'rules': Object.assign({}, SettingsAccessibilityTest.axeOptions.rules, {
+        'link-in-text-block': {enabled: false},
+      })
+    });
+
 // Default accessibility audit options. Specify in test definition to use.
 SettingsAccessibilityTest.violationFilter = {
   // Polymer components use aria-active-attribute.
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 4c081383..2e92a513e 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -112,7 +112,8 @@
   }
 };
 
-TEST_F('OSSettingsPageTest', 'AllJsTests', () => {
+// Failing on linux-chromeos-dbg bot, see https://crbug.com/1013094
+TEST_F('OSSettingsPageTest', 'DISABLED_AllJsTests', () => {
   // Run all registered tests.
   mocha.run();
 });
@@ -188,7 +189,8 @@
   }
 };
 
-TEST_F('OSSettingsAppManagementDomSwitchTest', 'All', function() {
+// Failing on linux-chromeos-dbg bot, see https://crbug.com/1013094
+TEST_F('OSSettingsAppManagementDomSwitchTest', 'DISABLED_All', function() {
   mocha.run();
 });
 
@@ -209,7 +211,8 @@
   }
 };
 
-TEST_F('OSSettingsAppManagementPageTest', 'AllJsTests', () => {
+// Failing on linux-chromeos-dbg bot, see https://crbug.com/1013094
+TEST_F('OSSettingsAppManagementPageTest', 'DISABLED_AllJsTests', () => {
   mocha.run();
 });
 
@@ -230,9 +233,12 @@
   }
 };
 
-TEST_F('OSSettingsAppManagementPwaPermissionViewTest', 'AllJsTests', () => {
-  mocha.run();
-});
+// Failing on linux-chromeos-dbg bot, see https://crbug.com/1013094
+TEST_F(
+    'OSSettingsAppManagementPwaPermissionViewTest', 'DISABLED_AllJsTests',
+    () => {
+      mocha.run();
+    });
 
 // Test fixture for the app management arc permission view element.
 // eslint-disable-next-line no-var
@@ -251,9 +257,12 @@
   }
 };
 
-TEST_F('OSSettingsAppManagementArcPermissionViewTest', 'AllJsTests', () => {
-  mocha.run();
-});
+// Failing on linux-chromeos-dbg bot, see https://crbug.com/1013094
+TEST_F(
+    'OSSettingsAppManagementArcPermissionViewTest', 'DISABLED_AllJsTests',
+    () => {
+      mocha.run();
+    });
 
 // Test fixture for the app management managed app view.
 // eslint-disable-next-line no-var
@@ -272,7 +281,8 @@
   }
 };
 
-TEST_F('OSSettingsAppManagementManagedAppTest', 'AllJsTests', () => {
+// Failing on linux-chromeos-dbg bot, see https://crbug.com/1013094
+TEST_F('OSSettingsAppManagementManagedAppTest', 'DISABLED_AllJsTests', () => {
   mocha.run();
 });
 
@@ -289,7 +299,8 @@
   }
 };
 
-TEST_F('OSSettingsAppManagementReducersTest', 'AllJsTests', () => {
+// Failing on linux-chromeos-dbg bot, see https://crbug.com/1013094
+TEST_F('OSSettingsAppManagementReducersTest', 'DISABLED_AllJsTests', () => {
   mocha.run();
 });
 
@@ -563,7 +574,8 @@
   }
 };
 
-TEST_F('OSSettingsMainTest', 'AllJsTests', () => {
+// Failing on linux-chromeos-dbg bot, see https://crbug.com/1013094
+TEST_F('OSSettingsMainTest', 'DISABLED_AllJsTests', () => {
   mocha.run();
 });
 
@@ -579,7 +591,8 @@
   }
 };
 
-TEST_F('OSSettingsMenuTest', 'AllJsTests', () => {
+// Failing on linux-chromeos-dbg bot, see https://crbug.com/1013094
+TEST_F('OSSettingsMenuTest', 'DISABLED_AllJsTests', () => {
   mocha.run();
 });
 
@@ -847,7 +860,8 @@
   }
 };
 
-TEST_F('OSSettingsPeoplePageTest', 'AllJsTests', () => {
+// Failing on linux-chromeos-dbg bot, see https://crbug.com/1013094
+TEST_F('OSSettingsPeoplePageTest', 'DISABLED_AllJsTests', () => {
   mocha.run();
 });
 
@@ -865,7 +879,8 @@
   }
 };
 
-TEST_F('OSSettingsPersonalizationPageTest', 'AllJsTests', () => {
+// Failing on linux-chromeos-dbg bot, see https://crbug.com/1013094
+TEST_F('OSSettingsPersonalizationPageTest', 'DISABLED_AllJsTests', () => {
   mocha.run();
 });
 
diff --git a/chrome/test/data/webui/welcome/a11y_tests.js b/chrome/test/data/webui/welcome/a11y_tests.js
index da69f12..1f6c29a9 100644
--- a/chrome/test/data/webui/welcome/a11y_tests.js
+++ b/chrome/test/data/webui/welcome/a11y_tests.js
@@ -34,7 +34,12 @@
   name: 'WelcomeFlow',
 
   // Optional. Configuration for axe-core. Can be used to disable a test.
-  axeOptions: {},
+  axeOptions: {
+    'rules': {
+      // TODO(crbug.com/761461): enable after addressing flaky tests.
+      'color-contrast': {enabled: false},
+    }
+  },
 
   // Optional. Filter on failures. Use this for individual false positives.
   violationFilter: {},
diff --git a/chrome/tools/build/win/create_installer_archive.py b/chrome/tools/build/win/create_installer_archive.py
index 6175991..d9a9a0e 100755
--- a/chrome/tools/build/win/create_installer_archive.py
+++ b/chrome/tools/build/win/create_installer_archive.py
@@ -94,7 +94,7 @@
 
 
 def CopyAllFilesToStagingDir(config, distribution, staging_dir, build_dir,
-                             enable_hidpi):
+                             enable_hidpi, include_snapshotblob):
   """Copies the files required for installer archive.
   Copies all common files required for various distributions of Chromium and
   also files for the specific Chromium build specified by distribution.
@@ -111,6 +111,9 @@
   if enable_hidpi == '1':
     CopySectionFilesToStagingDir(config, 'HIDPI', staging_dir, build_dir)
 
+  if include_snapshotblob == '1':
+    CopySectionFilesToStagingDir(config, 'SNAPSHOTBLOB', staging_dir, build_dir)
+
 
 def CopySectionFilesToStagingDir(config, section, staging_dir, src_dir):
   """Copies installer archive files specified in section from src_dir to
@@ -516,7 +519,8 @@
   # Copy the files from the build dir.
   CopyAllFilesToStagingDir(config, options.distribution,
                            staging_dir, options.build_dir,
-                           options.enable_hidpi)
+                           options.enable_hidpi,
+                           options.include_snapshotblob)
 
   if options.component_build == '1':
     DoComponentBuildTasks(staging_dir, options.build_dir,
@@ -577,6 +581,8 @@
       help='Name used to prefix names of generated archives.')
   parser.add_option('--enable_hidpi', default='0',
       help='Whether to include HiDPI resource files.')
+  parser.add_option('--include_snapshotblob', default='0',
+      help='Whether to include the V8 snapshot blob.')
   parser.add_option('--component_build', default='0',
       help='Whether this archive is packaging a component build.')
   parser.add_option('--skip_archive_compression',
diff --git a/chromecast/browser/cast_extension_url_loader_factory.cc b/chromecast/browser/cast_extension_url_loader_factory.cc
index 32e5099..bd3fd5f 100644
--- a/chromecast/browser/cast_extension_url_loader_factory.cc
+++ b/chromecast/browser/cast_extension_url_loader_factory.cc
@@ -15,6 +15,7 @@
 #include "content/public/browser/storage_partition.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/info_map.h"
+#include "mojo/public/cpp/bindings/binding.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 
 namespace chromecast {
@@ -231,8 +232,8 @@
 }
 
 void CastExtensionURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest factory_request) {
-  bindings_.AddBinding(this, std::move(factory_request));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory_receiver) {
+  receivers_.Add(this, std::move(factory_receiver));
 }
 
 }  // namespace shell
diff --git a/chromecast/browser/cast_extension_url_loader_factory.h b/chromecast/browser/cast_extension_url_loader_factory.h
index ad90bb0..cf5db53 100644
--- a/chromecast/browser/cast_extension_url_loader_factory.h
+++ b/chromecast/browser/cast_extension_url_loader_factory.h
@@ -8,7 +8,8 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
@@ -46,9 +47,10 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest factory_request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+                 factory_receiver) override;
 
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
   extensions::ExtensionRegistry* extension_registry_;
   std::unique_ptr<network::mojom::URLLoaderFactory> extension_factory_;
   scoped_refptr<network::SharedURLLoaderFactory> network_factory_;
diff --git a/chromecast/browser/cast_network_contexts.cc b/chromecast/browser/cast_network_contexts.cc
index edb6c43..46b316c 100644
--- a/chromecast/browser/cast_network_contexts.cc
+++ b/chromecast/browser/cast_network_contexts.cc
@@ -23,6 +23,7 @@
 #include "content/public/browser/cors_exempt_headers.h"
 #include "content/public/browser/network_service_instance.h"
 #include "content/public/browser/storage_partition.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/network_context.h"
 #include "services/network/public/cpp/cross_thread_shared_url_loader_factory_info.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -57,10 +58,11 @@
         std::move(client), traffic_annotation);
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
     if (!network_context_)
       return;
-    network_context_->GetSystemURLLoaderFactory()->Clone(std::move(request));
+    network_context_->GetSystemURLLoaderFactory()->Clone(std::move(receiver));
   }
 
   // SharedURLLoaderFactory implementation:
diff --git a/chromecast/browser/webview/proto/webview.proto b/chromecast/browser/webview/proto/webview.proto
index 541e806e..666bffa 100644
--- a/chromecast/browser/webview/proto/webview.proto
+++ b/chromecast/browser/webview/proto/webview.proto
@@ -179,6 +179,11 @@
   PREVENT = 1;
 }
 
+message JavascriptChannelMessage {
+  string channel = 1;
+  string message = 2;
+}
+
 message WebviewRequest {
   // Unique identifier for the request. For requests that will have a response,
   // the response id will match the request id.
@@ -239,6 +244,9 @@
     GetTitleResponse get_title = 7;
     // Triggered by web navigation events inside the webview.
     NavigationRequestEvent navigation_event = 9;
+    // Events sents from JS inside of Webviews to the embedder who added JS
+    // channels via AddJavascriptChannelsRequest.
+    JavascriptChannelMessage javascript_channel_message = 10;
   }
 }
 
diff --git a/components/autofill/content/common/mojom/autofill_agent.mojom b/components/autofill/content/common/mojom/autofill_agent.mojom
index ce88fc20..4e8ff31 100644
--- a/components/autofill/content/common/mojom/autofill_agent.mojom
+++ b/components/autofill/content/common/mojom/autofill_agent.mojom
@@ -92,6 +92,8 @@
   // logging the decisions made about saving the password.
   SetLoggingState(bool active);
 
+  // Informs the renderer that the Touch To Fill sheet has been dismissed.
+  TouchToFillDismissed();
 };
 
 // There is one instance of this interface per render frame in the render
diff --git a/components/autofill/content/renderer/PRESUBMIT.py b/components/autofill/content/renderer/PRESUBMIT.py
index 30f2ba54..f17ca91 100644
--- a/components/autofill/content/renderer/PRESUBMIT.py
+++ b/components/autofill/content/renderer/PRESUBMIT.py
@@ -22,9 +22,9 @@
         files.append(f)
 
   if len(files):
-    return [ output_api.PresubmitError(
-        'Do not call IsPasswordField() or FormControlType() directly but ' +
-        'use IsPasswordFieldForAutofill() and FormControlTypeForAutofill() ' +
+    return [ output_api.PresubmitPromptWarning(
+        'Consider to not call IsPasswordField() or FormControlType() directly ' +
+        'but use IsPasswordFieldForAutofill() and FormControlTypeForAutofill() ' +
         'respectively. These declare text input fields as password fields ' +
         'if they have been password fields in the past. This is relevant ' +
         'for websites that allow to reveal passwords with a button that ' +
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
index 7a3b7cf6..37da9887 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -770,9 +770,9 @@
                                   &password_element, &password_info)) {
     return false;
   }
-  if (was_touch_to_fill_ui_shown_)
+
+  if (!should_show_touch_to_fill_)
     return false;
-  was_touch_to_fill_ui_shown_ = true;
 
   GetPasswordManagerDriver()->ShowTouchToFill();
   return true;
@@ -1266,6 +1266,10 @@
   logging_state_active_ = active;
 }
 
+void PasswordAutofillAgent::TouchToFillDismissed() {
+  should_show_touch_to_fill_ = false;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // PasswordAutofillAgent, private:
 
@@ -1326,7 +1330,7 @@
   autofilled_elements_cache_.clear();
   last_updated_field_renderer_id_ = FormData::kNotSetFormRendererId;
   last_updated_form_renderer_id_ = FormData::kNotSetFormRendererId;
-  was_touch_to_fill_ui_shown_ = false;
+  should_show_touch_to_fill_ = true;
 #if !defined(OS_ANDROID) && !defined(OS_IOS)
   page_passwords_analyser_.Reset();
 #endif
diff --git a/components/autofill/content/renderer/password_autofill_agent.h b/components/autofill/content/renderer/password_autofill_agent.h
index 22a03b2..5b5b703 100644
--- a/components/autofill/content/renderer/password_autofill_agent.h
+++ b/components/autofill/content/renderer/password_autofill_agent.h
@@ -129,6 +129,7 @@
   void FillIntoFocusedField(bool is_password,
                             const base::string16& credential) override;
   void SetLoggingState(bool active) override;
+  void TouchToFillDismissed() override;
 
   // FormTracker::Observer
   void OnProvisionallySaveForm(const blink::WebFormElement& form,
@@ -534,7 +535,10 @@
   // Contains renderer id of the form of the last updated input element.
   uint32_t last_updated_form_renderer_id_ = FormData::kNotSetFormRendererId;
 
-  bool was_touch_to_fill_ui_shown_ = false;
+  // Flag that determines whether we instruct the browser to show the Touch To
+  // Fill sheet if applicable. This is set to false when TouchToFillDismissed()
+  // is invoked and gets reset during CleanupOnDocumentShutdown.
+  bool should_show_touch_to_fill_ = true;
 
   DISALLOW_COPY_AND_ASSIGN(PasswordAutofillAgent);
 };
diff --git a/components/autofill_assistant/browser/actions/set_form_field_value_action.cc b/components/autofill_assistant/browser/actions/set_form_field_value_action.cc
index 80552b7..7abd2a8 100644
--- a/components/autofill_assistant/browser/actions/set_form_field_value_action.cc
+++ b/components/autofill_assistant/browser/actions/set_form_field_value_action.cc
@@ -238,6 +238,8 @@
 }
 
 void SetFormFieldValueAction::EndAction(const ClientStatus& status) {
+  // Clear immediately, to prevent sensitive information from staying in memory.
+  field_inputs_.clear();
   UpdateProcessedAction(status);
   std::move(process_action_callback_).Run(std::move(processed_action_proto_));
 }
diff --git a/components/autofill_assistant/browser/actions/set_form_field_value_action.h b/components/autofill_assistant/browser/actions/set_form_field_value_action.h
index b00c045..77398be7 100644
--- a/components/autofill_assistant/browser/actions/set_form_field_value_action.h
+++ b/components/autofill_assistant/browser/actions/set_form_field_value_action.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/callback.h"
+#include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "components/autofill_assistant/browser/actions/action.h"
@@ -24,6 +25,9 @@
   ~SetFormFieldValueAction() override;
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(SetFormFieldValueActionTest,
+                           PasswordIsClearedFromMemory);
+
   // A field input as extracted from the proto, but already checked for
   // validity.
   struct FieldInput {
diff --git a/components/autofill_assistant/browser/actions/set_form_field_value_action_unittest.cc b/components/autofill_assistant/browser/actions/set_form_field_value_action_unittest.cc
index 4ca8944..9abee9a 100644
--- a/components/autofill_assistant/browser/actions/set_form_field_value_action_unittest.cc
+++ b/components/autofill_assistant/browser/actions/set_form_field_value_action_unittest.cc
@@ -24,7 +24,6 @@
 }  // namespace
 
 namespace autofill_assistant {
-namespace {
 
 using ::base::test::RunOnceCallback;
 using ::testing::_;
@@ -222,5 +221,14 @@
   action.ProcessAction(callback_.Get());
 }
 
-}  // namespace
-}  // namespace autofill_assistant
\ No newline at end of file
+TEST_F(SetFormFieldValueActionTest, PasswordIsClearedFromMemory) {
+  auto* value = set_form_field_proto_->add_value();
+  value->set_use_password(true);
+  SetFormFieldValueAction action(&mock_action_delegate_, proto_);
+  ON_CALL(mock_action_delegate_, OnGetFieldValue(_, _))
+      .WillByDefault(RunOnceCallback<1>(true, kFakePassword));
+  action.ProcessAction(callback_.Get());
+  EXPECT_TRUE(action.field_inputs_.empty());
+}
+
+}  // namespace autofill_assistant
diff --git a/components/constrained_window/constrained_window_views.cc b/components/constrained_window/constrained_window_views.cc
index d6f68e0a..34744e4 100644
--- a/components/constrained_window/constrained_window_views.cc
+++ b/components/constrained_window/constrained_window_views.cc
@@ -227,7 +227,7 @@
   views::Widget* widget =
       views::DialogDelegate::CreateDialogWidget(dialog, nullptr, parent_view);
 
-  bool requires_positioning = dialog->ShouldUseCustomFrame();
+  bool requires_positioning = dialog->use_custom_frame();
 
 #if defined(OS_MACOSX)
   // On Mac, window modal dialogs are displayed as sheets, so their position is
diff --git a/components/gcm_driver/gcm_driver_desktop_unittest.cc b/components/gcm_driver/gcm_driver_desktop_unittest.cc
index 0bb3d063..567e854 100644
--- a/components/gcm_driver/gcm_driver_desktop_unittest.cc
+++ b/components/gcm_driver/gcm_driver_desktop_unittest.cc
@@ -618,7 +618,8 @@
   EXPECT_EQ(GCMClient::SUCCESS, registration_result());
 }
 
-TEST_F(GCMDriverFunctionalTest, RegisterError) {
+// This test is flaky, see https://crbug.com/1010462
+TEST_F(GCMDriverFunctionalTest, DISABLED_RegisterError) {
   std::vector<std::string> sender_ids;
   sender_ids.push_back("sender1@error");
   Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
@@ -627,7 +628,8 @@
   EXPECT_NE(GCMClient::SUCCESS, registration_result());
 }
 
-TEST_F(GCMDriverFunctionalTest, RegisterAgainWithSameSenderIDs) {
+// This test is flaky, see https://crbug.com/1010462
+TEST_F(GCMDriverFunctionalTest, DISABLED_RegisterAgainWithSameSenderIDs) {
   std::vector<std::string> sender_ids;
   sender_ids.push_back("sender1");
   sender_ids.push_back("sender2");
@@ -653,7 +655,8 @@
   EXPECT_EQ(GCMClient::SUCCESS, registration_result());
 }
 
-TEST_F(GCMDriverFunctionalTest, RegisterAgainWithDifferentSenderIDs) {
+// This test is flaky, see https://crbug.com/1010462
+TEST_F(GCMDriverFunctionalTest, DISABLED_RegisterAgainWithDifferentSenderIDs) {
   std::vector<std::string> sender_ids;
   sender_ids.push_back("sender1");
   Register(kTestAppID1, sender_ids, GCMDriverTest::WAIT);
@@ -778,7 +781,8 @@
   EXPECT_EQ(GCMClient::SUCCESS, registration_result());
 }
 
-TEST_F(GCMDriverFunctionalTest, RegisterAfterUnfinishedUnregister) {
+// This test is flaky, see https://crbug.com/1010462
+TEST_F(GCMDriverFunctionalTest, DISABLED_RegisterAfterUnfinishedUnregister) {
   // Register and wait for it to complete.
   std::vector<std::string> sender_ids;
   sender_ids.push_back("sender1");
@@ -845,7 +849,8 @@
             gcm_app_handler()->send_error_details().additional_data);
 }
 
-TEST_F(GCMDriverFunctionalTest, MessageReceived) {
+// This test is flaky, see https://crbug.com/1010462
+TEST_F(GCMDriverFunctionalTest, DISABLED_MessageReceived) {
   // GCM registration has to be performed otherwise GCM will not be started.
   Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);
 
@@ -863,7 +868,8 @@
   EXPECT_EQ(message.sender_id, gcm_app_handler()->message().sender_id);
 }
 
-TEST_F(GCMDriverFunctionalTest, MessageWithCollapseKeyReceived) {
+// This test is flaky, see https://crbug.com/1010462
+TEST_F(GCMDriverFunctionalTest, DISABLED_MessageWithCollapseKeyReceived) {
   // GCM registration has to be performed otherwise GCM will not be started.
   Register(kTestAppID1, ToSenderList("sender"), GCMDriverTest::WAIT);
 
@@ -1019,7 +1025,8 @@
   EXPECT_TRUE(syncer()->gcm_enabled());
 }
 
-TEST_F(GCMChannelStatusSyncerTest, DisableRestartAndEnable) {
+// This test is flaky, see https://crbug.com/1010462
+TEST_F(GCMChannelStatusSyncerTest, DISABLED_DisableRestartAndEnable) {
   // Create GCMDriver first. By default, GCM is enabled.
   CreateDriver();
   EXPECT_TRUE(driver()->gcm_enabled());
@@ -1278,7 +1285,9 @@
   EXPECT_TRUE(extra_data().empty());
 }
 
-TEST_F(GCMDriverInstanceIDTest, GCMClientNotReadyBeforeInstanceIDData) {
+// This test is flaky, see https://crbug.com/1010462
+TEST_F(GCMDriverInstanceIDTest,
+       DISABLED_GCMClientNotReadyBeforeInstanceIDData) {
   CreateDriver();
   PumpIOLoop();
   PumpUILoop();
diff --git a/components/gcm_driver/gcm_stats_recorder_impl_unittest.cc b/components/gcm_driver/gcm_stats_recorder_impl_unittest.cc
index 741a854..8d36c10 100644
--- a/components/gcm_driver/gcm_stats_recorder_impl_unittest.cc
+++ b/components/gcm_driver/gcm_stats_recorder_impl_unittest.cc
@@ -425,7 +425,8 @@
   VerifyRecordedSendingCount(0);
 }
 
-TEST_F(GCMStatsRecorderImplTest, CheckinTest) {
+// This test is flaky, see https://crbug.com/1010462
+TEST_F(GCMStatsRecorderImplTest, DISABLED_CheckinTest) {
   recorder_.RecordCheckinInitiated(kAndroidId);
   VerifyRecordedCheckinCount(1);
   VerifyCheckinInitiated("1st call");
diff --git a/components/mirroring/service/fake_network_service.cc b/components/mirroring/service/fake_network_service.cc
index 97f36ac6..80ebddc 100644
--- a/components/mirroring/service/fake_network_service.cc
+++ b/components/mirroring/service/fake_network_service.cc
@@ -5,7 +5,7 @@
 #include "components/mirroring/service/fake_network_service.h"
 
 #include "media/cast/test/utility/net_utility.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "services/network/test/test_url_loader_factory.h"
 
 namespace mirroring {
@@ -67,11 +67,11 @@
 }
 
 void MockNetworkContext::CreateURLLoaderFactory(
-    network::mojom::URLLoaderFactoryRequest request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
     network::mojom::URLLoaderFactoryParamsPtr params) {
   ASSERT_TRUE(params);
-  mojo::MakeStrongBinding(std::make_unique<network::TestURLLoaderFactory>(),
-                          std::move(request));
+  mojo::MakeSelfOwnedReceiver(std::make_unique<network::TestURLLoaderFactory>(),
+                              std::move(receiver));
 }
 
 }  // namespace mirroring
diff --git a/components/mirroring/service/fake_network_service.h b/components/mirroring/service/fake_network_service.h
index d8ef20b..5af9804c 100644
--- a/components/mirroring/service/fake_network_service.h
+++ b/components/mirroring/service/fake_network_service.h
@@ -82,7 +82,7 @@
       mojo::PendingReceiver<network::mojom::UDPSocket> receiver,
       mojo::PendingRemote<network::mojom::UDPSocketListener> listener) override;
   void CreateURLLoaderFactory(
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       network::mojom::URLLoaderFactoryParamsPtr params) override;
 
   MockUdpSocket* udp_socket() const { return udp_socket_.get(); }
diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc
index 8d6b2fc..7f9333fa 100644
--- a/components/omnibox/browser/omnibox_edit_model.cc
+++ b/components/omnibox/browser/omnibox_edit_model.cc
@@ -1178,8 +1178,12 @@
     // If, as a result of the key press, we would select the first result, then
     // we should revert the temporary text same as what pressing escape would
     // have done.
+    //
+    // This doesn't apply for on-focus suggestions, for which the first result
+    // can be completely distinct from the omnibox contents. We enforce that
+    // via user_input_in_progress_, which is false for ZeroSuggest.
     const size_t line_no = GetNewSelectedLine(count);
-    if (has_temporary_text_ && user_input_in_progress_ && line_no == 0) {
+    if (has_temporary_text_ && line_no == 0 && user_input_in_progress_) {
       RevertTemporaryText(true);
     } else {
       popup_model()->MoveTo(line_no);
diff --git a/components/password_manager/content/browser/content_password_manager_driver.cc b/components/password_manager/content/browser/content_password_manager_driver.cc
index cd798f6..4a24acc 100644
--- a/components/password_manager/content/browser/content_password_manager_driver.cc
+++ b/components/password_manager/content/browser/content_password_manager_driver.cc
@@ -130,6 +130,10 @@
       this, form_data, generation_element_id, password);
 }
 
+void ContentPasswordManagerDriver::TouchToFillDismissed() {
+  GetPasswordAutofillAgent()->TouchToFillDismissed();
+}
+
 void ContentPasswordManagerDriver::FillSuggestion(
     const base::string16& username,
     const base::string16& password) {
diff --git a/components/password_manager/content/browser/content_password_manager_driver.h b/components/password_manager/content/browser/content_password_manager_driver.h
index b84c7ea..39d1fde 100644
--- a/components/password_manager/content/browser/content_password_manager_driver.h
+++ b/components/password_manager/content/browser/content_password_manager_driver.h
@@ -62,6 +62,7 @@
   void GeneratedPasswordAccepted(const autofill::FormData& form_data,
                                  uint32_t generation_element_id,
                                  const base::string16& password) override;
+  void TouchToFillDismissed() override;
   void FillSuggestion(const base::string16& username,
                       const base::string16& password) override;
   void FillIntoFocusedField(bool is_password,
diff --git a/components/password_manager/content/browser/content_password_manager_driver_unittest.cc b/components/password_manager/content/browser/content_password_manager_driver_unittest.cc
index aa2255b..ae51e7d 100644
--- a/components/password_manager/content/browser/content_password_manager_driver_unittest.cc
+++ b/components/password_manager/content/browser/content_password_manager_driver_unittest.cc
@@ -84,6 +84,7 @@
   // autofill::mojom::PasswordAutofillAgent:
   MOCK_METHOD1(FillPasswordForm, void(const autofill::PasswordFormFillData&));
   MOCK_METHOD2(FillIntoFocusedField, void(bool, const base::string16&));
+  MOCK_METHOD0(TouchToFillDismissed, void());
 
   MOCK_METHOD0(BlacklistedFormFound, void());
 
diff --git a/components/password_manager/core/browser/credential_cache.cc b/components/password_manager/core/browser/credential_cache.cc
index d3a4d661..5768f487 100644
--- a/components/password_manager/core/browser/credential_cache.cc
+++ b/components/password_manager/core/browser/credential_cache.cc
@@ -27,8 +27,9 @@
   std::vector<CredentialPair> credentials;
   credentials.reserve(best_matches.size());
   for (const PasswordForm* form : best_matches) {
-    credentials.emplace_back(form->username_value, form->password_value,
-                             form->origin, form->is_public_suffix_match);
+    credentials.emplace_back(
+        form->username_value, form->password_value, form->origin,
+        CredentialPair::IsPublicSuffixMatch(form->is_public_suffix_match));
   }
   // Sort by origin, then username.
   std::sort(credentials.begin(), credentials.end(),
diff --git a/components/password_manager/core/browser/credential_cache_unittest.cc b/components/password_manager/core/browser/credential_cache_unittest.cc
index 285786f..ca28ffc 100644
--- a/components/password_manager/core/browser/credential_cache_unittest.cc
+++ b/components/password_manager/core/browser/credential_cache_unittest.cc
@@ -19,6 +19,8 @@
 using base::ASCIIToUTF16;
 using url::Origin;
 
+using IsPublicSuffixMatch = CredentialPair::IsPublicSuffixMatch;
+
 constexpr char kExampleSiteAndroidApp[] = "android://3x4mpl3@com.example.app/";
 constexpr char kExampleSite[] = "https://example.com";
 constexpr char kExampleSite2[] = "https://example.two.com";
@@ -62,29 +64,32 @@
 
           // Alphabetical entries of the exactly matching https://example.com:
           CredentialPair(ASCIIToUTF16("Adam"), ASCIIToUTF16("Pas83B"),
-                         GURL(kExampleSite), /*is_psl_match*/ false),
+                         GURL(kExampleSite), IsPublicSuffixMatch(false)),
           CredentialPair(ASCIIToUTF16("Berta"), ASCIIToUTF16("30948"),
-                         GURL(kExampleSite), /*is_psl_match*/ false),
+                         GURL(kExampleSite), IsPublicSuffixMatch(false)),
           CredentialPair(ASCIIToUTF16("Carl"), ASCIIToUTF16("P1238C"),
-                         GURL(kExampleSite), /*is_psl_match*/ false),
+                         GURL(kExampleSite), IsPublicSuffixMatch(false)),
           CredentialPair(ASCIIToUTF16("Dora"), ASCIIToUTF16("PakudC"),
-                         GURL(kExampleSite), /*is_psl_match*/ false),
+                         GURL(kExampleSite), IsPublicSuffixMatch(false)),
 
           // Entry for PSL-match android://3x4mpl3@com.example.app:
           CredentialPair(ASCIIToUTF16("Cesar"), ASCIIToUTF16("V3V1V"),
-                         GURL(kExampleSiteAndroidApp), /*is_psl_match*/ false),
+                         GURL(kExampleSiteAndroidApp),
+                         IsPublicSuffixMatch(false)),
 
           // Alphabetical entries of PSL-match https://accounts.example.com:
           CredentialPair(ASCIIToUTF16("Elfi"), ASCIIToUTF16("a65ddm"),
-                         GURL(kExampleSiteSubdomain), /*is_psl_match*/ true),
+                         GURL(kExampleSiteSubdomain),
+                         IsPublicSuffixMatch(true)),
           CredentialPair(ASCIIToUTF16("Greg"), ASCIIToUTF16("5fnd1m"),
-                         GURL(kExampleSiteSubdomain), /*is_psl_match*/ true),
+                         GURL(kExampleSiteSubdomain),
+                         IsPublicSuffixMatch(true)),
 
           // Alphabetical entries of PSL-match https://m.example.com:
           CredentialPair(ASCIIToUTF16("Alf"), ASCIIToUTF16("R4nd50m"),
-                         GURL(kExampleSiteMobile), /*is_psl_match*/ true),
+                         GURL(kExampleSiteMobile), IsPublicSuffixMatch(true)),
           CredentialPair(ASCIIToUTF16("Rolf"), ASCIIToUTF16("A4nd0m"),
-                         GURL(kExampleSiteMobile), /*is_psl_match*/ true)));
+                         GURL(kExampleSiteMobile), IsPublicSuffixMatch(true))));
 }
 
 TEST_F(CredentialCacheTest, StoredCredentialsForIndependentOrigins) {
@@ -97,13 +102,13 @@
       {CreateEntry("Abe", "B4dPW", GURL(kExampleSite2), false).first}, origin2);
 
   EXPECT_THAT(cache()->GetCredentialStore(origin).GetCredentials(),
-              testing::ElementsAre(
-                  CredentialPair(ASCIIToUTF16("Ben"), ASCIIToUTF16("S3cur3"),
-                                 GURL(kExampleSite), /*is_psl_match*/ false)));
+              testing::ElementsAre(CredentialPair(
+                  ASCIIToUTF16("Ben"), ASCIIToUTF16("S3cur3"),
+                  GURL(kExampleSite), IsPublicSuffixMatch(false))));
   EXPECT_THAT(cache()->GetCredentialStore(origin2).GetCredentials(),
-              testing::ElementsAre(
-                  CredentialPair(ASCIIToUTF16("Abe"), ASCIIToUTF16("B4dPW"),
-                                 GURL(kExampleSite2), /*is_psl_match*/ false)));
+              testing::ElementsAre(CredentialPair(
+                  ASCIIToUTF16("Abe"), ASCIIToUTF16("B4dPW"),
+                  GURL(kExampleSite2), IsPublicSuffixMatch(false))));
 }
 
 TEST_F(CredentialCacheTest, ClearsCredentials) {
@@ -112,9 +117,9 @@
       {CreateEntry("Ben", "S3cur3", GURL(kExampleSite), false).first},
       Origin::Create(GURL(kExampleSite)));
   ASSERT_THAT(cache()->GetCredentialStore(origin).GetCredentials(),
-              testing::ElementsAre(
-                  CredentialPair(ASCIIToUTF16("Ben"), ASCIIToUTF16("S3cur3"),
-                                 GURL(kExampleSite), /*is_psl_match*/ false)));
+              testing::ElementsAre(CredentialPair(
+                  ASCIIToUTF16("Ben"), ASCIIToUTF16("S3cur3"),
+                  GURL(kExampleSite), IsPublicSuffixMatch(false))));
 
   cache()->ClearCredentials();
   EXPECT_EQ(cache()->GetCredentialStore(origin).GetCredentials().size(), 0u);
diff --git a/components/password_manager/core/browser/leaked_credentials_table.cc b/components/password_manager/core/browser/leaked_credentials_table.cc
index 65d0a1e..9b56d6d 100644
--- a/components/password_manager/core/browser/leaked_credentials_table.cc
+++ b/components/password_manager/core/browser/leaked_credentials_table.cc
@@ -110,9 +110,6 @@
     const base::RepeatingCallback<bool(const GURL&)>& url_filter,
     base::Time remove_begin,
     base::Time remove_end) {
-  if (remove_end.is_null())
-    remove_end = base::Time::Max();
-
   const int64_t remove_begin_us =
       remove_begin.ToDeltaSinceWindowsEpoch().InMicroseconds();
   const int64_t remove_end_us =
diff --git a/components/password_manager/core/browser/leaked_credentials_table.h b/components/password_manager/core/browser/leaked_credentials_table.h
index a4ed2037..6fb5f392 100644
--- a/components/password_manager/core/browser/leaked_credentials_table.h
+++ b/components/password_manager/core/browser/leaked_credentials_table.h
@@ -53,10 +53,9 @@
   bool RemoveRow(const GURL& url, const base::string16& username);
 
   // Removes all leaked credentials created between |remove_begin| inclusive and
-  // |remove_end| exclusive. Using a null Time value will do an unbounded delete
-  // in either direction. If |url_filter| is not null, only leaked credentials
-  // for matching urls are removed. Returns true if the SQL completed
-  // successfully.
+  // |remove_end| exclusive. If |url_filter| is not null, only leaked
+  // credentials for matching urls are removed. Returns true if the SQL
+  // completed successfully.
   bool RemoveRowsByUrlAndTime(
       const base::RepeatingCallback<bool(const GURL&)>& url_filter,
       base::Time remove_begin,
diff --git a/components/password_manager/core/browser/leaked_credentials_table_unittest.cc b/components/password_manager/core/browser/leaked_credentials_table_unittest.cc
index 35f3f63a..1a0d43d 100644
--- a/components/password_manager/core/browser/leaked_credentials_table_unittest.cc
+++ b/components/password_manager/core/browser/leaked_credentials_table_unittest.cc
@@ -170,7 +170,7 @@
                           leaked_credentials3));
 
   EXPECT_TRUE(db()->RemoveRowsByUrlAndTime(base::NullCallback(), base::Time(),
-                                           base::Time()));
+                                           base::Time::Max()));
 
   EXPECT_THAT(db()->GetAllRows(), IsEmpty());
 }
@@ -195,7 +195,7 @@
 
   EXPECT_TRUE(db()->RemoveRowsByUrlAndTime(
       base::BindRepeating(std::not_equal_to<GURL>(), leaked_credentials1.url),
-      base::Time(), base::Time()));
+      base::Time(), base::Time::Max()));
   // With unbounded time range and given url filter all rows that are not
   // matching the |leaked_credentials1.url| should be removed.
   EXPECT_THAT(db()->GetAllRows(),
diff --git a/components/password_manager/core/browser/origin_credential_store.cc b/components/password_manager/core/browser/origin_credential_store.cc
index 9a84515b..f85c096 100644
--- a/components/password_manager/core/browser/origin_credential_store.cc
+++ b/components/password_manager/core/browser/origin_credential_store.cc
@@ -23,7 +23,7 @@
 CredentialPair::CredentialPair(base::string16 username,
                                base::string16 password,
                                const GURL& origin_url,
-                               bool is_public_suffix_match)
+                               IsPublicSuffixMatch is_public_suffix_match)
     : username(std::move(username)),
       password(std::move(password)),
       origin_url(GetAndroidOrOriginURL(origin_url)),
@@ -32,6 +32,7 @@
 CredentialPair::CredentialPair(const CredentialPair&) = default;
 CredentialPair& CredentialPair::operator=(CredentialPair&&) = default;
 CredentialPair& CredentialPair::operator=(const CredentialPair&) = default;
+CredentialPair::~CredentialPair() = default;
 
 bool operator==(const CredentialPair& lhs, const CredentialPair& rhs) {
   return lhs.username == rhs.username && lhs.password == rhs.password &&
diff --git a/components/password_manager/core/browser/origin_credential_store.h b/components/password_manager/core/browser/origin_credential_store.h
index d1d5d29a..a3ab81ec 100644
--- a/components/password_manager/core/browser/origin_credential_store.h
+++ b/components/password_manager/core/browser/origin_credential_store.h
@@ -9,6 +9,7 @@
 
 #include "base/containers/span.h"
 #include "base/strings/string16.h"
+#include "base/util/type_safety/strong_alias.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -16,19 +17,23 @@
 
 // Encapsulates the data from the password manager backend as used by the UI.
 struct CredentialPair {
+  using IsPublicSuffixMatch =
+      util::StrongAlias<class IsPublicSuffixMatchTag, bool>;
+
   CredentialPair(base::string16 username,
                  base::string16 password,
                  const GURL& origin_url,
-                 bool is_public_suffix_match);
+                 IsPublicSuffixMatch is_public_suffix_match);
   CredentialPair(CredentialPair&&);
   CredentialPair(const CredentialPair&);
   CredentialPair& operator=(CredentialPair&&);
   CredentialPair& operator=(const CredentialPair&);
+  ~CredentialPair();
 
   base::string16 username;
   base::string16 password;
   GURL origin_url;  // Could be android:// which url::Origin doesn't support.
-  bool is_public_suffix_match = false;
+  IsPublicSuffixMatch is_public_suffix_match{false};
 };
 
 bool operator==(const CredentialPair& lhs, const CredentialPair& rhs);
diff --git a/components/password_manager/core/browser/origin_credential_store_unittest.cc b/components/password_manager/core/browser/origin_credential_store_unittest.cc
index 99aba3a..15f71e81 100644
--- a/components/password_manager/core/browser/origin_credential_store_unittest.cc
+++ b/components/password_manager/core/browser/origin_credential_store_unittest.cc
@@ -18,13 +18,15 @@
 using base::ASCIIToUTF16;
 using testing::ElementsAre;
 
+using IsPublicSuffixMatch = CredentialPair::IsPublicSuffixMatch;
+
 constexpr char kExampleSite[] = "https://example.com";
 constexpr char kExampleSiteAndroidApp[] = "android://3x4mpl3@com.example.app/";
 
 CredentialPair CreateCredentials(std::string username, std::string password) {
   return CredentialPair(base::ASCIIToUTF16(std::move(username)),
                         base::ASCIIToUTF16(std::move(password)),
-                        GURL(kExampleSite), /*is_psl_match=*/false);
+                        GURL(kExampleSite), IsPublicSuffixMatch(false));
 }
 
 }  // namespace
@@ -53,30 +55,32 @@
 TEST_F(OriginCredentialStoreTest, StoresOnlyNormalizedOrigins) {
   store()->SaveCredentials(
       {CredentialPair(base::ASCIIToUTF16("Berta"), base::ASCIIToUTF16("30948"),
-                      GURL(kExampleSite), /*is_psl_match=*/false),
+                      GURL(kExampleSite), IsPublicSuffixMatch(false)),
        CredentialPair(base::ASCIIToUTF16("Adam"), base::ASCIIToUTF16("Pas83B"),
                       GURL(kExampleSite).Resolve("/agbs"),
-                      /*is_psl_match=*/false),
+                      IsPublicSuffixMatch(false)),
        CredentialPair(base::ASCIIToUTF16("Dora"), base::ASCIIToUTF16("PakudC"),
-                      GURL(kExampleSiteAndroidApp), /*is_psl_match=*/false)});
+                      GURL(kExampleSiteAndroidApp),
+                      IsPublicSuffixMatch(false))});
 
-  EXPECT_THAT(store()->GetCredentials(),
-              ElementsAre(
+  EXPECT_THAT(
+      store()->GetCredentials(),
+      ElementsAre(
 
-                  // The URL that equals an origin stays untouched.
-                  CredentialPair(base::ASCIIToUTF16("Berta"),
-                                 base::ASCIIToUTF16("30948"),
-                                 GURL(kExampleSite), /*is_psl_match=*/false),
+          // The URL that equals an origin stays untouched.
+          CredentialPair(base::ASCIIToUTF16("Berta"),
+                         base::ASCIIToUTF16("30948"), GURL(kExampleSite),
+                         IsPublicSuffixMatch(false)),
 
-                  // The longer URL is reduced to an origin.
-                  CredentialPair(base::ASCIIToUTF16("Adam"),
-                                 base::ASCIIToUTF16("Pas83B"),
-                                 GURL(kExampleSite), /*is_psl_match=*/false),
+          // The longer URL is reduced to an origin.
+          CredentialPair(base::ASCIIToUTF16("Adam"),
+                         base::ASCIIToUTF16("Pas83B"), GURL(kExampleSite),
+                         IsPublicSuffixMatch(false)),
 
-                  // The android origin stays untouched.
-                  CredentialPair(
-                      base::ASCIIToUTF16("Dora"), base::ASCIIToUTF16("PakudC"),
-                      GURL(kExampleSiteAndroidApp), /*is_psl_match=*/false)));
+          // The android origin stays untouched.
+          CredentialPair(
+              base::ASCIIToUTF16("Dora"), base::ASCIIToUTF16("PakudC"),
+              GURL(kExampleSiteAndroidApp), IsPublicSuffixMatch(false))));
 }
 
 TEST_F(OriginCredentialStoreTest, ReplacesCredentials) {
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index c8041da18..26d7d39 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -916,7 +916,7 @@
   // Look for the actually submitted credentials in the list of previously saved
   // credentials that were available to autofilling.
   const PasswordForm* saved_form = password_manager_util::GetMatchForUpdating(
-      *parsed_submitted_form_, ByUsername(GetBestMatches()));
+      *parsed_submitted_form_, GetBestMatches());
   if (saved_form) {
     // A similar credential exists in the store already.
     pending_credentials_ = *saved_form;
@@ -1150,7 +1150,7 @@
 
 void PasswordFormManager::SavePendingToStore(bool update) {
   const PasswordForm* saved_form = password_manager_util::GetMatchForUpdating(
-      *parsed_submitted_form_, ByUsername(GetBestMatches()));
+      *parsed_submitted_form_, GetBestMatches());
   if ((update || password_overridden_) &&
       !pending_credentials_.IsFederatedCredential()) {
     DCHECK(saved_form);
diff --git a/components/password_manager/core/browser/password_manager_driver.h b/components/password_manager/core/browser/password_manager_driver.h
index 46b8ed5..6e076a5 100644
--- a/components/password_manager/core/browser/password_manager_driver.h
+++ b/components/password_manager/core/browser/password_manager_driver.h
@@ -62,6 +62,8 @@
                                          uint32_t generation_element_id,
                                          const base::string16& password) {}
 
+  virtual void TouchToFillDismissed() {}
+
   // Tells the driver to fill the form with the |username| and |password|.
   virtual void FillSuggestion(const base::string16& username,
                               const base::string16& password) = 0;
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc
index 062c3d6..586de4c 100644
--- a/components/password_manager/core/browser/password_manager_util.cc
+++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -60,6 +60,18 @@
          std::make_pair(!rhs->is_public_suffix_match, rhs->date_last_used);
 }
 
+// Returns a form with the given |username_value| from |credentials|, or nullptr
+// if none exists.
+const PasswordForm* FindByUsername(
+    const std::vector<const PasswordForm*>& credentials,
+    const base::string16& username_value) {
+  for (const auto* form : credentials) {
+    if (form->username_value == username_value)
+      return form;
+  }
+  return nullptr;
+}
+
 }  // namespace
 
 // Update |credential| to reflect usage.
@@ -261,7 +273,7 @@
 
 const PasswordForm* GetMatchForUpdating(
     const PasswordForm& submitted_form,
-    const std::map<base::string16, const PasswordForm*>& credentials) {
+    const std::vector<const PasswordForm*>& credentials) {
   // This is the case for the credential management API. It should not depend on
   // form managers. Once that's the case, this should be turned into a DCHECK.
   // TODO(crbug/947030): turn it into a DCHECK.
@@ -269,10 +281,11 @@
     return nullptr;
 
   // Try to return form with matching |username_value|.
-  auto it = credentials.find(submitted_form.username_value);
-  if (it != credentials.end()) {
-    if (!it->second->is_public_suffix_match)
-      return it->second;
+  const PasswordForm* username_match =
+      FindByUsername(credentials, submitted_form.username_value);
+  if (username_match) {
+    if (!username_match->is_public_suffix_match)
+      return username_match;
 
     const auto& password_to_save = submitted_form.new_password_value.empty()
                                        ? submitted_form.password_value
@@ -286,24 +299,25 @@
     // that the autofilled credentials and |submitted_password_form|
     // actually correspond to two different accounts (see
     // http://crbug.com/385619).
-    return password_to_save == it->second->password_value ? it->second
-                                                          : nullptr;
+    return password_to_save == username_match->password_value ? username_match
+                                                              : nullptr;
   }
 
   // Next attempt is to find a match by password value. It should not be tried
   // when the username was actually detected.
   if (submitted_form.type == PasswordForm::Type::kApi ||
-      !submitted_form.username_value.empty())
+      !submitted_form.username_value.empty()) {
     return nullptr;
+  }
 
-  for (const auto& stored_match : credentials) {
-    if (stored_match.second->password_value == submitted_form.password_value)
-      return stored_match.second;
+  for (const PasswordForm* stored_match : credentials) {
+    if (stored_match->password_value == submitted_form.password_value)
+      return stored_match;
   }
 
   // Last try. The submitted form had no username but a password. Assume that
   // it's an existing credential.
-  return credentials.empty() ? nullptr : credentials.begin()->second;
+  return credentials.empty() ? nullptr : credentials.front();
 }
 
 autofill::PasswordForm MakeNormalizedBlacklistedForm(
diff --git a/components/password_manager/core/browser/password_manager_util.h b/components/password_manager/core/browser/password_manager_util.h
index 5c5cc98c..2512b944 100644
--- a/components/password_manager/core/browser/password_manager_util.h
+++ b/components/password_manager/core/browser/password_manager_util.h
@@ -5,7 +5,6 @@
 #ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_MANAGER_UTIL_H_
 #define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_MANAGER_UTIL_H_
 
-#include <map>
 #include <memory>
 #include <vector>
 
@@ -126,7 +125,7 @@
 // PSL and Android matches.
 const autofill::PasswordForm* GetMatchForUpdating(
     const autofill::PasswordForm& submitted_form,
-    const std::map<base::string16, const autofill::PasswordForm*>& credentials);
+    const std::vector<const autofill::PasswordForm*>& credentials);
 
 // This method creates a blacklisted form with |digests|'s scheme, signon_realm
 // and origin. This is done to avoid storing PII and to have a normalized unique
diff --git a/components/password_manager/core/browser/password_manager_util_unittest.cc b/components/password_manager/core/browser/password_manager_util_unittest.cc
index 5dbb4e6f..fcfb646 100644
--- a/components/password_manager/core/browser/password_manager_util_unittest.cc
+++ b/components/password_manager/core/browser/password_manager_util_unittest.cc
@@ -67,16 +67,6 @@
   return form;
 }
 
-std::map<base::string16, const autofill::PasswordForm*> MapFromCredentials(
-    const std::vector<const autofill::PasswordForm*>& forms) {
-  std::map<base::string16, const autofill::PasswordForm*> result;
-  for (const autofill::PasswordForm* form : forms) {
-    auto inserted = result.emplace(form->username_value, form);
-    EXPECT_TRUE(inserted.second);
-  }
-  return result;
-}
-
 }  // namespace
 
 using password_manager::UnorderedPasswordFormElementsAre;
@@ -390,8 +380,7 @@
   autofill::PasswordForm parsed = GetTestCredential();
   parsed.password_value = base::ASCIIToUTF16("new_password");
 
-  EXPECT_EQ(&stored,
-            GetMatchForUpdating(parsed, MapFromCredentials({&stored})));
+  EXPECT_EQ(&stored, GetMatchForUpdating(parsed, {&stored}));
 }
 
 TEST(PasswordManagerUtil, GetMatchForUpdating_RejectUnknownUsername) {
@@ -399,8 +388,7 @@
   autofill::PasswordForm parsed = GetTestCredential();
   parsed.username_value = base::ASCIIToUTF16("other_username");
 
-  EXPECT_EQ(nullptr,
-            GetMatchForUpdating(parsed, MapFromCredentials({&stored})));
+  EXPECT_EQ(nullptr, GetMatchForUpdating(parsed, {&stored}));
 }
 
 TEST(PasswordManagerUtil, GetMatchForUpdating_FederatedCredential) {
@@ -409,8 +397,7 @@
   parsed.password_value.clear();
   parsed.federation_origin = url::Origin::Create(GURL(kTestFederationURL));
 
-  EXPECT_EQ(nullptr,
-            GetMatchForUpdating(parsed, MapFromCredentials({&stored})));
+  EXPECT_EQ(nullptr, GetMatchForUpdating(parsed, {&stored}));
 }
 
 TEST(PasswordManagerUtil, GetMatchForUpdating_MatchUsernamePSL) {
@@ -418,8 +405,7 @@
   stored.is_public_suffix_match = true;
   autofill::PasswordForm parsed = GetTestCredential();
 
-  EXPECT_EQ(&stored,
-            GetMatchForUpdating(parsed, MapFromCredentials({&stored})));
+  EXPECT_EQ(&stored, GetMatchForUpdating(parsed, {&stored}));
 }
 
 TEST(PasswordManagerUtil, GetMatchForUpdating_MatchUsernamePSLAnotherPassword) {
@@ -428,8 +414,7 @@
   autofill::PasswordForm parsed = GetTestCredential();
   parsed.password_value = base::ASCIIToUTF16("new_password");
 
-  EXPECT_EQ(nullptr,
-            GetMatchForUpdating(parsed, MapFromCredentials({&stored})));
+  EXPECT_EQ(nullptr, GetMatchForUpdating(parsed, {&stored}));
 }
 
 TEST(PasswordManagerUtil,
@@ -440,8 +425,7 @@
   parsed.new_password_value = parsed.password_value;
   parsed.password_value.clear();
 
-  EXPECT_EQ(&stored,
-            GetMatchForUpdating(parsed, MapFromCredentials({&stored})));
+  EXPECT_EQ(&stored, GetMatchForUpdating(parsed, {&stored}));
 }
 
 TEST(PasswordManagerUtil,
@@ -452,8 +436,7 @@
   parsed.new_password_value = base::ASCIIToUTF16("new_password");
   parsed.password_value.clear();
 
-  EXPECT_EQ(nullptr,
-            GetMatchForUpdating(parsed, MapFromCredentials({&stored})));
+  EXPECT_EQ(nullptr, GetMatchForUpdating(parsed, {&stored}));
 }
 
 TEST(PasswordManagerUtil, GetMatchForUpdating_EmptyUsernameFindByPassword) {
@@ -461,8 +444,7 @@
   autofill::PasswordForm parsed = GetTestCredential();
   parsed.username_value.clear();
 
-  EXPECT_EQ(&stored,
-            GetMatchForUpdating(parsed, MapFromCredentials({&stored})));
+  EXPECT_EQ(&stored, GetMatchForUpdating(parsed, {&stored}));
 }
 
 TEST(PasswordManagerUtil, GetMatchForUpdating_EmptyUsernameFindByPasswordPSL) {
@@ -471,8 +453,7 @@
   autofill::PasswordForm parsed = GetTestCredential();
   parsed.username_value.clear();
 
-  EXPECT_EQ(&stored,
-            GetMatchForUpdating(parsed, MapFromCredentials({&stored})));
+  EXPECT_EQ(&stored, GetMatchForUpdating(parsed, {&stored}));
 }
 
 TEST(PasswordManagerUtil, GetMatchForUpdating_EmptyUsernameCMAPI) {
@@ -483,8 +464,7 @@
 
   // In case of the Credential Management API we know for sure that the site
   // meant empty username. Don't try any other heuristics.
-  EXPECT_EQ(nullptr,
-            GetMatchForUpdating(parsed, MapFromCredentials({&stored})));
+  EXPECT_EQ(nullptr, GetMatchForUpdating(parsed, {&stored}));
 }
 
 TEST(PasswordManagerUtil, GetMatchForUpdating_EmptyUsernamePickFirst) {
@@ -501,10 +481,9 @@
   autofill::PasswordForm parsed = GetTestCredential();
   parsed.username_value.clear();
 
-  // The credential with the first username is picked.
-  EXPECT_EQ(&stored1,
-            GetMatchForUpdating(
-                parsed, MapFromCredentials({&stored3, &stored2, &stored1})));
+  // The first credential is picked (arbitrarily).
+  EXPECT_EQ(&stored3,
+            GetMatchForUpdating(parsed, {&stored3, &stored2, &stored1}));
 }
 
 TEST(PasswordManagerUtil, MakeNormalizedBlacklistedForm_Android) {
diff --git a/components/performance_manager/performance_manager.cc b/components/performance_manager/performance_manager.cc
index 0ecf1ae..aad56b5 100644
--- a/components/performance_manager/performance_manager.cc
+++ b/components/performance_manager/performance_manager.cc
@@ -21,14 +21,10 @@
                                      GraphCallback callback) {
   DCHECK(callback);
 
-  // Passing |pm| unretained is safe as it is actually destroyed on the
-  // destination sequence, and g_performance_manager.Get() would return nullptr
-  // if its deletion task was already posted.
-  auto* pm = PerformanceManagerImpl::GetInstance();
   // TODO(siggi): Unwrap this by binding the loose param.
-  pm->task_runner_->PostTask(
+  PerformanceManagerImpl::GetTaskRunner()->PostTask(
       from_here, base::BindOnce(&PerformanceManagerImpl::RunCallbackWithGraph,
-                                base::Unretained(pm), std::move(callback)));
+                                std::move(callback)));
 }
 
 // static
@@ -36,14 +32,17 @@
                                      std::unique_ptr<GraphOwned> graph_owned) {
   DCHECK(graph_owned);
 
-  // Passing |graph_| unretained is safe as it is actually destroyed on the
-  // destination sequence, and g_performance_manager.Get() would return nullptr
-  // if its deletion task was already posted.
-  auto* pm = PerformanceManagerImpl::GetInstance();
-  pm->task_runner_->PostTask(
+  // PassToGraph() should only be called when a graph is available to take
+  // ownership of |graph_owned|.
+  DCHECK(IsAvailable());
+
+  PerformanceManagerImpl::CallOnGraphImpl(
       from_here,
-      base::BindOnce(&GraphImpl::PassToGraph, base::Unretained(&pm->graph_),
-                     std::move(graph_owned)));
+      base::BindOnce(
+          [](std::unique_ptr<GraphOwned> graph_owned, GraphImpl* graph) {
+            graph->PassToGraph(std::move(graph_owned));
+          },
+          std::move(graph_owned)));
 }
 
 // static
diff --git a/components/performance_manager/performance_manager_impl.cc b/components/performance_manager/performance_manager_impl.cc
index f639a79..c3cbf5ce 100644
--- a/components/performance_manager/performance_manager_impl.cc
+++ b/components/performance_manager/performance_manager_impl.cc
@@ -12,6 +12,7 @@
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
+#include "base/task/lazy_task_runner.h"
 #include "base/task/post_task.h"
 #include "base/task/task_traits.h"
 #include "components/performance_manager/graph/frame_node_impl.h"
@@ -24,89 +25,76 @@
 
 namespace {
 
-class Singleton {
- public:
-  Singleton() = default;
-  ~Singleton() = default;
+// Singleton instance of PerformanceManagerImpl. Set from
+// PerformanceManagerImpl::StartImpl() and reset from the destructor of
+// PerformanceManagerImpl (PM sequence). Accesses should be on the PM sequence.
+PerformanceManagerImpl* g_performance_manager_from_pm_sequence = nullptr;
 
-  // Safe to call from any thread.
-  PerformanceManagerImpl* Get() {
-    return instance_.load(std::memory_order_acquire);
-  }
+// Singleton instance of PerformanceManagerImpl. Set from Create() and reset
+// from Destroy() (external sequence). Accesses can be on any sequence but must
+// not race with Create() or Destroy().
+//
+// TODO(https://crbug.com/1013127): Get rid of
+// PerformanceManagerImpl::GetInstance(). Callers can probably use
+// PerformanceManagerImpl::CallOnGraphImpl().
+PerformanceManagerImpl* g_performance_manager_from_any_sequence = nullptr;
 
-  // Should be called from the main thread only.
-  void Set(PerformanceManagerImpl* instance) {
-    DCHECK_NE(nullptr, instance);
-    auto* old_value = instance_.exchange(instance, std::memory_order_release);
-    DCHECK_EQ(nullptr, old_value);
-  }
-
-  // Should be called from the main thread only.
-  void Clear(PerformanceManagerImpl* instance) {
-    DCHECK_NE(nullptr, instance);
-    auto* old_value = instance_.exchange(nullptr, std::memory_order_release);
-    DCHECK_EQ(instance, old_value);
-  }
-
- private:
-  std::atomic<PerformanceManagerImpl*> instance_{nullptr};
-};
-Singleton g_performance_manager;
-
-scoped_refptr<base::SequencedTaskRunner> CreateTaskRunner() {
-  return base::CreateSequencedTaskRunner(
-      {base::ThreadPool(), base::TaskPriority::USER_VISIBLE,
-       base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN, base::MayBlock()});
-}
+// The performance manager TaskRunner.
+base::LazySequencedTaskRunner g_performance_manager_task_runner =
+    LAZY_SEQUENCED_TASK_RUNNER_INITIALIZER(
+        base::TaskTraits(base::ThreadPool(),
+                         base::TaskPriority::USER_VISIBLE,
+                         base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
+                         base::MayBlock()));
 
 }  // namespace
 
 PerformanceManagerImpl::~PerformanceManagerImpl() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK_EQ(g_performance_manager_from_pm_sequence, this);
   // TODO(https://crbug.com/966840): Move this to a TearDown function.
   graph_.TearDown();
+  g_performance_manager_from_pm_sequence = nullptr;
 }
 
 // static
 void PerformanceManagerImpl::CallOnGraphImpl(const base::Location& from_here,
                                              GraphImplCallback callback) {
   DCHECK(callback);
-
-  // Passing |pm| unretained is safe as it is actually destroyed on the
-  // destination sequence, and g_performance_manager.Get() would return nullptr
-  // if its deletion task was already posted.
-  auto* pm = g_performance_manager.Get();
-  pm->task_runner_->PostTask(
+  GetTaskRunner()->PostTask(
       from_here,
       base::BindOnce(&PerformanceManagerImpl::RunCallbackWithGraphImpl,
-                     base::Unretained(pm), std::move(callback)));
+                     std::move(callback)));
 }
 
 PerformanceManagerImpl* PerformanceManagerImpl::GetInstance() {
-  return g_performance_manager.Get();
+  return g_performance_manager_from_any_sequence;
 }
 
 // static
 std::unique_ptr<PerformanceManagerImpl> PerformanceManagerImpl::Create(
     GraphImplCallback on_start) {
+  DCHECK(!g_performance_manager_from_any_sequence);
+
   std::unique_ptr<PerformanceManagerImpl> instance =
       base::WrapUnique(new PerformanceManagerImpl());
 
-  instance->task_runner()->PostTask(
+  g_performance_manager_from_any_sequence = instance.get();
+
+  GetTaskRunner()->PostTask(
       FROM_HERE,
       base::BindOnce(&PerformanceManagerImpl::OnStartImpl,
                      base::Unretained(instance.get()), std::move(on_start)));
 
-  g_performance_manager.Set(instance.get());
-
   return instance;
 }
 
 // static
 void PerformanceManagerImpl::Destroy(
     std::unique_ptr<PerformanceManagerImpl> instance) {
-  g_performance_manager.Clear(instance.get());
-  instance->task_runner_->DeleteSoon(FROM_HERE, instance.release());
+  DCHECK_EQ(instance.get(), g_performance_manager_from_any_sequence);
+  g_performance_manager_from_any_sequence = nullptr;
+  GetTaskRunner()->DeleteSoon(FROM_HERE, instance.release());
 }
 
 std::unique_ptr<FrameNodeImpl> PerformanceManagerImpl::CreateFrameNode(
@@ -155,13 +143,12 @@
 
 void PerformanceManagerImpl::BatchDeleteNodes(
     std::vector<std::unique_ptr<NodeBase>> nodes) {
-  task_runner_->PostTask(
+  GetTaskRunner()->PostTask(
       FROM_HERE, base::BindOnce(&PerformanceManagerImpl::BatchDeleteNodesImpl,
                                 base::Unretained(this), std::move(nodes)));
 }
 
-PerformanceManagerImpl::PerformanceManagerImpl()
-    : task_runner_(CreateTaskRunner()) {
+PerformanceManagerImpl::PerformanceManagerImpl() {
   DETACH_FROM_SEQUENCE(sequence_checker_);
 }
 
@@ -187,7 +174,7 @@
     Args&&... constructor_args) {
   std::unique_ptr<NodeType> new_node = std::make_unique<NodeType>(
       &graph_, std::forward<Args>(constructor_args)...);
-  task_runner_->PostTask(
+  GetTaskRunner()->PostTask(
       FROM_HERE, base::BindOnce(&AddNodeAndInvokeCreationCallback<NodeType>,
                                 std::move(creation_callback),
                                 base::Unretained(new_node.get()),
@@ -196,7 +183,7 @@
 }
 
 void PerformanceManagerImpl::PostDeleteNode(std::unique_ptr<NodeBase> node) {
-  task_runner_->PostTask(
+  GetTaskRunner()->PostTask(
       FROM_HERE, base::BindOnce(&PerformanceManagerImpl::DeleteNodeImpl,
                                 base::Unretained(this), std::move(node)));
 }
@@ -269,23 +256,39 @@
   // When |nodes| goes out of scope, all nodes are deleted.
 }
 
-void PerformanceManagerImpl::RunCallbackWithGraphImpl(
-    GraphImplCallback graph_callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-
-  std::move(graph_callback).Run(&graph_);
+// static
+scoped_refptr<base::SequencedTaskRunner>
+PerformanceManagerImpl::GetTaskRunner() {
+  return g_performance_manager_task_runner.Get();
 }
 
+// static
+void PerformanceManagerImpl::RunCallbackWithGraphImpl(
+    GraphImplCallback graph_callback) {
+  DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence());
+
+  if (g_performance_manager_from_pm_sequence) {
+    std::move(graph_callback)
+        .Run(&g_performance_manager_from_pm_sequence->graph_);
+  }
+}
+
+// static
 void PerformanceManagerImpl::RunCallbackWithGraph(
     GraphCallback graph_callback) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(GetTaskRunner()->RunsTasksInCurrentSequence());
 
-  std::move(graph_callback).Run(&graph_);
+  if (g_performance_manager_from_pm_sequence) {
+    std::move(graph_callback)
+        .Run(&g_performance_manager_from_pm_sequence->graph_);
+  }
 }
 
 void PerformanceManagerImpl::OnStartImpl(GraphImplCallback on_start) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  DCHECK(!g_performance_manager_from_pm_sequence);
 
+  g_performance_manager_from_pm_sequence = this;
   graph_.set_ukm_recorder(ukm::UkmRecorder::Get());
   std::move(on_start).Run(&graph_);
 }
diff --git a/components/performance_manager/performance_manager_impl.h b/components/performance_manager/performance_manager_impl.h
index b2c38fc1..2c90fba 100644
--- a/components/performance_manager/performance_manager_impl.h
+++ b/components/performance_manager/performance_manager_impl.h
@@ -40,8 +40,9 @@
   ~PerformanceManagerImpl() override;
 
   // Posts a callback that will run on the PM sequence, and be provided a
-  // pointer to the Graph. Valid to be called from the main thread only, and
-  // only if "IsAvailable" returns true.
+  // pointer to the Graph. Valid to call from any sequence, but |graph_callback|
+  // won't run if this is called before Create() or after Destroy().
+  //
   // TODO(chrisha): Move this to the public interface.
   using GraphImplCallback = base::OnceCallback<void(GraphImpl*)>;
   static void CallOnGraphImpl(const base::Location& from_here,
@@ -57,10 +58,10 @@
       base::OnceCallback<TaskReturnType(GraphImpl*)> task,
       base::OnceCallback<void(TaskReturnType)> reply);
 
-  // Retrieves the currently registered instance.
-  // The caller needs to ensure that the lifetime of the registered instance
-  // exceeds the use of this function and the retrieved pointer.
-  // This function can be called from any sequence with those caveats.
+  // Retrieves the currently registered instance. Calls must not race with
+  // Create() or Destroy(). The returned pointer must not be used after
+  // Destroy(). This function can be called from any sequence with those
+  // caveats.
   static PerformanceManagerImpl* GetInstance();
 
   // Creates, initializes and registers an instance.
@@ -112,17 +113,16 @@
   // in topological order and destroying them.
   void BatchDeleteNodes(std::vector<std::unique_ptr<NodeBase>> nodes);
 
+  // Returns the performance manager TaskRunner.
   // TODO(chrisha): Hide this after the last consumer stops using it!
-  scoped_refptr<base::SequencedTaskRunner> task_runner() const {
-    return task_runner_;
-  }
+  static scoped_refptr<base::SequencedTaskRunner> GetTaskRunner();
 
   content::LockObserver* lock_observer() { return &lock_observer_; }
 
   // Indicates whether or not the caller is currently running on the PM task
   // runner.
   bool OnPMTaskRunnerForTesting() const {
-    return task_runner_->RunsTasksInCurrentSequence();
+    return GetTaskRunner()->RunsTasksInCurrentSequence();
   }
 
  private:
@@ -140,15 +140,13 @@
   void BatchDeleteNodesImpl(std::vector<std::unique_ptr<NodeBase>> nodes);
 
   void OnStartImpl(GraphImplCallback graph_callback);
-  void RunCallbackWithGraphImpl(GraphImplCallback graph_callback);
-  void RunCallbackWithGraph(GraphCallback graph_callback);
+  static void RunCallbackWithGraphImpl(GraphImplCallback graph_callback);
+  static void RunCallbackWithGraph(GraphCallback graph_callback);
 
   template <typename TaskReturnType>
   TaskReturnType RunCallbackWithGraphAndReplyWithResult(
       base::OnceCallback<TaskReturnType(GraphImpl*)> task);
 
-  // The performance task runner.
-  const scoped_refptr<base::SequencedTaskRunner> task_runner_;
   GraphImpl graph_;
 
   // The LockObserver registered with //content to track lock acquisitions.
@@ -171,7 +169,7 @@
     base::OnceCallback<void(TaskReturnType)> reply) {
   auto* pm = GetInstance();
   base::PostTaskAndReplyWithResult(
-      pm->task_runner_.get(), from_here,
+      GetTaskRunner().get(), from_here,
       base::BindOnce(
           &PerformanceManagerImpl::RunCallbackWithGraphAndReplyWithResult<
               TaskReturnType>,
diff --git a/components/performance_manager/performance_manager_tab_helper.cc b/components/performance_manager/performance_manager_tab_helper.cc
index ea2e4a2..afe9062 100644
--- a/components/performance_manager/performance_manager_tab_helper.cc
+++ b/components/performance_manager/performance_manager_tab_helper.cc
@@ -232,7 +232,7 @@
     return;
 
   // Perform the swap in the graph.
-  performance_manager_->task_runner()->PostTask(
+  PerformanceManagerImpl::GetTaskRunner()->PostTask(
       FROM_HERE, base::BindOnce(
                      [](FrameNodeImpl* old_frame, FrameNodeImpl* new_frame) {
                        if (old_frame) {
@@ -393,7 +393,7 @@
                                               Args&&... args) {
   static_assert(std::is_base_of<NodeBase, NodeType>::value,
                 "NodeType must be descended from NodeBase");
-  performance_manager_->task_runner()->PostTask(
+  PerformanceManagerImpl::GetTaskRunner()->PostTask(
       from_here, base::BindOnce(functor, base::Unretained(node),
                                 std::forward<Args>(args)...));
 }
diff --git a/components/performance_manager/performance_manager_tab_helper_unittest.cc b/components/performance_manager/performance_manager_tab_helper_unittest.cc
index 4c05c66f..055ad1c 100644
--- a/components/performance_manager/performance_manager_tab_helper_unittest.cc
+++ b/components/performance_manager/performance_manager_tab_helper_unittest.cc
@@ -9,6 +9,7 @@
 #include "base/run_loop.h"
 #include "base/stl_util.h"
 #include "base/test/bind_test_util.h"
+#include "build/build_config.h"
 #include "components/performance_manager/graph/frame_node_impl.h"
 #include "components/performance_manager/graph/graph_impl_operations.h"
 #include "components/performance_manager/graph/page_node_impl.h"
@@ -218,7 +219,13 @@
 
 }  // namespace
 
-TEST_F(PerformanceManagerTabHelperTest, PageIsAudible) {
+// This test is flaky on windows. See https://1012601
+#if defined(OS_WIN)
+#define MAYBE_PageIsAudible DISABLED_PageIsAudible
+#else
+#define MAYBE_PageIsAudible PageIsAudible
+#endif
+TEST_F(PerformanceManagerTabHelperTest, MAYBE_PageIsAudible) {
   SetContents(CreateTestWebContents());
 
   ExpectPageIsAudible(false);
diff --git a/components/performance_manager/public/performance_manager.h b/components/performance_manager/public/performance_manager.h
index 89bb227..191742c 100644
--- a/components/performance_manager/public/performance_manager.h
+++ b/components/performance_manager/public/performance_manager.h
@@ -26,8 +26,8 @@
   static bool IsAvailable();
 
   // Posts a callback that will run on the PM sequence, and be provided a
-  // pointer to the Graph. Valid to call from the main thread only, and only
-  // if "IsAvailable" returns true.
+  // pointer to the Graph. Valid to call from any sequence, but |graph_callback|
+  // won't run if "IsAvailable" returns false.
   using GraphCallback = base::OnceCallback<void(Graph*)>;
   static void CallOnGraph(const base::Location& from_here,
                           GraphCallback graph_callback);
diff --git a/components/performance_manager/render_process_user_data.cc b/components/performance_manager/render_process_user_data.cc
index d12e161..c095cdc 100644
--- a/components/performance_manager/render_process_user_data.cc
+++ b/components/performance_manager/render_process_user_data.cc
@@ -88,9 +88,6 @@
 
 void RenderProcessUserData::RenderProcessReady(
     content::RenderProcessHost* host) {
-  PerformanceManagerImpl* performance_manager =
-      PerformanceManagerImpl::GetInstance();
-
   const base::Time launch_time =
 #if defined(OS_ANDROID)
       // Process::CreationTime() is not available on Android. Since this
@@ -101,7 +98,7 @@
       host->GetProcess().CreationTime();
 #endif
 
-  performance_manager->task_runner()->PostTask(
+  PerformanceManagerImpl::GetTaskRunner()->PostTask(
       FROM_HERE, base::BindOnce(&ProcessNodeImpl::SetProcess,
                                 base::Unretained(process_node_.get()),
                                 host->GetProcess().Duplicate(), launch_time));
@@ -110,10 +107,7 @@
 void RenderProcessUserData::RenderProcessExited(
     content::RenderProcessHost* host,
     const content::ChildProcessTerminationInfo& info) {
-  PerformanceManagerImpl* performance_manager =
-      PerformanceManagerImpl::GetInstance();
-
-  performance_manager->task_runner()->PostTask(
+  PerformanceManagerImpl::GetTaskRunner()->PostTask(
       FROM_HERE,
       base::BindOnce(&ProcessNodeImpl::SetProcessExitStatus,
                      base::Unretained(process_node_.get()), info.exit_code));
diff --git a/components/query_parser/BUILD.gn b/components/query_parser/BUILD.gn
index c116225..e627455d 100644
--- a/components/query_parser/BUILD.gn
+++ b/components/query_parser/BUILD.gn
@@ -2,6 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//testing/libfuzzer/fuzzer_test.gni")
+
 source_set("query_parser") {
   sources = [
     "query_parser.cc",
@@ -29,3 +31,13 @@
     "//testing/gtest",
   ]
 }
+
+fuzzer_test("query_parser_fuzzer") {
+  sources = [
+    "query_parser_fuzzer.cc",
+  ]
+  deps = [
+    ":query_parser",
+    "//base:base",
+  ]
+}
diff --git a/components/query_parser/query_parser.h b/components/query_parser/query_parser.h
index 5e3f18b..a48973c 100644
--- a/components/query_parser/query_parser.h
+++ b/components/query_parser/query_parser.h
@@ -33,6 +33,7 @@
   DEFAULT,
   // All words are considered for a prefix search.
   ALWAYS_PREFIX_SEARCH,
+  kMaxValue = ALWAYS_PREFIX_SEARCH,
 };
 
 using QueryWordVector = std::vector<query_parser::QueryWord>;
diff --git a/components/query_parser/query_parser_fuzzer.cc b/components/query_parser/query_parser_fuzzer.cc
new file mode 100644
index 0000000..38b1c6f
--- /dev/null
+++ b/components/query_parser/query_parser_fuzzer.cc
@@ -0,0 +1,25 @@
+// Copyright 2019 The Chromium 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 <fuzzer/FuzzedDataProvider.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "base/strings/utf_string_conversions.h"
+#include "components/query_parser/query_parser.h"
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  FuzzedDataProvider data_provider(data, size);
+
+  const query_parser::MatchingAlgorithm matching_alg =
+      data_provider.ConsumeEnum<query_parser::MatchingAlgorithm>();
+  const base::string16 query16(base::UTF8ToUTF16(
+      data_provider.ConsumeBytesAsString(data_provider.remaining_bytes())));
+
+  query_parser::QueryParser parser;
+  std::vector<base::string16> words;
+  parser.ParseQueryWords(query16, matching_alg, &words);
+
+  return 0;
+}
diff --git a/components/resources/components_resources.grd b/components/resources/components_resources.grd
index adff924..78700d9 100644
--- a/components/resources/components_resources.grd
+++ b/components/resources/components_resources.grd
@@ -22,7 +22,6 @@
       <part file="safe_browsing_resources.grdp" />
       <part file="security_interstitials_resources.grdp" />
       <part file="signin_resources.grdp" />
-      <part file="sync_driver_resources.grdp" />
       <part file="translate_resources.grdp" />
       <part file="user_actions_ui_resources.grdp" />
       <part file="version_ui_resources.grdp" />
diff --git a/chrome/app/theme/default_100_percent/chromium/product_logo_white.png b/components/resources/default_100_percent/chromium/product_logo_white.png
similarity index 100%
rename from chrome/app/theme/default_100_percent/chromium/product_logo_white.png
rename to components/resources/default_100_percent/chromium/product_logo_white.png
Binary files differ
diff --git a/chrome/app/theme/default_200_percent/chromium/product_logo_white.png b/components/resources/default_200_percent/chromium/product_logo_white.png
similarity index 100%
rename from chrome/app/theme/default_200_percent/chromium/product_logo_white.png
rename to components/resources/default_200_percent/chromium/product_logo_white.png
Binary files differ
diff --git a/components/resources/sync_driver_resources.grdp b/components/resources/sync_driver_resources.grdp
deleted file mode 100644
index 9c322f5a..0000000
--- a/components/resources/sync_driver_resources.grdp
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<grit-part>
-  <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_INDEX_HTML" file="../sync/driver/resources/index.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" />
-  <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_INDEX_JS" file="../sync/driver/resources/sync_index.js" type="BINDATA" compress="gzip" />
-  <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_CHROME_SYNC_JS" file="../sync/driver/resources/chrome_sync.js" type="BINDATA" compress="gzip" />
-  <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_TYPES_JS" file="../sync/driver/resources/types.js" type="BINDATA" compress="gzip" />
-  <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_LOG_JS" file="../sync/driver/resources/sync_log.js" type="BINDATA" compress="gzip" />
-  <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS" file="../sync/driver/resources/sync_node_browser.js" type="BINDATA" compress="gzip" />
-  <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_SEARCH_JS" file="../sync/driver/resources/sync_search.js" type="BINDATA" compress="gzip" />
-  <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_ABOUT_JS" file="../sync/driver/resources/about.js" type="BINDATA" compress="gzip" />
-  <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_DATA_JS" file="../sync/driver/resources/data.js" type="BINDATA" compress="gzip" />
-  <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_EVENTS_JS" file="../sync/driver/resources/events.js" type="BINDATA" compress="gzip" />
-  <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SEARCH_JS" file="../sync/driver/resources/search.js" type="BINDATA" compress="gzip" />
-  <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_USER_EVENTS_JS" file="../sync/driver/resources/user_events.js" type="BINDATA" compress="gzip" />
-  <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_TRAFFIC_LOG_JS"  file="../sync/driver/resources/traffic_log.js" type="BINDATA" compress="gzip" />
-</grit-part>
diff --git a/components/resources/version_ui_scaled_resources.grdp b/components/resources/version_ui_scaled_resources.grdp
index 06f2a2ba..b199a552 100644
--- a/components/resources/version_ui_scaled_resources.grdp
+++ b/components/resources/version_ui_scaled_resources.grdp
@@ -2,8 +2,10 @@
 <grit-part>
   <if expr="not _google_chrome">
     <structure type="chrome_scaled_image" name="IDR_PRODUCT_LOGO" file="chromium/product_logo.png" />
+    <structure type="chrome_scaled_image" name="IDR_PRODUCT_LOGO_WHITE" file="chromium/product_logo_white.png" />
   </if>
   <if expr="_google_chrome">
     <structure type="chrome_scaled_image" name="IDR_PRODUCT_LOGO" file="google_chrome/product_logo.png" />
+  <structure type="chrome_scaled_image" name="IDR_PRODUCT_LOGO_WHITE" file="google_chrome/product_logo_white.png" />
   </if>
 </grit-part>
diff --git a/components/rlz/DEPS b/components/rlz/DEPS
index 7a00b939..6b1dc7a 100644
--- a/components/rlz/DEPS
+++ b/components/rlz/DEPS
@@ -1,6 +1,7 @@
 include_rules = [
   "+chromeos/system",
   "+components/google",
+  "+mojo/public/cpp/bindings",
   "+net",
   "+rlz",
   "+ui/base",
diff --git a/components/rlz/rlz_tracker.cc b/components/rlz/rlz_tracker.cc
index e166e85..470ee26 100644
--- a/components/rlz/rlz_tracker.cc
+++ b/components/rlz/rlz_tracker.cc
@@ -22,6 +22,7 @@
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
 #include "components/rlz/rlz_tracker_delegate.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 
@@ -195,7 +196,8 @@
                          traffic_annotation));
     }
   }
-  void Clone(network::mojom::URLLoaderFactoryRequest factory) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory)
+      override {
     NOTIMPLEMENTED();
   }
 
diff --git a/components/safe_browsing/browser/safe_browsing_network_context.cc b/components/safe_browsing/browser/safe_browsing_network_context.cc
index d5de6107..14eb5545 100644
--- a/components/safe_browsing/browser/safe_browsing_network_context.cc
+++ b/components/safe_browsing/browser/safe_browsing_network_context.cc
@@ -15,6 +15,7 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/network_context_client_base.h"
 #include "content/public/browser/network_service_instance.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
@@ -80,8 +81,9 @@
         std::move(client), traffic_annotation);
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
-    GetURLLoaderFactory()->Clone(std::move(request));
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
+    GetURLLoaderFactory()->Clone(std::move(receiver));
   }
 
   // network::SharedURLLoaderFactory implementation:
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
index 6b8be382..359ad73 100644
--- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
+++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
@@ -242,7 +242,6 @@
         scoped_refptr<TokenWebData> token_web_data,
         signin::AccountConsistencyMethod account_consistency,
         bool revoke_all_tokens_on_load,
-        bool can_revoke_credentials,
         FixRequestErrorCallback fix_request_error_callback)
     : web_data_service_request_(0),
       backoff_entry_(&backoff_policy_),
@@ -253,7 +252,6 @@
       token_web_data_(token_web_data),
       account_consistency_(account_consistency),
       revoke_all_tokens_on_load_(revoke_all_tokens_on_load),
-      can_revoke_credentials_(can_revoke_credentials),
       fix_request_error_callback_(fix_request_error_callback) {
   VLOG(1) << "MutablePO2TS::MutablePO2TS";
   DCHECK(client);
@@ -735,8 +733,6 @@
 }
 
 void MutableProfileOAuth2TokenServiceDelegate::RevokeAllCredentials() {
-  if (!can_revoke_credentials_)
-    return;
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
   VLOG(1) << "MutablePO2TS::RevokeAllCredentials";
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h
index 41b71cd..67796d20 100644
--- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h
+++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h
@@ -5,7 +5,9 @@
 #ifndef COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_MUTABLE_PROFILE_OAUTH2_TOKEN_SERVICE_DELEGATE_H_
 #define COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_MUTABLE_PROFILE_OAUTH2_TOKEN_SERVICE_DELEGATE_H_
 
+#include <map>
 #include <memory>
+#include <string>
 #include <vector>
 
 #include "base/callback.h"
@@ -39,7 +41,6 @@
       scoped_refptr<TokenWebData> token_web_data,
       signin::AccountConsistencyMethod account_consistency,
       bool revoke_all_tokens_on_load,
-      bool can_revoke_credentials,
       FixRequestErrorCallback fix_request_error_callback);
   ~MutableProfileOAuth2TokenServiceDelegate() override;
 
@@ -229,11 +230,6 @@
   // error state.
   const bool revoke_all_tokens_on_load_;
 
-  // Supervised users cannot revoke credentials.
-  // TODO(droger): remove this when supervised users are no longer supported on
-  // any platform.
-  const bool can_revoke_credentials_;
-
   // Callback function that attempts to correct request errors.  Best effort
   // only.  Returns true if the error was fixed and retry should be reattempted.
   FixRequestErrorCallback fix_request_error_callback_;
diff --git a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
index 336de645..ce3d3cc 100644
--- a/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
+++ b/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
@@ -147,7 +147,6 @@
         client_.get(), &account_tracker_service_,
         network::TestNetworkConnectionTracker::GetInstance(), token_web_data_,
         account_consistency, revoke_all_tokens_on_load_,
-        true /* can_revoke_credantials */,
         MutableProfileOAuth2TokenServiceDelegate::FixRequestErrorCallback());
   }
 
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc b/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc
index 1a3546be..9613765f 100644
--- a/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc
+++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc
@@ -90,7 +90,6 @@
   return std::make_unique<MutableProfileOAuth2TokenServiceDelegate>(
       signin_client, account_tracker_service, network_connection_tracker,
       token_web_data, account_consistency, revoke_all_tokens_on_load,
-      true /* can_revoke_credentials */,
 #if defined(OS_WIN)
       reauth_callback
 #else
diff --git a/components/storage_monitor/storage_monitor_linux_unittest.cc b/components/storage_monitor/storage_monitor_linux_unittest.cc
index a3bc395..00dd8f48 100644
--- a/components/storage_monitor/storage_monitor_linux_unittest.cc
+++ b/components/storage_monitor/storage_monitor_linux_unittest.cc
@@ -337,7 +337,8 @@
 }
 
 // Only removable devices are recognized.
-TEST_F(StorageMonitorLinuxTest, Removable) {
+// This test is flaky, see https://crbug.com/1012211
+TEST_F(StorageMonitorLinuxTest, DISABLED_Removable) {
   base::FilePath test_path_a = CreateMountPointWithDCIMDir(kMountPointA);
   ASSERT_FALSE(test_path_a.empty());
   MtabTestData test_data1[] = {
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn
index 9754803..24bb5a2 100644
--- a/components/sync/BUILD.gn
+++ b/components/sync/BUILD.gn
@@ -590,6 +590,7 @@
     "driver/shared_change_processor_unittest.cc",
     "driver/startup_controller_unittest.cc",
     "driver/sync_auth_manager_unittest.cc",
+    "driver/sync_service_crypto_unittest.cc",
     "driver/sync_service_utils_unittest.cc",
     "driver/sync_session_durations_metrics_recorder_unittest.cc",
     "driver/sync_stopped_reporter_unittest.cc",
diff --git a/components/sync/PRESUBMIT.py b/components/sync/PRESUBMIT.py
index 6df7434..062e29ea 100644
--- a/components/sync/PRESUBMIT.py
+++ b/components/sync/PRESUBMIT.py
@@ -27,9 +27,6 @@
   'SUPERVISED_USER_WHITELISTS',  # See previous.
 
   # Deprecated types:
-  'DEPRECATED_APP_NOTIFICATIONS',
-  'DEPRECATED_SYNCED_NOTIFICATIONS',
-  'DEPRECATED_SYNCED_NOTIFICATION_APP_INFO',
   'DEPRECATED_EXPERIMENTS']
 
 # Root tags are used as prefixes when creating storage keys, so certain strings
@@ -372,8 +369,7 @@
     => 'AppSpecifics'
   """
   return field_number.replace(FIELD_NUMBER_PREFIX, '').replace(
-    'FieldNumber', 'Specifics').replace(
-    'AppNotificationSpecifics', 'AppNotification')
+    'FieldNumber', 'Specifics')
 
 def CheckChangeLintsClean(input_api, output_api):
   source_filter = lambda x: input_api.FilterSourceFile(
diff --git a/components/sync/base/data_type_histogram.h b/components/sync/base/data_type_histogram.h
index 56eac74..066cf46 100644
--- a/components/sync/base/data_type_histogram.h
+++ b/components/sync/base/data_type_histogram.h
@@ -89,18 +89,9 @@
       case ::syncer::EXTENSION_SETTINGS:                       \
         PER_DATA_TYPE_MACRO("ExtensionSettings");              \
         break;                                                 \
-      case ::syncer::DEPRECATED_APP_NOTIFICATIONS:             \
-        PER_DATA_TYPE_MACRO("AppNotifications");               \
-        break;                                                 \
       case ::syncer::HISTORY_DELETE_DIRECTIVES:                \
         PER_DATA_TYPE_MACRO("HistoryDeleteDirectives");        \
         break;                                                 \
-      case ::syncer::DEPRECATED_SYNCED_NOTIFICATIONS:          \
-        PER_DATA_TYPE_MACRO("SyncedNotifications");            \
-        break;                                                 \
-      case ::syncer::DEPRECATED_SYNCED_NOTIFICATION_APP_INFO:  \
-        PER_DATA_TYPE_MACRO("SyncedNotificationAppInfo");      \
-        break;                                                 \
       case ::syncer::DICTIONARY:                               \
         PER_DATA_TYPE_MACRO("Dictionary");                     \
         break;                                                 \
diff --git a/components/sync/base/model_type.cc b/components/sync/base/model_type.cc
index 14552b37..7fdb224 100644
--- a/components/sync/base/model_type.cc
+++ b/components/sync/base/model_type.cc
@@ -9,7 +9,6 @@
 #include "base/stl_util.h"
 #include "base/strings/string_split.h"
 #include "base/values.h"
-#include "components/sync/protocol/app_notification_specifics.pb.h"
 #include "components/sync/protocol/app_setting_specifics.pb.h"
 #include "components/sync/protocol/app_specifics.pb.h"
 #include "components/sync/protocol/autofill_specifics.pb.h"
@@ -107,21 +106,10 @@
      "Extension settings",
      sync_pb::EntitySpecifics::kExtensionSettingFieldNumber,
      ModelTypeForHistograms::kExtensionSettings},
-    {DEPRECATED_APP_NOTIFICATIONS, "APP_NOTIFICATION", "app_notifications",
-     "App Notifications", sync_pb::EntitySpecifics::kAppNotificationFieldNumber,
-     ModelTypeForHistograms::kDeprecatedAppNotifications},
     {HISTORY_DELETE_DIRECTIVES, "HISTORY_DELETE_DIRECTIVE",
      "history_delete_directives", "History Delete Directives",
      sync_pb::EntitySpecifics::kHistoryDeleteDirectiveFieldNumber,
      ModelTypeForHistograms::kHistoryDeleteDirectices},
-    {DEPRECATED_SYNCED_NOTIFICATIONS, "SYNCED_NOTIFICATION",
-     "synced_notifications", "Synced Notifications",
-     sync_pb::EntitySpecifics::kSyncedNotificationFieldNumber,
-     ModelTypeForHistograms::kDeprecatedSyncedNotifications},
-    {DEPRECATED_SYNCED_NOTIFICATION_APP_INFO, "SYNCED_NOTIFICATION_APP_INFO",
-     "synced_notification_app_info", "Synced Notification App Info",
-     sync_pb::EntitySpecifics::kSyncedNotificationAppInfoFieldNumber,
-     ModelTypeForHistograms::kDeprecatedSyncedNotificationAppInfo},
     {DICTIONARY, "DICTIONARY", "dictionary", "Dictionary",
      sync_pb::EntitySpecifics::kDictionaryFieldNumber,
      ModelTypeForHistograms::kDictionary},
@@ -194,11 +182,11 @@
 static_assert(base::size(kModelTypeInfoMap) == ModelType::NUM_ENTRIES,
               "kModelTypeInfoMap should have ModelType::NUM_ENTRIES elements");
 
-static_assert(42 == syncer::ModelType::NUM_ENTRIES,
+static_assert(39 == syncer::ModelType::NUM_ENTRIES,
               "When adding a new type, update enum SyncModelTypes in enums.xml "
               "and suffix SyncModelType in histograms.xml.");
 
-static_assert(42 == syncer::ModelType::NUM_ENTRIES,
+static_assert(39 == syncer::ModelType::NUM_ENTRIES,
               "When adding a new type, update kAllocatorDumpNameWhitelist in "
               "base/trace_event/memory_infra_background_whitelist.cc.");
 
@@ -253,18 +241,9 @@
     case EXTENSION_SETTINGS:
       specifics->mutable_extension_setting();
       break;
-    case DEPRECATED_APP_NOTIFICATIONS:
-      specifics->mutable_app_notification();
-      break;
     case HISTORY_DELETE_DIRECTIVES:
       specifics->mutable_history_delete_directive();
       break;
-    case DEPRECATED_SYNCED_NOTIFICATIONS:
-      specifics->mutable_synced_notification();
-      break;
-    case DEPRECATED_SYNCED_NOTIFICATION_APP_INFO:
-      specifics->mutable_synced_notification_app_info();
-      break;
     case DICTIONARY:
       specifics->mutable_dictionary();
       break;
@@ -370,7 +349,7 @@
 }
 
 ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics) {
-  static_assert(42 == ModelType::NUM_ENTRIES,
+  static_assert(39 == ModelType::NUM_ENTRIES,
                 "When adding new protocol types, the following type lookup "
                 "logic must be updated.");
   if (specifics.has_bookmark())
@@ -403,14 +382,8 @@
     return APP_SETTINGS;
   if (specifics.has_extension_setting())
     return EXTENSION_SETTINGS;
-  if (specifics.has_app_notification())
-    return DEPRECATED_APP_NOTIFICATIONS;
   if (specifics.has_history_delete_directive())
     return HISTORY_DELETE_DIRECTIVES;
-  if (specifics.has_synced_notification())
-    return DEPRECATED_SYNCED_NOTIFICATIONS;
-  if (specifics.has_synced_notification_app_info())
-    return DEPRECATED_SYNCED_NOTIFICATION_APP_INFO;
   if (specifics.has_dictionary())
     return DICTIONARY;
   if (specifics.has_favicon_image())
@@ -456,7 +429,7 @@
 }
 
 ModelTypeSet EncryptableUserTypes() {
-  static_assert(42 == ModelType::NUM_ENTRIES,
+  static_assert(39 == ModelType::NUM_ENTRIES,
                 "If adding an unencryptable type, remove from "
                 "encryptable_user_types below.");
   ModelTypeSet encryptable_user_types = UserTypes();
@@ -464,11 +437,6 @@
   encryptable_user_types.Remove(AUTOFILL_WALLET_DATA);
   // We never encrypt history delete directives.
   encryptable_user_types.Remove(HISTORY_DELETE_DIRECTIVES);
-  // Synced notifications are not encrypted since the server must see changes.
-  encryptable_user_types.Remove(DEPRECATED_SYNCED_NOTIFICATIONS);
-  // Synced Notification App Info does not have private data, so it is not
-  // encrypted.
-  encryptable_user_types.Remove(DEPRECATED_SYNCED_NOTIFICATION_APP_INFO);
   // Device info data is not encrypted because it might be synced before
   // encryption is ready.
   encryptable_user_types.Remove(DEVICE_INFO);
diff --git a/components/sync/base/model_type.h b/components/sync/base/model_type.h
index e239fefe..1ee889c7 100644
--- a/components/sync/base/model_type.h
+++ b/components/sync/base/model_type.h
@@ -92,12 +92,9 @@
   APP_SETTINGS,
   // An extension setting from the extension settings API.
   EXTENSION_SETTINGS,
-  DEPRECATED_APP_NOTIFICATIONS,
   // History delete directives, used to propagate history deletions (e.g. based
   // on a time range).
   HISTORY_DELETE_DIRECTIVES,
-  DEPRECATED_SYNCED_NOTIFICATIONS,
-  DEPRECATED_SYNCED_NOTIFICATION_APP_INFO,
   // Custom spelling dictionary entries.
   DICTIONARY,
   // Favicon images, including both the image URL and the actual pixels.
@@ -251,9 +248,7 @@
       BOOKMARKS, PREFERENCES, PASSWORDS, AUTOFILL_PROFILE, AUTOFILL,
       AUTOFILL_WALLET_DATA, AUTOFILL_WALLET_METADATA, THEMES, TYPED_URLS,
       EXTENSIONS, SEARCH_ENGINES, SESSIONS, APPS, APP_SETTINGS,
-      EXTENSION_SETTINGS, DEPRECATED_APP_NOTIFICATIONS,
-      HISTORY_DELETE_DIRECTIVES, DEPRECATED_SYNCED_NOTIFICATIONS,
-      DEPRECATED_SYNCED_NOTIFICATION_APP_INFO, DICTIONARY, FAVICON_IMAGES,
+      EXTENSION_SETTINGS, HISTORY_DELETE_DIRECTIVES, DICTIONARY, FAVICON_IMAGES,
       FAVICON_TRACKING, DEVICE_INFO, PRIORITY_PREFERENCES,
       SUPERVISED_USER_SETTINGS, APP_LIST, SUPERVISED_USER_WHITELISTS,
       ARC_PACKAGE, PRINTERS, READING_LIST, USER_EVENTS, NIGORI,
diff --git a/components/sync/driver/BUILD.gn b/components/sync/driver/BUILD.gn
index 9c90227..b968b087 100644
--- a/components/sync/driver/BUILD.gn
+++ b/components/sync/driver/BUILD.gn
@@ -4,6 +4,7 @@
 
 import("//build/config/features.gni")
 import("//build/config/jumbo.gni")
+import("//tools/grit/grit_rule.gni")
 
 declare_args() {
   # Controls the product part of the user agent calculated in sync_util.cc.
@@ -89,6 +90,7 @@
     "sync_util.h",
     "syncable_service_based_model_type_controller.cc",
     "syncable_service_based_model_type_controller.h",
+    "trusted_vault_client.h",
   ]
 
   configs += [ "//build/config:precompiled_headers" ]
@@ -134,6 +136,23 @@
   configs += [ "//build/config/compiler:wexit_time_destructors" ]
 }
 
+grit("resources") {
+  source = "resources.grd"
+
+  # The .grd contains references to generated files.
+  source_is_generated = true
+  outputs = [
+    "grit/sync_driver_resources.h",
+    "sync_driver_resources.pak",
+  ]
+  output_dir = "$root_gen_dir/components"
+  depfile_dir = target_gen_dir
+  grit_flags = [
+    "-E",
+    "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir),
+  ]
+}
+
 static_library("test_support") {
   testonly = true
   sources = [
diff --git a/components/sync/driver/glue/sync_engine_impl.cc b/components/sync/driver/glue/sync_engine_impl.cc
index 60c3bd7..46c4314 100644
--- a/components/sync/driver/glue/sync_engine_impl.cc
+++ b/components/sync/driver/glue/sync_engine_impl.cc
@@ -120,12 +120,14 @@
 }
 
 void SyncEngineImpl::AddTrustedVaultDecryptionKeys(
-    const std::vector<std::string>& keys) {
+    const std::vector<std::string>& keys,
+    base::OnceClosure done_cb) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  sync_task_runner_->PostTask(
+  sync_task_runner_->PostTaskAndReply(
       FROM_HERE,
       base::BindOnce(&SyncEngineBackend::DoAddTrustedVaultDecryptionKeys,
-                     backend_, keys));
+                     backend_, keys),
+      std::move(done_cb));
 }
 
 void SyncEngineImpl::StopSyncingForShutdown() {
diff --git a/components/sync/driver/glue/sync_engine_impl.h b/components/sync/driver/glue/sync_engine_impl.h
index 71d2db1b..08e6222 100644
--- a/components/sync/driver/glue/sync_engine_impl.h
+++ b/components/sync/driver/glue/sync_engine_impl.h
@@ -64,8 +64,8 @@
   void StartSyncingWithServer() override;
   void SetEncryptionPassphrase(const std::string& passphrase) override;
   void SetDecryptionPassphrase(const std::string& passphrase) override;
-  void AddTrustedVaultDecryptionKeys(
-      const std::vector<std::string>& keys) override;
+  void AddTrustedVaultDecryptionKeys(const std::vector<std::string>& keys,
+                                     base::OnceClosure done_cb) override;
   void StopSyncingForShutdown() override;
   void Shutdown(ShutdownReason reason) override;
   void ConfigureDataTypes(ConfigureParams params) override;
diff --git a/components/sync/driver/model_association_manager.cc b/components/sync/driver/model_association_manager.cc
index 7734ed2..8d2bec1 100644
--- a/components/sync/driver/model_association_manager.cc
+++ b/components/sync/driver/model_association_manager.cc
@@ -36,16 +36,14 @@
     // in parallel with the UI types.
     PASSWORDS, AUTOFILL, AUTOFILL_PROFILE, AUTOFILL_WALLET_DATA,
     AUTOFILL_WALLET_METADATA, EXTENSION_SETTINGS, APP_SETTINGS, TYPED_URLS,
-    HISTORY_DELETE_DIRECTIVES, DEPRECATED_SYNCED_NOTIFICATIONS,
-    DEPRECATED_SYNCED_NOTIFICATION_APP_INFO,
+    HISTORY_DELETE_DIRECTIVES,
 
     // UI thread data types.
     BOOKMARKS, PREFERENCES, PRIORITY_PREFERENCES, EXTENSIONS, APPS, APP_LIST,
-    ARC_PACKAGE, READING_LIST, THEMES, SEARCH_ENGINES, SESSIONS,
-    DEPRECATED_APP_NOTIFICATIONS, DICTIONARY, FAVICON_IMAGES, FAVICON_TRACKING,
-    PRINTERS, USER_CONSENTS, USER_EVENTS, SUPERVISED_USER_SETTINGS,
-    SUPERVISED_USER_WHITELISTS, MOUNTAIN_SHARES, SEND_TAB_TO_SELF,
-    SECURITY_EVENTS, WEB_APPS, WIFI_CONFIGURATIONS};
+    ARC_PACKAGE, READING_LIST, THEMES, SEARCH_ENGINES, SESSIONS, DICTIONARY,
+    FAVICON_IMAGES, FAVICON_TRACKING, PRINTERS, USER_CONSENTS, USER_EVENTS,
+    SUPERVISED_USER_SETTINGS, SUPERVISED_USER_WHITELISTS, MOUNTAIN_SHARES,
+    SEND_TAB_TO_SELF, SECURITY_EVENTS, WEB_APPS, WIFI_CONFIGURATIONS};
 
 static_assert(base::size(kStartOrder) ==
                   ModelType::NUM_ENTRIES - FIRST_REAL_MODEL_TYPE,
diff --git a/components/sync/driver/profile_sync_service.cc b/components/sync/driver/profile_sync_service.cc
index d1423bf..b20443c 100644
--- a/components/sync/driver/profile_sync_service.cc
+++ b/components/sync/driver/profile_sync_service.cc
@@ -149,7 +149,8 @@
                               base::Unretained(this)),
           base::BindRepeating(&ProfileSyncService::ReconfigureDueToPassphrase,
                               base::Unretained(this)),
-          &sync_prefs_),
+          &sync_prefs_,
+          sync_client_->GetTrustedVaultClient()),
       network_time_update_callback_(
           std::move(init_params.network_time_update_callback)),
       url_loader_factory_(std::move(init_params.url_loader_factory)),
diff --git a/components/sync/driver/resources.grd b/components/sync/driver/resources.grd
new file mode 100644
index 0000000..5b59e1f09
--- /dev/null
+++ b/components/sync/driver/resources.grd
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grit latest_public_release="0"
+      current_release="1"
+      output_all_resource_defines="false">
+  <outputs>
+    <output filename="grit/sync_driver_resources.h" type="rc_header">
+      <emit emit_type='prepend'></emit>
+    </output>
+    <output filename="sync_driver_resources.pak" type="data_package" />
+  </outputs>
+  <release seq="1">
+    <includes>
+      <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_INDEX_HTML" file="resources/index.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" compress="gzip" />
+      <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_INDEX_JS" file="resources/sync_index.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_CHROME_SYNC_JS" file="resources/chrome_sync.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_TYPES_JS" file="resources/types.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_LOG_JS" file="resources/sync_log.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS" file="resources/sync_node_browser.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_SEARCH_JS" file="resources/sync_search.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_ABOUT_JS" file="resources/about.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_DATA_JS" file="resources/data.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_EVENTS_JS" file="resources/events.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SEARCH_JS" file="resources/search.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_USER_EVENTS_JS" file="resources/user_events.js" type="BINDATA" compress="gzip" />
+      <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_TRAFFIC_LOG_JS"  file="resources/traffic_log.js" type="BINDATA" compress="gzip" />
+    </includes>
+  </release>
+</grit>
diff --git a/components/sync/driver/sync_client.h b/components/sync/driver/sync_client.h
index 90db4a2..301f8d5 100644
--- a/components/sync/driver/sync_client.h
+++ b/components/sync/driver/sync_client.h
@@ -27,6 +27,7 @@
 class SyncableService;
 class SyncService;
 class SyncTypePreferenceProvider;
+class TrustedVaultClient;
 
 // Interface for clients of the Sync API to plumb through necessary dependent
 // components. This interface is purely for abstracting dependencies, and
@@ -53,6 +54,7 @@
       SyncService* sync_service) = 0;
 
   virtual invalidation::InvalidationService* GetInvalidationService() = 0;
+  virtual TrustedVaultClient* GetTrustedVaultClient() = 0;
   virtual scoped_refptr<ExtensionsActivity> GetExtensionsActivity() = 0;
 
   // Returns a weak pointer to the syncable service specified by |type|.
diff --git a/components/sync/driver/sync_client_mock.h b/components/sync/driver/sync_client_mock.h
index 2d7d700..fa65fb7 100644
--- a/components/sync/driver/sync_client_mock.h
+++ b/components/sync/driver/sync_client_mock.h
@@ -24,6 +24,7 @@
   MOCK_METHOD0(GetPasswordStateChangedCallback, base::RepeatingClosure());
 
   MOCK_METHOD0(GetInvalidationService, invalidation::InvalidationService*());
+  MOCK_METHOD0(GetTrustedVaultClient, TrustedVaultClient*());
   MOCK_METHOD0(GetExtensionsActivity, scoped_refptr<ExtensionsActivity>());
   MOCK_METHOD1(GetSyncableServiceForType,
                base::WeakPtr<SyncableService>(ModelType type));
diff --git a/components/sync/driver/sync_service_crypto.cc b/components/sync/driver/sync_service_crypto.cc
index 78029e7a..afbe6c62 100644
--- a/components/sync/driver/sync_service_crypto.cc
+++ b/components/sync/driver/sync_service_crypto.cc
@@ -7,14 +7,17 @@
 #include <utility>
 
 #include "base/bind.h"
+#include "base/bind_helpers.h"
 #include "base/feature_list.h"
 #include "base/metrics/histogram_macros.h"
+#include "base/no_destructor.h"
 #include "base/sequenced_task_runner.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "components/sync/base/passphrase_enums.h"
 #include "components/sync/base/sync_prefs.h"
 #include "components/sync/driver/sync_driver_switches.h"
 #include "components/sync/driver/sync_service.h"
+#include "components/sync/driver/trusted_vault_client.h"
 #include "components/sync/engine/sync_string_conversions.h"
 #include "components/sync/nigori/nigori.h"
 
@@ -22,6 +25,23 @@
 
 namespace {
 
+// Used for the case where a null client is passed to SyncServiceCrypto.
+class EmptyTrustedVaultClient : public TrustedVaultClient {
+ public:
+  EmptyTrustedVaultClient() = default;
+  ~EmptyTrustedVaultClient() override = default;
+
+  // TrustedVaultClient implementatio.
+  void FetchKeys(
+      const CoreAccountId& account_id,
+      base::OnceCallback<void(const std::vector<std::string>&)> cb) override {
+    std::move(cb).Run({});
+  }
+
+  void StoreKeys(const CoreAccountId& account_id,
+                 const std::vector<std::string>& keys) override {}
+};
+
 // A SyncEncryptionHandler::Observer implementation that simply posts all calls
 // to another task runner.
 class SyncEncryptionObserverProxy : public SyncEncryptionHandler::Observer {
@@ -112,6 +132,15 @@
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
 };
 
+TrustedVaultClient* ResoveNullClient(TrustedVaultClient* client) {
+  if (client) {
+    return client;
+  }
+
+  static base::NoDestructor<EmptyTrustedVaultClient> empty_client;
+  return empty_client.get();
+}
+
 // Checks if |passphrase| can be used to decrypt the given pending keys. Returns
 // true if decryption was successful. Returns false otherwise. Must be called
 // with non-empty pending keys cache.
@@ -147,13 +176,16 @@
 SyncServiceCrypto::SyncServiceCrypto(
     const base::RepeatingClosure& notify_observers,
     const base::RepeatingCallback<void(ConfigureReason)>& reconfigure,
-    CryptoSyncPrefs* sync_prefs)
+    CryptoSyncPrefs* sync_prefs,
+    TrustedVaultClient* trusted_vault_client)
     : notify_observers_(notify_observers),
       reconfigure_(reconfigure),
-      sync_prefs_(sync_prefs) {
+      sync_prefs_(sync_prefs),
+      trusted_vault_client_(ResoveNullClient(trusted_vault_client)) {
   DCHECK(notify_observers_);
   DCHECK(reconfigure_);
   DCHECK(sync_prefs_);
+  DCHECK(trusted_vault_client_);
 }
 
 SyncServiceCrypto::~SyncServiceCrypto() = default;
@@ -172,6 +204,7 @@
 
   switch (state_.required_user_action) {
     case RequiredUserAction::kNone:
+    case RequiredUserAction::kFetchingTrustedVaultKeys:
     case RequiredUserAction::kTrustedVaultKeyRequired:
       return false;
     case RequiredUserAction::kPassphraseRequiredForDecryption:
@@ -286,8 +319,10 @@
 void SyncServiceCrypto::AddTrustedVaultDecryptionKeys(
     const CoreAccountId& account_id,
     const std::vector<std::string>& keys) {
+  trusted_vault_client_->StoreKeys(account_id, keys);
+
   if (state_.engine && state_.account_id == account_id) {
-    state_.engine->AddTrustedVaultDecryptionKeys(keys);
+    state_.engine->AddTrustedVaultDecryptionKeys(keys, base::DoNothing());
   }
 }
 
@@ -360,19 +395,25 @@
     return;
   }
 
-  state_.required_user_action = RequiredUserAction::kTrustedVaultKeyRequired;
+  state_.required_user_action = RequiredUserAction::kFetchingTrustedVaultKeys;
 
-  // Reconfigure without the encrypted types (excluded implicitly via the
-  // failed datatypes handler).
-  reconfigure_.Run(CONFIGURE_REASON_CRYPTO);
+  trusted_vault_client_->FetchKeys(
+      state_.account_id,
+      base::BindOnce(&SyncServiceCrypto::TrustedVaultKeysFetched,
+                     weak_factory_.GetWeakPtr()));
 }
 
 void SyncServiceCrypto::OnTrustedVaultKeyAccepted() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  if (state_.required_user_action !=
-      RequiredUserAction::kTrustedVaultKeyRequired) {
-    return;
+  switch (state_.required_user_action) {
+    case RequiredUserAction::kNone:
+    case RequiredUserAction::kPassphraseRequiredForDecryption:
+    case RequiredUserAction::kPassphraseRequiredForEncryption:
+      return;
+    case RequiredUserAction::kFetchingTrustedVaultKeys:
+    case RequiredUserAction::kTrustedVaultKeyRequired:
+      break;
   }
 
   state_.required_user_action = RequiredUserAction::kNone;
@@ -450,4 +491,29 @@
       weak_factory_.GetWeakPtr(), base::SequencedTaskRunnerHandle::Get());
 }
 
+void SyncServiceCrypto::TrustedVaultKeysFetched(
+    const std::vector<std::string>& keys) {
+  // The engine could have been shut down while keys were being fetched.
+  if (!state_.engine) {
+    return;
+  }
+
+  state_.engine->AddTrustedVaultDecryptionKeys(
+      keys, base::BindOnce(&SyncServiceCrypto::TrustedVaultKeysAdded,
+                           weak_factory_.GetWeakPtr()));
+}
+
+void SyncServiceCrypto::TrustedVaultKeysAdded() {
+  if (state_.required_user_action !=
+      RequiredUserAction::kFetchingTrustedVaultKeys) {
+    return;
+  }
+
+  // Reaching this codepath indicates OnTrustedVaultKeyAccepted() was not
+  // triggered, so reconfigure without the encrypted types (excluded implicitly
+  // via the failed datatypes handler).
+  state_.required_user_action = RequiredUserAction::kTrustedVaultKeyRequired;
+  reconfigure_.Run(CONFIGURE_REASON_CRYPTO);
+}
+
 }  // namespace syncer
diff --git a/components/sync/driver/sync_service_crypto.h b/components/sync/driver/sync_service_crypto.h
index 786a3ce..7859d350 100644
--- a/components/sync/driver/sync_service_crypto.h
+++ b/components/sync/driver/sync_service_crypto.h
@@ -21,16 +21,21 @@
 namespace syncer {
 
 class CryptoSyncPrefs;
+class TrustedVaultClient;
 
 // This class functions as mostly independent component of SyncService that
 // handles things related to encryption, including holding lots of state and
 // encryption communications with the sync thread.
 class SyncServiceCrypto : public SyncEncryptionHandler::Observer {
  public:
+  // |sync_prefs| must not be null and must outlive this object.
+  // |trusted_vault_client| may be null, but if non-null, the pointee must
+  // outlive this object.
   SyncServiceCrypto(
       const base::RepeatingClosure& notify_observers,
       const base::RepeatingCallback<void(ConfigureReason)>& reconfigure,
-      CryptoSyncPrefs* sync_prefs);
+      CryptoSyncPrefs* sync_prefs,
+      TrustedVaultClient* trusted_vault_client);
   ~SyncServiceCrypto() override;
 
   void Reset();
@@ -84,9 +89,19 @@
     kNone,
     kPassphraseRequiredForDecryption,
     kPassphraseRequiredForEncryption,
+    // Trusted vault keys are required but a silent attempt to fetch keys is in
+    // progress before prompting the user.
+    kFetchingTrustedVaultKeys,
+    // Silent attempt is completed and user action is definitely required to
+    // retrieve trusted vault keys.
     kTrustedVaultKeyRequired,
   };
 
+  // Called at various stages of asynchronously fetching and processing trusted
+  // vault encryption keys.
+  void TrustedVaultKeysFetched(const std::vector<std::string>& keys);
+  void TrustedVaultKeysAdded();
+
   // Calls SyncServiceBase::NotifyObservers(). Never null.
   const base::RepeatingClosure notify_observers_;
 
@@ -96,6 +111,9 @@
   // outlive us.
   CryptoSyncPrefs* const sync_prefs_;
 
+  // Never null and guaranteed to outlive us.
+  TrustedVaultClient* const trusted_vault_client_;
+
   // All the mutable state is wrapped in a struct so that it can be easily
   // reset to its default values.
   struct State {
diff --git a/components/sync/driver/sync_service_crypto_unittest.cc b/components/sync/driver/sync_service_crypto_unittest.cc
new file mode 100644
index 0000000..c37ce666
--- /dev/null
+++ b/components/sync/driver/sync_service_crypto_unittest.cc
@@ -0,0 +1,243 @@
+// Copyright 2019 The Chromium 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 "components/sync/driver/sync_service_crypto.h"
+
+#include <utility>
+
+#include "base/bind_helpers.h"
+#include "base/run_loop.h"
+#include "base/test/mock_callback.h"
+#include "components/sync/base/sync_prefs.h"
+#include "components/sync/driver/trusted_vault_client.h"
+#include "components/sync/engine/mock_sync_engine.h"
+#include "components/sync/nigori/nigori.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace syncer {
+
+namespace {
+
+using testing::_;
+
+sync_pb::EncryptedData MakeEncryptedData(
+    const std::string& passphrase,
+    const KeyDerivationParams& derivation_params) {
+  std::unique_ptr<Nigori> nigori =
+      Nigori::CreateByDerivation(derivation_params, passphrase);
+
+  std::string nigori_name;
+  EXPECT_TRUE(
+      nigori->Permute(Nigori::Type::Password, kNigoriKeyName, &nigori_name));
+
+  const std::string unencrypted = "test";
+  sync_pb::EncryptedData encrypted;
+  encrypted.set_key_name(nigori_name);
+  EXPECT_TRUE(nigori->Encrypt(unencrypted, encrypted.mutable_blob()));
+  return encrypted;
+}
+
+class MockCryptoSyncPrefs : public CryptoSyncPrefs {
+ public:
+  MockCryptoSyncPrefs() = default;
+  ~MockCryptoSyncPrefs() override = default;
+
+  MOCK_CONST_METHOD0(GetEncryptionBootstrapToken, std::string());
+  MOCK_METHOD1(SetEncryptionBootstrapToken, void(const std::string&));
+  MOCK_CONST_METHOD0(GetKeystoreEncryptionBootstrapToken, std::string());
+  MOCK_METHOD1(SetKeystoreEncryptionBootstrapToken, void(const std::string&));
+};
+
+class MockTrustedVaultClient : public TrustedVaultClient {
+ public:
+  MockTrustedVaultClient() = default;
+  ~MockTrustedVaultClient() override = default;
+
+  MOCK_METHOD2(
+      FetchKeys,
+      void(const CoreAccountId& account_id,
+           base::OnceCallback<void(const std::vector<std::string>&)> cb));
+  MOCK_METHOD2(StoreKeys,
+               void(const CoreAccountId& account_id,
+                    const std::vector<std::string>& keys));
+};
+
+class SyncServiceCryptoTest : public testing::Test {
+ protected:
+  SyncServiceCryptoTest()
+      : crypto_(notify_observers_cb_.Get(),
+                reconfigure_cb_.Get(),
+                &prefs_,
+                &trusted_vault_client_) {}
+
+  ~SyncServiceCryptoTest() override = default;
+
+  bool VerifyAndClearExpectations() {
+    return testing::Mock::VerifyAndClearExpectations(&notify_observers_cb_) &&
+           testing::Mock::VerifyAndClearExpectations(&notify_observers_cb_) &&
+           testing::Mock::VerifyAndClearExpectations(&trusted_vault_client_) &&
+           testing::Mock::VerifyAndClearExpectations(&engine_);
+  }
+
+  testing::NiceMock<base::MockCallback<base::RepeatingClosure>>
+      notify_observers_cb_;
+  testing::NiceMock<
+      base::MockCallback<base::RepeatingCallback<void(ConfigureReason)>>>
+      reconfigure_cb_;
+  testing::NiceMock<MockCryptoSyncPrefs> prefs_;
+  testing::NiceMock<MockTrustedVaultClient> trusted_vault_client_;
+  testing::NiceMock<MockSyncEngine> engine_;
+  SyncServiceCrypto crypto_;
+};
+
+TEST_F(SyncServiceCryptoTest, ShouldExposePassphraseRequired) {
+  const std::string kTestPassphrase = "somepassphrase";
+
+  crypto_.SetSyncEngine(CoreAccountId(), &engine_);
+  ASSERT_FALSE(crypto_.IsPassphraseRequired());
+
+  // Mimic the engine determining that a passphrase is required.
+  EXPECT_CALL(reconfigure_cb_, Run(CONFIGURE_REASON_CRYPTO));
+  crypto_.OnPassphraseRequired(
+      REASON_DECRYPTION, KeyDerivationParams::CreateForPbkdf2(),
+      MakeEncryptedData(kTestPassphrase,
+                        KeyDerivationParams::CreateForPbkdf2()));
+  EXPECT_TRUE(crypto_.IsPassphraseRequired());
+  VerifyAndClearExpectations();
+
+  // Entering the wrong passphrase should be rejected.
+  EXPECT_CALL(reconfigure_cb_, Run(_)).Times(0);
+  EXPECT_CALL(engine_, SetDecryptionPassphrase(_)).Times(0);
+  EXPECT_FALSE(crypto_.SetDecryptionPassphrase("wrongpassphrase"));
+  EXPECT_TRUE(crypto_.IsPassphraseRequired());
+
+  // Entering the correct passphrase should be accepted.
+  EXPECT_CALL(engine_, SetDecryptionPassphrase(kTestPassphrase))
+      .WillOnce([&](const std::string&) { crypto_.OnPassphraseAccepted(); });
+  // The current implementation issues two reconfigurations: one immediately
+  // after checking the passphase in the UI thread and a second time later when
+  // the engine confirms with OnPassphraseAccepted().
+  EXPECT_CALL(reconfigure_cb_, Run(CONFIGURE_REASON_CRYPTO)).Times(2);
+  EXPECT_TRUE(crypto_.SetDecryptionPassphrase(kTestPassphrase));
+  EXPECT_FALSE(crypto_.IsPassphraseRequired());
+}
+
+TEST_F(SyncServiceCryptoTest,
+       ShouldStoreTrustedVaultKeysBeforeEngineInitialization) {
+  const CoreAccountId kAccount = CoreAccountId("account1");
+  const std::vector<std::string> kKeys = {"key1"};
+  EXPECT_CALL(trusted_vault_client_, StoreKeys(kAccount, kKeys));
+  crypto_.AddTrustedVaultDecryptionKeys(kAccount, kKeys);
+}
+
+TEST_F(SyncServiceCryptoTest,
+       ShouldStoreTrustedVaultKeysAfterEngineInitialization) {
+  const CoreAccountId kSyncingAccount = CoreAccountId("syncingaccount");
+  const CoreAccountId kOtherAccount = CoreAccountId("otheraccount");
+  const std::vector<std::string> kSyncingAccountKeys = {"key1"};
+  const std::vector<std::string> kOtherAccountKeys = {"key2"};
+
+  crypto_.SetSyncEngine(kSyncingAccount, &engine_);
+
+  EXPECT_CALL(trusted_vault_client_,
+              StoreKeys(kOtherAccount, kOtherAccountKeys));
+  EXPECT_CALL(trusted_vault_client_,
+              StoreKeys(kSyncingAccount, kSyncingAccountKeys));
+
+  // Only the sync-ing account should be propagated to the engine.
+  EXPECT_CALL(engine_, AddTrustedVaultDecryptionKeys(kOtherAccountKeys, _))
+      .Times(0);
+  EXPECT_CALL(engine_, AddTrustedVaultDecryptionKeys(kSyncingAccountKeys, _));
+  crypto_.AddTrustedVaultDecryptionKeys(kOtherAccount, kOtherAccountKeys);
+  crypto_.AddTrustedVaultDecryptionKeys(kSyncingAccount, kSyncingAccountKeys);
+}
+
+TEST_F(SyncServiceCryptoTest, ShouldReadValidTrustedVaultKeysFromClient) {
+  const CoreAccountId kSyncingAccount = CoreAccountId("syncingaccount");
+  const std::vector<std::string> kFetchedKeys = {"key1"};
+
+  EXPECT_CALL(reconfigure_cb_, Run(_)).Times(0);
+  ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
+
+  base::OnceCallback<void(const std::vector<std::string>&)> fetch_keys_cb;
+  EXPECT_CALL(trusted_vault_client_, FetchKeys(kSyncingAccount, _))
+      .WillOnce(
+          [&](const CoreAccountId& account_id,
+              base::OnceCallback<void(const std::vector<std::string>&)> cb) {
+            fetch_keys_cb = std::move(cb);
+          });
+
+  // Mimic the engine determining that trusted vault keys are required.
+  crypto_.SetSyncEngine(kSyncingAccount, &engine_);
+  crypto_.OnTrustedVaultKeyRequired();
+  VerifyAndClearExpectations();
+
+  // While there is an ongoing fetch, there should be no user action required.
+  ASSERT_TRUE(fetch_keys_cb);
+  EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
+
+  base::OnceClosure add_keys_cb;
+  EXPECT_CALL(engine_, AddTrustedVaultDecryptionKeys(kFetchedKeys, _))
+      .WillOnce(
+          [&](const std::vector<std::string>& keys, base::OnceClosure done_cb) {
+            add_keys_cb = std::move(done_cb);
+          });
+
+  // Mimic completion of the fetch.
+  std::move(fetch_keys_cb).Run(kFetchedKeys);
+  ASSERT_TRUE(add_keys_cb);
+  EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
+
+  // Mimic completion of the engine.
+  EXPECT_CALL(reconfigure_cb_, Run(CONFIGURE_REASON_CRYPTO));
+  crypto_.OnTrustedVaultKeyAccepted();
+  std::move(add_keys_cb).Run();
+  EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
+}
+
+TEST_F(SyncServiceCryptoTest, ShouldReadInvalidTrustedVaultKeysFromClient) {
+  const CoreAccountId kSyncingAccount = CoreAccountId("syncingaccount");
+  const std::vector<std::string> kFetchedKeys = {"key1"};
+
+  ASSERT_FALSE(crypto_.IsTrustedVaultKeyRequired());
+
+  base::OnceCallback<void(const std::vector<std::string>&)> fetch_keys_cb;
+  EXPECT_CALL(trusted_vault_client_, FetchKeys(kSyncingAccount, _))
+      .WillOnce(
+          [&](const CoreAccountId& account_id,
+              base::OnceCallback<void(const std::vector<std::string>&)> cb) {
+            fetch_keys_cb = std::move(cb);
+          });
+
+  // Mimic the engine determining that trusted vault keys are required.
+  crypto_.SetSyncEngine(kSyncingAccount, &engine_);
+  crypto_.OnTrustedVaultKeyRequired();
+  VerifyAndClearExpectations();
+
+  // While there is an ongoing fetch, there should be no user action required.
+  ASSERT_TRUE(fetch_keys_cb);
+  EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
+
+  base::OnceClosure add_keys_cb;
+  EXPECT_CALL(engine_, AddTrustedVaultDecryptionKeys(kFetchedKeys, _))
+      .WillOnce(
+          [&](const std::vector<std::string>& keys, base::OnceClosure done_cb) {
+            add_keys_cb = std::move(done_cb);
+          });
+
+  // Mimic completion of the client.
+  std::move(fetch_keys_cb).Run(kFetchedKeys);
+  ASSERT_TRUE(add_keys_cb);
+  EXPECT_FALSE(crypto_.IsTrustedVaultKeyRequired());
+
+  // Mimic completion of the engine, without OnTrustedVaultKeyAccepted().
+  EXPECT_CALL(reconfigure_cb_, Run(CONFIGURE_REASON_CRYPTO));
+  std::move(add_keys_cb).Run();
+  EXPECT_TRUE(crypto_.IsTrustedVaultKeyRequired());
+}
+
+}  // namespace
+
+}  // namespace syncer
diff --git a/components/sync/driver/sync_user_settings_impl.cc b/components/sync/driver/sync_user_settings_impl.cc
index ac25c91..d336fa95 100644
--- a/components/sync/driver/sync_user_settings_impl.cc
+++ b/components/sync/driver/sync_user_settings_impl.cc
@@ -197,7 +197,7 @@
     types.RetainAll(registered_model_types_);
   }
 
-  static_assert(42 == ModelType::NUM_ENTRIES,
+  static_assert(39 == ModelType::NUM_ENTRIES,
                 "If adding a new sync data type, update the list below below if"
                 " you want to disable the new data type for local sync.");
   types.PutAll(ControlTypes());
diff --git a/components/sync/driver/sync_user_settings_unittest.cc b/components/sync/driver/sync_user_settings_unittest.cc
index bfdcea9..468ea6f 100644
--- a/components/sync/driver/sync_user_settings_unittest.cc
+++ b/components/sync/driver/sync_user_settings_unittest.cc
@@ -33,7 +33,8 @@
 
     sync_service_crypto_ = std::make_unique<SyncServiceCrypto>(
         /*notify_observers=*/base::DoNothing(),
-        /*reconfigure=*/base::DoNothing(), sync_prefs_.get());
+        /*reconfigure=*/base::DoNothing(), sync_prefs_.get(),
+        /*trusted_vault_client=*/nullptr);
   }
 
   std::unique_ptr<SyncUserSettingsImpl> MakeSyncUserSettings(
diff --git a/components/sync/driver/trusted_vault_client.h b/components/sync/driver/trusted_vault_client.h
new file mode 100644
index 0000000..3ac50ad
--- /dev/null
+++ b/components/sync/driver/trusted_vault_client.h
@@ -0,0 +1,45 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SYNC_DRIVER_TRUSTED_VAULT_CLIENT_H_
+#define COMPONENTS_SYNC_DRIVER_TRUSTED_VAULT_CLIENT_H_
+
+#include <string>
+#include <vector>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+
+struct CoreAccountId;
+
+namespace syncer {
+
+// Interface that allows platform-specific logic related to accessing locally
+// available trusted vault encryption keys.
+class TrustedVaultClient {
+ public:
+  TrustedVaultClient() = default;
+  virtual ~TrustedVaultClient() = default;
+
+  // Attempts to fetch decryption keys, required by sync to resume.
+  // Implementations are expected to NOT prompt the user for actions. |cb| is
+  // called on completion with known keys or an empty list if none known.
+  virtual void FetchKeys(
+      const CoreAccountId& account_id,
+      base::OnceCallback<void(const std::vector<std::string>&)> cb) = 0;
+
+  // Allows implementations to store encryption keys fetched by other means such
+  // as Web interactions. Implementations are free to completely ignore these
+  // keys, so callers may not assume that later calls to FetchKeys() would
+  // necessarily return the keys passed here.
+  virtual void StoreKeys(const CoreAccountId& account_id,
+                         const std::vector<std::string>& keys) = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TrustedVaultClient);
+};
+
+}  // namespace syncer
+
+#endif  // COMPONENTS_SYNC_DRIVER_TRUSTED_VAULT_CLIENT_H_
diff --git a/components/sync/engine/fake_sync_engine.cc b/components/sync/engine/fake_sync_engine.cc
index 9318db8..c274449 100644
--- a/components/sync/engine/fake_sync_engine.cc
+++ b/components/sync/engine/fake_sync_engine.cc
@@ -4,6 +4,8 @@
 
 #include "components/sync/engine/fake_sync_engine.h"
 
+#include <utility>
+
 #include "components/sync/engine/data_type_activation_response.h"
 #include "components/sync/engine/sync_engine_host.h"
 #include "components/sync/model/model_type_controller_delegate.h"
@@ -47,7 +49,10 @@
 void FakeSyncEngine::SetDecryptionPassphrase(const std::string& passphrase) {}
 
 void FakeSyncEngine::AddTrustedVaultDecryptionKeys(
-    const std::vector<std::string>& keys) {}
+    const std::vector<std::string>& keys,
+    base::OnceClosure done_cb) {
+  std::move(done_cb).Run();
+}
 
 void FakeSyncEngine::StopSyncingForShutdown() {}
 
diff --git a/components/sync/engine/fake_sync_engine.h b/components/sync/engine/fake_sync_engine.h
index 0665e80..c6ced2a 100644
--- a/components/sync/engine/fake_sync_engine.h
+++ b/components/sync/engine/fake_sync_engine.h
@@ -46,8 +46,8 @@
 
   void SetDecryptionPassphrase(const std::string& passphrase) override;
 
-  void AddTrustedVaultDecryptionKeys(
-      const std::vector<std::string>& keys) override;
+  void AddTrustedVaultDecryptionKeys(const std::vector<std::string>& keys,
+                                     base::OnceClosure done_cb) override;
 
   void StopSyncingForShutdown() override;
 
diff --git a/components/sync/engine/mock_sync_engine.h b/components/sync/engine/mock_sync_engine.h
index 808207d..49ad0315 100644
--- a/components/sync/engine/mock_sync_engine.h
+++ b/components/sync/engine/mock_sync_engine.h
@@ -45,8 +45,8 @@
   MOCK_METHOD0(StartSyncingWithServer, void());
   MOCK_METHOD1(SetEncryptionPassphrase, void(const std::string&));
   MOCK_METHOD1(SetDecryptionPassphrase, void(const std::string&));
-  MOCK_METHOD1(AddTrustedVaultDecryptionKeys,
-               void(const std::vector<std::string>&));
+  MOCK_METHOD2(AddTrustedVaultDecryptionKeys,
+               void(const std::vector<std::string>&, base::OnceClosure));
   MOCK_METHOD0(StopSyncingForShutdown, void());
   MOCK_METHOD1(Shutdown, void(ShutdownReason));
   MOCK_METHOD0(EnableEncryptEverything, void());
diff --git a/components/sync/engine/sync_engine.h b/components/sync/engine/sync_engine.h
index 5037d65..41b2d99 100644
--- a/components/sync/engine/sync_engine.h
+++ b/components/sync/engine/sync_engine.h
@@ -139,9 +139,10 @@
   // TRUSTED_VAULT_PASSPHRASE: it provides new decryption keys that could
   // allow decrypting pending Nigori keys. Notifies observers of the result of
   // the operation via OnTrustedVaultKeyAccepted if the provided keys
-  // successfully decrypted pending keys.
+  // successfully decrypted pending keys. |done_cb| is invoked at the very end.
   virtual void AddTrustedVaultDecryptionKeys(
-      const std::vector<std::string>& keys) = 0;
+      const std::vector<std::string>& keys,
+      base::OnceClosure done_cb) = 0;
 
   // Kick off shutdown procedure. Attempts to cut short any long-lived or
   // blocking sync thread tasks so that the shutdown on sync thread task that
diff --git a/components/sync/nigori/nigori_sync_bridge_impl.cc b/components/sync/nigori/nigori_sync_bridge_impl.cc
index 7ae269fb..e5d564f 100644
--- a/components/sync/nigori/nigori_sync_bridge_impl.cc
+++ b/components/sync/nigori/nigori_sync_bridge_impl.cc
@@ -400,7 +400,7 @@
 void UpdateNigoriSpecificsFromEncryptedTypes(
     ModelTypeSet encrypted_types,
     sync_pb::NigoriSpecifics* specifics) {
-  static_assert(42 == ModelType::NUM_ENTRIES,
+  static_assert(39 == ModelType::NUM_ENTRIES,
                 "If adding an encryptable type, update handling below.");
   specifics->set_encrypt_bookmarks(encrypted_types.Has(BOOKMARKS));
   specifics->set_encrypt_preferences(encrypted_types.Has(PREFERENCES));
@@ -418,8 +418,6 @@
   specifics->set_encrypt_app_settings(encrypted_types.Has(APP_SETTINGS));
   specifics->set_encrypt_extension_settings(
       encrypted_types.Has(EXTENSION_SETTINGS));
-  specifics->set_encrypt_app_notifications(
-      encrypted_types.Has(DEPRECATED_APP_NOTIFICATIONS));
   specifics->set_encrypt_dictionary(encrypted_types.Has(DICTIONARY));
   specifics->set_encrypt_favicon_images(encrypted_types.Has(FAVICON_IMAGES));
   specifics->set_encrypt_favicon_tracking(
diff --git a/components/sync/protocol/nigori_specifics.proto b/components/sync/protocol/nigori_specifics.proto
index 54b4ab9..a72dbfc 100644
--- a/components/sync/protocol/nigori_specifics.proto
+++ b/components/sync/protocol/nigori_specifics.proto
@@ -75,7 +75,9 @@
   optional bool encrypt_everything = 24;
 
   optional bool encrypt_extension_settings = 25;
+
   optional bool encrypt_app_notifications = 26 [deprecated = true];
+
   optional bool encrypt_app_settings = 27;
 
   // User device information. Contains information about each device that has a
diff --git a/components/sync/protocol/proto_value_conversions_unittest.cc b/components/sync/protocol/proto_value_conversions_unittest.cc
index 2e3e59b..5ba9ca804 100644
--- a/components/sync/protocol/proto_value_conversions_unittest.cc
+++ b/components/sync/protocol/proto_value_conversions_unittest.cc
@@ -56,7 +56,7 @@
 
 DEFINE_SPECIFICS_TO_VALUE_TEST(encrypted)
 
-static_assert(42 == syncer::ModelType::NUM_ENTRIES,
+static_assert(39 == syncer::ModelType::NUM_ENTRIES,
               "When adding a new field, add a DEFINE_SPECIFICS_TO_VALUE_TEST "
               "for your field below, and optionally a test for the specific "
               "conversions.");
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h
index 2199676a..57601078 100644
--- a/components/sync/protocol/proto_visitors.h
+++ b/components/sync/protocol/proto_visitors.h
@@ -362,7 +362,7 @@
 }
 
 VISIT_PROTO_FIELDS(const sync_pb::EntitySpecifics& proto) {
-  static_assert(42 == ModelType::NUM_ENTRIES,
+  static_assert(39 == ModelType::NUM_ENTRIES,
                 "When adding a new protocol type, you will likely need to add "
                 "it here as well.");
   VISIT(encrypted);
diff --git a/components/sync/protocol/sync.proto b/components/sync/protocol/sync.proto
index c041290..20ab560 100644
--- a/components/sync/protocol/sync.proto
+++ b/components/sync/protocol/sync.proto
@@ -115,7 +115,9 @@
     PreferenceSpecifics preference = 37702;
     TypedUrlSpecifics typed_url = 40781;
     ThemeSpecifics theme = 41210;
-    AppNotification app_notification = 45184;
+    // TODO(crbug.com/1012648): |app_notification| isn't used by the client
+    // anymore, but the server still needs it for now.
+    AppNotification app_notification = 45184 [deprecated = true];
     PasswordSpecifics password = 45873;
     NigoriSpecifics nigori = 47745;
     ExtensionSpecifics extension = 48119;
@@ -126,8 +128,13 @@
     ExtensionSettingSpecifics extension_setting = 96159;
     AppSettingSpecifics app_setting = 103656;
     HistoryDeleteDirectiveSpecifics history_delete_directive = 150251;
-    SyncedNotificationSpecifics synced_notification = 153108;
-    SyncedNotificationAppInfoSpecifics synced_notification_app_info = 235816;
+    // TODO(crbug.com/1012648): |synced_notification| and
+    // |synced_notification_app_info| aren't used by the client anymore, but the
+    // server still needs them for now.
+    SyncedNotificationSpecifics synced_notification = 153108
+        [deprecated = true];
+    SyncedNotificationAppInfoSpecifics synced_notification_app_info = 235816
+        [deprecated = true];
     DeviceInfoSpecifics device_info = 154522;
     ExperimentsSpecifics experiments = 161496;
     PriorityPreferenceSpecifics priority_preference = 163425;
diff --git a/components/sync/syncable/nigori_util.cc b/components/sync/syncable/nigori_util.cc
index 352b8acd..a4d62e7 100644
--- a/components/sync/syncable/nigori_util.cc
+++ b/components/sync/syncable/nigori_util.cc
@@ -265,7 +265,7 @@
                                     bool encrypt_everything,
                                     sync_pb::NigoriSpecifics* nigori) {
   nigori->set_encrypt_everything(encrypt_everything);
-  static_assert(42 == ModelType::NUM_ENTRIES,
+  static_assert(39 == ModelType::NUM_ENTRIES,
                 "If adding an encryptable type, update handling below.");
   nigori->set_encrypt_bookmarks(encrypted_types.Has(BOOKMARKS));
   nigori->set_encrypt_preferences(encrypted_types.Has(PREFERENCES));
@@ -282,8 +282,6 @@
   nigori->set_encrypt_app_settings(encrypted_types.Has(APP_SETTINGS));
   nigori->set_encrypt_extension_settings(
       encrypted_types.Has(EXTENSION_SETTINGS));
-  nigori->set_encrypt_app_notifications(
-      encrypted_types.Has(DEPRECATED_APP_NOTIFICATIONS));
   nigori->set_encrypt_dictionary(encrypted_types.Has(DICTIONARY));
   nigori->set_encrypt_favicon_images(encrypted_types.Has(FAVICON_IMAGES));
   nigori->set_encrypt_favicon_tracking(encrypted_types.Has(FAVICON_TRACKING));
@@ -302,7 +300,7 @@
     return ModelTypeSet::All();
 
   ModelTypeSet encrypted_types;
-  static_assert(42 == ModelType::NUM_ENTRIES,
+  static_assert(39 == ModelType::NUM_ENTRIES,
                 "If adding an encryptable type, update handling below.");
   if (nigori.encrypt_bookmarks())
     encrypted_types.Put(BOOKMARKS);
@@ -330,8 +328,6 @@
     encrypted_types.Put(APP_SETTINGS);
   if (nigori.encrypt_extension_settings())
     encrypted_types.Put(EXTENSION_SETTINGS);
-  if (nigori.encrypt_app_notifications())
-    encrypted_types.Put(DEPRECATED_APP_NOTIFICATIONS);
   if (nigori.encrypt_dictionary())
     encrypted_types.Put(DICTIONARY);
   if (nigori.encrypt_favicon_images())
diff --git a/components/version_ui/resources/about_version.css b/components/version_ui/resources/about_version.css
index 7c247b6..bd7da3a 100644
--- a/components/version_ui/resources/about_version.css
+++ b/components/version_ui/resources/about_version.css
@@ -2,9 +2,23 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file. */
 
+html {
+  --google-grey-200: rgb(232, 234, 237);
+  --google-grey-900: rgb(32, 33, 36);
+
+  --primary-color: var(--google-grey-900);
+  background: white;
+}
+
+@media (prefers-color-scheme: dark) {
+  html {
+    --primary-color: var(--google-grey-200);
+    background: var(--google-grey-900);
+  }
+}
+
 body {
-  background-color: white;
-  color: black;
+  color: var(--primary-color);
   font-size: 100%;
   margin: 0;
 }
diff --git a/components/version_ui/resources/about_version.html b/components/version_ui/resources/about_version.html
index 9441e42..182f7c4 100644
--- a/components/version_ui/resources/about_version.html
+++ b/components/version_ui/resources/about_version.html
@@ -36,10 +36,18 @@
       <div id="logo">
 <if expr="not is_android and not is_ios">
         <!-- Version for themes. -->
-        <img src="chrome://theme/IDR_PRODUCT_LOGO">
+        <picture>
+          <source srcset="chrome://theme/IDR_PRODUCT_LOGO_WHITE" media="(prefers-color-scheme: dark)">
+          <source srcset="chrome://theme/IDR_PRODUCT_LOGO" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)">
+          <img src="chrome://theme/IDR_PRODUCT_LOGO">
+        </picture>
 </if>
 <if expr="is_ios or is_android">
-        <img src="../../../components/resources/default_100_percent/%DISTRIBUTION%/product_logo.png">
+        <picture>
+          <source srcset="../../../components/resources/default_100_percent/%DISTRIBUTION%/product_logo_white.png" media="(prefers-color-scheme: dark)">
+          <source srcset="../../../components/resources/default_100_percent/%DISTRIBUTION%/product_logo.png" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)">
+          <img src="../../../components/resources/default_100_percent/%DISTRIBUTION%/product_logo.png">
+        </picture>
 </if>
         <div id="company">$i18n{company}</div>
         <div id="copyright">$i18n{copyright}</div>
diff --git a/content/browser/DEPS b/content/browser/DEPS
index f5db6d0..cf3c7ede 100644
--- a/content/browser/DEPS
+++ b/content/browser/DEPS
@@ -118,7 +118,6 @@
   "+third_party/blink/public/platform/web_text_input_type.h",
   "+third_party/blink/public/platform/mac/web_scrollbar_theme.h",
   "+third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h",
-  "+third_party/blink/public/platform/modules/notifications/web_notification_constants.h",
   "+third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h",
   "+third_party/blink/public/platform/modules/sms/sms_receiver.mojom.h",
   "+third_party/blink/public/public_buildflags.h",
diff --git a/content/browser/about_url_loader_factory.cc b/content/browser/about_url_loader_factory.cc
index ed65bb5..d78311dc 100644
--- a/content/browser/about_url_loader_factory.cc
+++ b/content/browser/about_url_loader_factory.cc
@@ -39,8 +39,8 @@
 }
 
 void AboutURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest loader) {
-  bindings_.AddBinding(this, std::move(loader));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) {
+  receivers_.Add(this, std::move(loader));
 }
 
 }  // namespace content
diff --git a/content/browser/about_url_loader_factory.h b/content/browser/about_url_loader_factory.h
index 3b20b1a..68ab970 100644
--- a/content/browser/about_url_loader_factory.h
+++ b/content/browser/about_url_loader_factory.h
@@ -6,7 +6,8 @@
 #define CONTENT_BROWSER_ABOUT_URL_LOADER_FACTORY_H_
 
 #include "base/macros.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
 namespace content {
@@ -29,9 +30,10 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest loader) override;
+  void Clone(
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) override;
 
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   DISALLOW_COPY_AND_ASSIGN(AboutURLLoaderFactory);
 };
diff --git a/content/browser/android/content_url_loader_factory.cc b/content/browser/android/content_url_loader_factory.cc
index 52f1d381..1f29596 100644
--- a/content/browser/android/content_url_loader_factory.cc
+++ b/content/browser/android/content_url_loader_factory.cc
@@ -19,6 +19,7 @@
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/file_url_loader.h"
 #include "content/public/common/content_client.h"
+#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "mojo/public/cpp/system/data_pipe_producer.h"
 #include "mojo/public/cpp/system/file_data_source.h"
@@ -286,8 +287,8 @@
 }
 
 void ContentURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest loader) {
-  bindings_.AddBinding(this, std::move(loader));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) {
+  receivers_.Add(this, std::move(loader));
 }
 
 }  // namespace content
diff --git a/content/browser/android/content_url_loader_factory.h b/content/browser/android/content_url_loader_factory.h
index 8cbe8c6..c5bce0ff 100644
--- a/content/browser/android/content_url_loader_factory.h
+++ b/content/browser/android/content_url_loader_factory.h
@@ -8,7 +8,8 @@
 #include "base/macros.h"
 #include "base/sequenced_task_runner.h"
 #include "content/common/content_export.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
 namespace content {
@@ -34,10 +35,11 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest loader) override;
+  void Clone(
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) override;
 
   const scoped_refptr<base::SequencedTaskRunner> task_runner_;
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   DISALLOW_COPY_AND_ASSIGN(ContentURLLoaderFactory);
 };
diff --git a/content/browser/appcache/appcache_subresource_url_factory.cc b/content/browser/appcache/appcache_subresource_url_factory.cc
index 46f01aa..ccc2d0b 100644
--- a/content/browser/appcache/appcache_subresource_url_factory.cc
+++ b/content/browser/appcache/appcache_subresource_url_factory.cc
@@ -331,8 +331,8 @@
     base::WeakPtr<AppCacheHost> host)
     : network_loader_factory_(std::move(network_loader_factory)),
       appcache_host_(host) {
-  bindings_.set_connection_error_handler(
-      base::BindRepeating(&AppCacheSubresourceURLFactory::OnConnectionError,
+  receivers_.set_disconnect_handler(
+      base::BindRepeating(&AppCacheSubresourceURLFactory::OnMojoDisconnect,
                           base::Unretained(this)));
 }
 
@@ -416,8 +416,8 @@
 }
 
 void AppCacheSubresourceURLFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
-  bindings_.AddBinding(this, std::move(request));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
+  receivers_.Add(this, std::move(receiver));
 }
 
 base::WeakPtr<AppCacheSubresourceURLFactory>
@@ -425,8 +425,8 @@
   return weak_factory_.GetWeakPtr();
 }
 
-void AppCacheSubresourceURLFactory::OnConnectionError() {
-  if (bindings_.empty())
+void AppCacheSubresourceURLFactory::OnMojoDisconnect() {
+  if (receivers_.empty())
     delete this;
 }
 
diff --git a/content/browser/appcache/appcache_subresource_url_factory.h b/content/browser/appcache/appcache_subresource_url_factory.h
index 097ae61..a3988ca 100644
--- a/content/browser/appcache/appcache_subresource_url_factory.h
+++ b/content/browser/appcache/appcache_subresource_url_factory.h
@@ -8,7 +8,8 @@
 #include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 #include "content/common/content_export.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 #include "url/gurl.h"
@@ -47,7 +48,8 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
 
   base::WeakPtr<AppCacheSubresourceURLFactory> GetWeakPtr();
 
@@ -59,9 +61,9 @@
   AppCacheSubresourceURLFactory(
       scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory,
       base::WeakPtr<AppCacheHost> host);
-  void OnConnectionError();
+  void OnMojoDisconnect();
 
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
   scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory_;
   base::WeakPtr<AppCacheHost> appcache_host_;
   base::WeakPtrFactory<AppCacheSubresourceURLFactory> weak_factory_{this};
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc
index 26b3e43..af573aa9 100644
--- a/content/browser/back_forward_cache_browsertest.cc
+++ b/content/browser/back_forward_cache_browsertest.cc
@@ -116,6 +116,24 @@
         << location.ToString();
   }
 
+  void ExpectEvicted(BackForwardCacheMetrics::EvictedReason reason,
+                     base::Location location) {
+    base::HistogramBase::Sample sample = base::HistogramBase::Sample(reason);
+    AddSampleToBuckets(&expected_eviction_reasons_, sample);
+
+    EXPECT_EQ(expected_eviction_reasons_,
+              histogram_tester_.GetAllSamples(
+                  "BackForwardCache.HistoryNavigationOutcome.EvictedReason"))
+        << location.ToString();
+  }
+
+  void ExpectEvictedIsEmpty(base::Location location) {
+    EXPECT_THAT(histogram_tester_.GetAllSamples(
+                    "BackForwardCache.HistoryNavigationOutcome.EvictedReason"),
+                ElementsAre())
+        << location.ToString();
+  }
+
   void ExpectEvictedAfterCommitted(
       std::vector<BackForwardCacheMetrics::EvictedAfterDocumentRestoredReason>
           reasons,
@@ -150,6 +168,7 @@
   base::HistogramTester histogram_tester_;
   std::vector<base::Bucket> expected_outcomes_;
   std::vector<base::Bucket> expected_disabled_reasons_;
+  std::vector<base::Bucket> expected_eviction_reasons_;
   std::vector<base::Bucket> expected_eviction_after_committing_;
 };
 
@@ -532,6 +551,7 @@
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
   ExpectOutcome(BackForwardCacheMetrics::HistoryNavigationOutcome::kEvicted,
                 FROM_HERE);
+  ExpectEvicted(BackForwardCacheMetrics::EvictedReason::kCacheLimit, FROM_HERE);
 }
 
 // Test documents are evicted from the BackForwardCache at some point.
@@ -1413,6 +1433,8 @@
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
   ExpectOutcome(BackForwardCacheMetrics::HistoryNavigationOutcome::kEvicted,
                 FROM_HERE);
+  ExpectEvicted(BackForwardCacheMetrics::EvictedReason::kJavaScriptExecution,
+                FROM_HERE);
 }
 
 // Similar to BackForwardCacheBrowserTest.EvictionOnJavaScriptExecution.
@@ -1452,11 +1474,13 @@
   delete_observer_rfh_a.WaitUntilDeleted();
   delete_observer_rfh_b.WaitUntilDeleted();
 
-  // 4) Go back to A.
+  // 4) Go back to A(B).
   web_contents()->GetController().GoBack();
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
   ExpectOutcome(BackForwardCacheMetrics::HistoryNavigationOutcome::kEvicted,
                 FROM_HERE);
+  ExpectEvicted(BackForwardCacheMetrics::EvictedReason::kJavaScriptExecution,
+                FROM_HERE);
 }
 
 IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
@@ -1497,6 +1521,8 @@
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
   ExpectOutcome(BackForwardCacheMetrics::HistoryNavigationOutcome::kEvicted,
                 FROM_HERE);
+  ExpectEvicted(BackForwardCacheMetrics::EvictedReason::kJavaScriptExecution,
+                FROM_HERE);
 }
 
 // Similar to BackForwardCacheBrowserTest.EvictionOnJavaScriptExecution, but
@@ -1851,6 +1877,8 @@
 
   ExpectOutcome(BackForwardCacheMetrics::HistoryNavigationOutcome::kEvicted,
                 FROM_HERE);
+  ExpectEvicted(BackForwardCacheMetrics::EvictedReason::kJavaScriptExecution,
+                FROM_HERE);
 }
 
 // Test that if the renderer process crashes while a document is in the
@@ -1893,6 +1921,8 @@
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
   ExpectOutcome(BackForwardCacheMetrics::HistoryNavigationOutcome::kEvicted,
                 FROM_HERE);
+  ExpectEvicted(BackForwardCacheMetrics::EvictedReason::kRendererProcessKilled,
+                FROM_HERE);
 }
 
 // The test is simulating a race condition. The scheduler tracked features are
@@ -2405,6 +2435,11 @@
   EXPECT_TRUE(rfh_a->is_evicted_from_back_forward_cache());
   delete_observer_rfh_a.WaitUntilDeleted();
   EXPECT_EQ(current_frame_host(), rfh_b);
+
+  // 7) Go back to A.
+  web_contents()->GetController().GoBack();
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+  ExpectEvicted(BackForwardCacheMetrics::EvictedReason::kTimeout, FROM_HERE);
 }
 
 IN_PROC_BROWSER_TEST_F(
@@ -2431,6 +2466,7 @@
   web_contents()->GetController().GoBack();
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
   ExpectDisabledWithReason("DisabledByBackForwardCacheBrowserTest", FROM_HERE);
+  ExpectEvictedIsEmpty(FROM_HERE);
 }
 
 IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
@@ -2461,6 +2497,7 @@
   web_contents()->GetController().GoBack();
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
   ExpectDisabledWithReason("DisabledByBackForwardCacheBrowserTest", FROM_HERE);
+  ExpectEvictedIsEmpty(FROM_HERE);
 }
 
 IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
@@ -2484,6 +2521,11 @@
   EXPECT_TRUE(NavigateToURL(shell(), url_c));
   EXPECT_TRUE(delete_observer_rfh_a.deleted());
   EXPECT_TRUE(delete_observer_rfh_b.deleted());
+
+  // 3) Go back to A.
+  web_contents()->GetController().GoBack();
+  EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
+  ExpectEvictedIsEmpty(FROM_HERE);
 }
 
 IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest,
@@ -2516,6 +2558,7 @@
   web_contents()->GetController().GoBack();
   EXPECT_TRUE(WaitForLoadStop(shell()->web_contents()));
   ExpectDisabledWithReason("DisabledByBackForwardCacheBrowserTest", FROM_HERE);
+  ExpectEvictedIsEmpty(FROM_HERE);
 }
 
 // Confirm that same-document navigation and not history-navigation does not
diff --git a/content/browser/background_sync/background_sync_scheduler.cc b/content/browser/background_sync/background_sync_scheduler.cc
index e919b10..9615aec 100644
--- a/content/browser/background_sync/background_sync_scheduler.cc
+++ b/content/browser/background_sync/background_sync_scheduler.cc
@@ -91,7 +91,7 @@
   if (sync_type == blink::mojom::BackgroundSyncType::ONE_SHOT)
     return delayed_processing_info_one_shot_;
   else
-    return delayed_processing_info_one_shot_;
+    return delayed_processing_info_periodic_;
 }
 
 }  // namespace content
diff --git a/content/browser/background_sync/background_sync_scheduler_unittest.cc b/content/browser/background_sync/background_sync_scheduler_unittest.cc
index f818bf5..ea472f7 100644
--- a/content/browser/background_sync/background_sync_scheduler_unittest.cc
+++ b/content/browser/background_sync/background_sync_scheduler_unittest.cc
@@ -171,4 +171,16 @@
   run_loop_2.Run();
 }
 
+TEST_F(BackgroundSyncSchedulerTest, ScheduleBothTypesOfSync) {
+  base::RunLoop run_loop_1, run_loop_2;
+  ScheduleDelayedProcessing(
+      GURL(kUrl_1), blink::mojom::BackgroundSyncType::ONE_SHOT,
+      base::TimeDelta::FromMilliseconds(1), run_loop_1.QuitClosure());
+  ScheduleDelayedProcessing(
+      GURL(kUrl_1), blink::mojom::BackgroundSyncType::PERIODIC,
+      base::TimeDelta::FromMilliseconds(1), run_loop_2.QuitClosure());
+  run_loop_1.Run();
+  run_loop_2.Run();
+}
+
 }  // namespace content
diff --git a/content/browser/battery_monitor_browsertest.cc b/content/browser/battery_monitor_browsertest.cc
index 508facb..7eafea5 100644
--- a/content/browser/battery_monitor_browsertest.cc
+++ b/content/browser/battery_monitor_browsertest.cc
@@ -78,8 +78,8 @@
     // it.
     service_manager::ServiceBinding::OverrideInterfaceBinderForTesting(
         device::mojom::kServiceName,
-        base::Bind(&MockBatteryMonitor::Bind,
-                   base::Unretained(mock_battery_monitor_.get())));
+        base::BindRepeating(&MockBatteryMonitor::Bind,
+                            base::Unretained(mock_battery_monitor_.get())));
   }
 
   ~BatteryMonitorTest() override {
diff --git a/content/browser/blob_storage/chrome_blob_storage_context.cc b/content/browser/blob_storage/chrome_blob_storage_context.cc
index 7550078..c1bc20a5 100644
--- a/content/browser/blob_storage/chrome_blob_storage_context.cc
+++ b/content/browser/blob_storage/chrome_blob_storage_context.cc
@@ -24,6 +24,7 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/content_features.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/cpp/resource_request_body.h"
 #include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
 #include "storage/browser/blob/blob_data_builder.h"
@@ -188,21 +189,23 @@
     BrowserContext* browser_context,
     mojo::PendingRemote<blink::mojom::BlobURLToken> token) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  network::mojom::URLLoaderFactoryPtr blob_url_loader_factory_ptr;
+  mojo::PendingRemote<network::mojom::URLLoaderFactory>
+      blob_url_loader_factory_remote;
   base::PostTask(
       FROM_HERE, {BrowserThread::IO},
       base::BindOnce(
           [](scoped_refptr<ChromeBlobStorageContext> context,
-             network::mojom::URLLoaderFactoryRequest request,
+             mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
              mojo::PendingRemote<blink::mojom::BlobURLToken> token) {
             storage::BlobURLLoaderFactory::Create(
                 std::move(token), context->context()->AsWeakPtr(),
-                std::move(request));
+                std::move(receiver));
           },
           base::WrapRefCounted(GetFor(browser_context)),
-          MakeRequest(&blob_url_loader_factory_ptr), std::move(token)));
+          blob_url_loader_factory_remote.InitWithNewPipeAndPassReceiver(),
+          std::move(token)));
   return base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
-      std::move(blob_url_loader_factory_ptr));
+      std::move(blob_url_loader_factory_remote));
 }
 
 // static
@@ -211,21 +214,24 @@
     BrowserContext* browser_context,
     const GURL& url) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  network::mojom::URLLoaderFactoryPtr blob_url_loader_factory_ptr;
+  mojo::PendingRemote<network::mojom::URLLoaderFactory>
+      blob_url_loader_factory_remote;
   base::PostTask(
       FROM_HERE, {BrowserThread::IO},
       base::BindOnce(
           [](scoped_refptr<ChromeBlobStorageContext> context,
-             network::mojom::URLLoaderFactoryRequest request, const GURL& url) {
+             mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
+             const GURL& url) {
             auto blob_remote = context->context()->GetBlobFromPublicURL(url);
             storage::BlobURLLoaderFactory::Create(
                 std::move(blob_remote), url, context->context()->AsWeakPtr(),
-                std::move(request));
+                std::move(receiver));
           },
           base::WrapRefCounted(GetFor(browser_context)),
-          MakeRequest(&blob_url_loader_factory_ptr), url));
+          blob_url_loader_factory_remote.InitWithNewPipeAndPassReceiver(),
+          url));
   return base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
-      std::move(blob_url_loader_factory_ptr));
+      std::move(blob_url_loader_factory_remote));
 }
 
 // static
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc
index 01779cc..49febb06 100644
--- a/content/browser/browser_main_loop.cc
+++ b/content/browser/browser_main_loop.cc
@@ -890,23 +890,23 @@
   startup_task_runner_ = std::make_unique<StartupTaskRunner>(
       base::OnceCallback<void(int)>(), base::ThreadTaskRunnerHandle::Get());
 #endif
-  StartupTask pre_create_threads =
-      base::Bind(&BrowserMainLoop::PreCreateThreads, base::Unretained(this));
+  StartupTask pre_create_threads = base::BindOnce(
+      &BrowserMainLoop::PreCreateThreads, base::Unretained(this));
   startup_task_runner_->AddTask(std::move(pre_create_threads));
 
   StartupTask create_threads =
-      base::Bind(&BrowserMainLoop::CreateThreads, base::Unretained(this));
+      base::BindOnce(&BrowserMainLoop::CreateThreads, base::Unretained(this));
   startup_task_runner_->AddTask(std::move(create_threads));
 
-  StartupTask post_create_threads =
-      base::Bind(&BrowserMainLoop::PostCreateThreads, base::Unretained(this));
+  StartupTask post_create_threads = base::BindOnce(
+      &BrowserMainLoop::PostCreateThreads, base::Unretained(this));
   startup_task_runner_->AddTask(std::move(post_create_threads));
 
-  StartupTask browser_thread_started = base::Bind(
+  StartupTask browser_thread_started = base::BindOnce(
       &BrowserMainLoop::BrowserThreadsStarted, base::Unretained(this));
   startup_task_runner_->AddTask(std::move(browser_thread_started));
 
-  StartupTask pre_main_message_loop_run = base::Bind(
+  StartupTask pre_main_message_loop_run = base::BindOnce(
       &BrowserMainLoop::PreMainMessageLoopRun, base::Unretained(this));
   startup_task_runner_->AddTask(std::move(pre_main_message_loop_run));
 
diff --git a/content/browser/browsing_data/same_site_data_remover_impl.cc b/content/browser/browsing_data/same_site_data_remover_impl.cc
index 4787f6a..e6e40013b 100644
--- a/content/browser/browsing_data/same_site_data_remover_impl.cc
+++ b/content/browser/browsing_data/same_site_data_remover_impl.cc
@@ -17,6 +17,7 @@
 #include "content/public/browser/same_site_data_remover.h"
 #include "content/public/browser/storage_partition.h"
 #include "net/cookies/canonical_cookie.h"
+#include "net/cookies/cookie_constants.h"
 #include "net/cookies/cookie_monster.h"
 #include "net/cookies/cookie_util.h"
 #include "services/network/public/mojom/cookie_manager.mojom.h"
@@ -26,14 +27,18 @@
 
 namespace {
 
-void OnGetAllCookies(base::OnceClosure closure,
-                     network::mojom::CookieManager* cookie_manager,
-                     std::set<std::string>* same_site_none_domains,
-                     const std::vector<net::CanonicalCookie>& cookies) {
+void OnGetAllCookiesWithAccessSemantics(
+    base::OnceClosure closure,
+    network::mojom::CookieManager* cookie_manager,
+    std::set<std::string>* same_site_none_domains,
+    const std::vector<net::CanonicalCookie>& cookies,
+    const std::vector<net::CookieAccessSemantics>& access_semantics_list) {
+  DCHECK(cookies.size() == access_semantics_list.size());
   base::RepeatingClosure barrier =
       base::BarrierClosure(cookies.size(), std::move(closure));
-  for (const auto& cookie : cookies) {
-    if (cookie.IsEffectivelySameSiteNone()) {
+  for (size_t i = 0; i < cookies.size(); ++i) {
+    const net::CanonicalCookie& cookie = cookies[i];
+    if (cookie.IsEffectivelySameSiteNone(access_semantics_list[i])) {
       same_site_none_domains->emplace(cookie.Domain());
       cookie_manager->DeleteCanonicalCookie(
           cookie, base::BindOnce([](const base::RepeatingClosure& callback,
@@ -94,9 +99,9 @@
   same_site_none_domains_.clear();
   auto* cookie_manager =
       storage_partition_->GetCookieManagerForBrowserProcess();
-  cookie_manager->GetAllCookies(
-      base::BindOnce(&OnGetAllCookies, std::move(closure), cookie_manager,
-                     &same_site_none_domains_));
+  cookie_manager->GetAllCookiesWithAccessSemantics(
+      base::BindOnce(&OnGetAllCookiesWithAccessSemantics, std::move(closure),
+                     cookie_manager, &same_site_none_domains_));
 }
 
 void SameSiteDataRemoverImpl::ClearStoragePartitionData(
diff --git a/content/browser/byte_stream.h b/content/browser/byte_stream.h
index 1ac82cac..f85ffcc9 100644
--- a/content/browser/byte_stream.h
+++ b/content/browser/byte_stream.h
@@ -75,7 +75,7 @@
 //          &reader);         // Presumed passed to FILE thread for reading.
 //
 //      // Setup callback for writing.
-//      writer->RegisterCallback(base::Bind(&SpaceAvailable, this));
+//      writer->RegisterCallback(base::BindRepeating(&SpaceAvailable, this));
 //
 //      // Do initial round of writing.
 //      SpaceAvailable();
@@ -102,7 +102,7 @@
 //
 //    void ReceivingClass::Initialize() {
 //      // Initialization
-//      reader->RegisterCallback(base::Bind(&DataAvailable, obj));
+//      reader->RegisterCallback(base::BindRepeating(&DataAvailable, obj));
 //    }
 //
 //    // Called whenever there's something to read.
diff --git a/content/browser/code_cache/generated_code_cache.cc b/content/browser/code_cache/generated_code_cache.cc
index a753890..69e2c59 100644
--- a/content/browser/code_cache/generated_code_cache.cc
+++ b/content/browser/code_cache/generated_code_cache.cc
@@ -68,6 +68,37 @@
 }
 
 constexpr int kResponseTimeSizeInBytes = sizeof(int64_t);
+constexpr int kDataSizeInBytes = sizeof(uint32_t);
+constexpr int kHeaderSizeInBytes = kResponseTimeSizeInBytes + kDataSizeInBytes;
+// This is the threshold for storing the header and cached code in stream 0,
+// which is read into memory on opening an entry. JavaScript code caching stores
+// time stamps with no data, or timestamps with just a tag, and we observe many
+// 8 and 16 byte reads and writes. Make the threshold larger to speed up many
+// code entries too.
+constexpr int kSmallDataLimit = 4096;
+
+void WriteSmallDataHeader(scoped_refptr<net::IOBufferWithSize> buffer,
+                          const base::Time& response_time,
+                          uint32_t data_size) {
+  DCHECK_LE(kHeaderSizeInBytes, buffer->size());
+  int64_t serialized_time =
+      response_time.ToDeltaSinceWindowsEpoch().InMicroseconds();
+  memcpy(buffer->data(), &serialized_time, kResponseTimeSizeInBytes);
+  // Copy size to small data buffer.
+  memcpy(buffer->data() + kResponseTimeSizeInBytes, &data_size,
+         kDataSizeInBytes);
+}
+
+void ReadSmallDataHeader(scoped_refptr<net::IOBufferWithSize> buffer,
+                         base::Time* response_time,
+                         uint32_t* data_size) {
+  DCHECK_LE(kHeaderSizeInBytes, buffer->size());
+  int64_t raw_response_time = *(reinterpret_cast<int64_t*>(buffer->data()));
+  *response_time = base::Time::FromDeltaSinceWindowsEpoch(
+      base::TimeDelta::FromMicroseconds(raw_response_time));
+  *data_size =
+      *(reinterpret_cast<uint32_t*>(buffer->data() + kResponseTimeSizeInBytes));
+}
 
 static_assert(mojo_base::BigBuffer::kMaxInlineBytes <=
                   std::numeric_limits<int>::max(),
@@ -81,7 +112,6 @@
       : net::IOBufferWithSize(nullptr, buffer.size()),
         buffer_(std::move(buffer)) {
     data_ = reinterpret_cast<char*>(buffer_.data());
-    DCHECK(data_);
   }
   explicit BigIOBuffer(size_t size) : net::IOBufferWithSize(nullptr, size) {
     buffer_ = mojo_base::BigBuffer(size);
@@ -135,12 +165,12 @@
  public:
   PendingOperation(Operation op,
                    const std::string& key,
-                   scoped_refptr<net::IOBufferWithSize> time_buffer,
-                   scoped_refptr<BigIOBuffer> data_buffer)
+                   scoped_refptr<net::IOBufferWithSize> small_buffer,
+                   scoped_refptr<BigIOBuffer> large_buffer)
       : op_(op),
         key_(key),
-        time_buffer_(time_buffer),
-        data_buffer_(data_buffer) {
+        small_buffer_(small_buffer),
+        large_buffer_(large_buffer) {
     DCHECK_EQ(Operation::kWrite, op_);
   }
 
@@ -164,42 +194,46 @@
 
   Operation operation() const { return op_; }
   const std::string& key() const { return key_; }
-  scoped_refptr<net::IOBufferWithSize> time_buffer() { return time_buffer_; }
-  scoped_refptr<BigIOBuffer> data_buffer() { return data_buffer_; }
+  scoped_refptr<net::IOBufferWithSize> small_buffer() { return small_buffer_; }
+  scoped_refptr<BigIOBuffer> large_buffer() { return large_buffer_; }
   ReadDataCallback TakeReadCallback() { return std::move(read_callback_); }
   GetBackendCallback TakeBackendCallback() {
     return std::move(backend_callback_);
   }
 
-  // These are used by Fetch operations to hold the buffers we create once the
+  // These are called by Fetch operations to hold the buffers we create once the
   // entry is opened.
-  void set_time_buffer(scoped_refptr<net::IOBufferWithSize> time_buffer) {
+  void set_small_buffer(scoped_refptr<net::IOBufferWithSize> small_buffer) {
     DCHECK_EQ(Operation::kFetch, op_);
-    time_buffer_ = time_buffer;
+    small_buffer_ = small_buffer;
   }
-  // Save fetched data until we can run the callback.
-  void set_data_buffer(scoped_refptr<BigIOBuffer> data_buffer) {
+  void set_large_buffer(scoped_refptr<BigIOBuffer> large_buffer) {
     DCHECK_EQ(Operation::kFetch, op_);
-    data_buffer_ = data_buffer;
+    large_buffer_ = large_buffer;
   }
-  // Verifies that Write/Fetch callbacks are received in the order we expect.
-  void VerifyCompletions(int expected) {
-#if DCHECK_IS_ON()
-    DCHECK_EQ(expected, completions_);
+
+  // These are called by write and fetch operations to track buffer completions
+  // and signal when the operation has finished, and whether it was successful.
+  bool succeeded() const { return succeeded_; }
+
+  bool AddBufferCompletion(bool succeeded) {
+    DCHECK(op_ == Operation::kWrite || op_ == Operation::kFetch);
+    if (!succeeded)
+      succeeded_ = false;
+    DCHECK_GT(2, completions_);
     completions_++;
-#endif
+    return completions_ == 2;
   }
 
  private:
   const Operation op_;
   const std::string key_;
-  scoped_refptr<net::IOBufferWithSize> time_buffer_;
-  scoped_refptr<BigIOBuffer> data_buffer_;
+  scoped_refptr<net::IOBufferWithSize> small_buffer_;
+  scoped_refptr<BigIOBuffer> large_buffer_;
   ReadDataCallback read_callback_;
   GetBackendCallback backend_callback_;
-#if DCHECK_IS_ON()
   int completions_ = 0;
-#endif
+  bool succeeded_ = true;
 };
 
 GeneratedCodeCache::PendingOperation::~PendingOperation() = default;
@@ -241,19 +275,28 @@
     return;
   }
 
-  // Response time and data are written separately, to avoid a copy. We need
-  // two IOBuffers, one for the time and one for the BigBuffer.
-  scoped_refptr<net::IOBufferWithSize> time_buffer =
-      base::MakeRefCounted<net::IOBufferWithSize>(kResponseTimeSizeInBytes);
-  int64_t serialized_time =
-      response_time.ToDeltaSinceWindowsEpoch().InMicroseconds();
-  memcpy(time_buffer->data(), &serialized_time, kResponseTimeSizeInBytes);
-  scoped_refptr<BigIOBuffer> data_buffer =
-      base::MakeRefCounted<BigIOBuffer>(std::move(data));
+  // If data is small, combine the header and data into a single write.
+  scoped_refptr<net::IOBufferWithSize> small_buffer;
+  scoped_refptr<BigIOBuffer> large_buffer;
+  uint32_t data_size = static_cast<uint32_t>(data.size());
+  if (data_size <= kSmallDataLimit) {
+    small_buffer = base::MakeRefCounted<net::IOBufferWithSize>(
+        kHeaderSizeInBytes + data.size());
+    // Copy |data| into the small buffer.
+    memcpy(small_buffer->data() + kHeaderSizeInBytes, data.data(), data.size());
+    // We write 0 bytes and truncate stream 1 to clear any stale data.
+    large_buffer = base::MakeRefCounted<BigIOBuffer>(mojo_base::BigBuffer());
+  } else {
+    small_buffer =
+        base::MakeRefCounted<net::IOBufferWithSize>(kHeaderSizeInBytes);
+    large_buffer = base::MakeRefCounted<BigIOBuffer>(std::move(data));
+  }
+  WriteSmallDataHeader(small_buffer, response_time, data_size);
+
   // Create the write operation.
   std::string key = GetCacheKey(url, origin_lock);
   auto op = std::make_unique<PendingOperation>(Operation::kWrite, key,
-                                               time_buffer, data_buffer);
+                                               small_buffer, large_buffer);
 
   if (backend_state_ != kInitialized) {
     // Insert it into the list of pending operations while the backend is
@@ -416,47 +459,50 @@
   // There should be a valid entry if the open was successful.
   DCHECK(entry);
 
-  // The response time must be written first, truncating the data.
-  auto time_buffer = op->time_buffer();
+  // Write the small data first, truncating.
+  auto small_buffer = op->small_buffer();
   int result = entry->WriteData(
-      kResponseTimeStream, 0, time_buffer.get(), kResponseTimeSizeInBytes,
-      base::BindOnce(&GeneratedCodeCache::WriteResponseTimeComplete,
+      kSmallDataStream, 0, small_buffer.get(), small_buffer->size(),
+      base::BindOnce(&GeneratedCodeCache::WriteSmallBufferComplete,
                      weak_ptr_factory_.GetWeakPtr(), op),
       true);
 
   if (result != net::ERR_IO_PENDING) {
-    WriteResponseTimeComplete(op, result);
+    WriteSmallBufferComplete(op, result);
   }
 
-  // Write the data after the response time, truncating the data.
-  auto data_buffer = op->data_buffer();
-  result =
-      entry->WriteData(kDataStream, 0, data_buffer.get(), data_buffer->size(),
-                       base::BindOnce(&GeneratedCodeCache::WriteDataComplete,
-                                      weak_ptr_factory_.GetWeakPtr(), op),
-                       true);
+  // Write the large data, truncating.
+  auto large_buffer = op->large_buffer();
+  result = entry->WriteData(
+      kLargeDataStream, 0, large_buffer.get(), large_buffer->size(),
+      base::BindOnce(&GeneratedCodeCache::WriteLargeBufferComplete,
+                     weak_ptr_factory_.GetWeakPtr(), op),
+      true);
 
   if (result != net::ERR_IO_PENDING) {
-    WriteDataComplete(op, result);
+    WriteLargeBufferComplete(op, result);
   }
 }
 
-void GeneratedCodeCache::WriteResponseTimeComplete(PendingOperation* op,
-                                                   int rv) {
+void GeneratedCodeCache::WriteSmallBufferComplete(PendingOperation* op,
+                                                  int rv) {
   DCHECK_EQ(Operation::kWrite, op->operation());
-  op->VerifyCompletions(0);  // WriteDataComplete did not run.
-  if (rv != kResponseTimeSizeInBytes) {
-    // The response time write failed; release the time buffer to signal that
-    // the overall request should also fail.
-    op->set_time_buffer(nullptr);
+  if (op->AddBufferCompletion(rv == op->small_buffer()->size())) {
+    WriteComplete(op);
   }
-  // |WriteDataComplete| needs to run and call CloseOperationAndIssueNext.
 }
 
-void GeneratedCodeCache::WriteDataComplete(PendingOperation* op, int rv) {
+void GeneratedCodeCache::WriteLargeBufferComplete(PendingOperation* op,
+                                                  int rv) {
   DCHECK_EQ(Operation::kWrite, op->operation());
-  op->VerifyCompletions(1);  // WriteResponseTimeComplete ran.
-  if (rv != op->data_buffer()->size() || !op->time_buffer()) {
+  if (op->AddBufferCompletion(rv == op->large_buffer()->size())) {
+    WriteComplete(op);
+  }
+}
+
+void GeneratedCodeCache::WriteComplete(PendingOperation* op) {
+  DCHECK_EQ(Operation::kWrite, op->operation());
+  if (!op->succeeded()) {
     // The write failed; record the failure and doom the entry here.
     CollectStatistics(CacheEntryStatus::kWriteFailed);
     DoomEntry(op);
@@ -497,66 +543,80 @@
   // There should be a valid entry if the open was successful.
   DCHECK(entry);
 
-  // To avoid a copying the data, we read it in two parts, response time and
-  // code. Create the buffers and pass them to |op|.
-  scoped_refptr<net::IOBufferWithSize> time_buffer =
-      base::MakeRefCounted<net::IOBufferWithSize>(kResponseTimeSizeInBytes);
-  op->set_time_buffer(time_buffer);
-  int data_size = entry->GetDataSize(kDataStream);
-  scoped_refptr<BigIOBuffer> data_buffer =
-      base::MakeRefCounted<BigIOBuffer>(data_size);
-  op->set_data_buffer(data_buffer);
+  int small_size = entry->GetDataSize(kSmallDataStream);
+  scoped_refptr<net::IOBufferWithSize> small_buffer =
+      base::MakeRefCounted<net::IOBufferWithSize>(small_size);
+  op->set_small_buffer(small_buffer);
+  int large_size = entry->GetDataSize(kLargeDataStream);
+  scoped_refptr<BigIOBuffer> large_buffer =
+      base::MakeRefCounted<BigIOBuffer>(large_size);
+  op->set_large_buffer(large_buffer);
 
-  // We must read response time first.
+  // Read the small data first.
   int result = entry->ReadData(
-      kResponseTimeStream, 0, time_buffer.get(), kResponseTimeSizeInBytes,
-      base::BindOnce(&GeneratedCodeCache::ReadResponseTimeComplete,
+      kSmallDataStream, 0, small_buffer.get(), small_buffer->size(),
+      base::BindOnce(&GeneratedCodeCache::ReadSmallBufferComplete,
                      weak_ptr_factory_.GetWeakPtr(), op));
 
   if (result != net::ERR_IO_PENDING) {
-    ReadResponseTimeComplete(op, result);
+    ReadSmallBufferComplete(op, result);
   }
 
-  // Read the data after the response time.
-  result =
-      entry->ReadData(kDataStream, 0, data_buffer.get(), data_buffer->size(),
-                      base::BindOnce(&GeneratedCodeCache::ReadDataComplete,
-                                     weak_ptr_factory_.GetWeakPtr(), op));
-  if (result != net::ERR_IO_PENDING) {
-    ReadDataComplete(op, result);
-  }
-}
-
-void GeneratedCodeCache::ReadResponseTimeComplete(PendingOperation* op,
-                                                  int rv) {
-  DCHECK_EQ(Operation::kFetch, op->operation());
-  op->VerifyCompletions(0);  // ReadDataComplete did not run.
-  if (rv != kResponseTimeSizeInBytes) {
-    CollectStatistics(CacheEntryStatus::kMiss);
-    // The response time read failed; release the time buffer to signal that
-    // the overall request should also fail.
-    op->set_time_buffer(nullptr);
+  // Skip the large read if data is in the small read.
+  if (large_size == 0)
     return;
+
+  // Read the large data.
+  result = entry->ReadData(
+      kLargeDataStream, 0, large_buffer.get(), large_buffer->size(),
+      base::BindOnce(&GeneratedCodeCache::ReadLargeBufferComplete,
+                     weak_ptr_factory_.GetWeakPtr(), op));
+  if (result != net::ERR_IO_PENDING) {
+    ReadLargeBufferComplete(op, result);
   }
-  // This is considered a cache hit, since response time was read.
-  CollectStatistics(CacheEntryStatus::kHit);
-  // |ReadDataComplete| needs to run and call CloseOperationAndIssueNext.
 }
 
-void GeneratedCodeCache::ReadDataComplete(PendingOperation* op, int rv) {
+void GeneratedCodeCache::ReadSmallBufferComplete(PendingOperation* op, int rv) {
   DCHECK_EQ(Operation::kFetch, op->operation());
-  op->VerifyCompletions(1);  // ReadResponseTimeComplete ran.
-  // Fail the request if either read failed.
-  if (rv != op->data_buffer()->size() || !op->time_buffer()) {
+  bool succeeded = rv == op->small_buffer()->size() && rv >= kHeaderSizeInBytes;
+  CollectStatistics(succeeded ? CacheEntryStatus::kHit
+                              : CacheEntryStatus::kMiss);
+
+  if (op->AddBufferCompletion(succeeded))
+    ReadComplete(op);
+
+  // Small reads must finish now since no large read is pending.
+  if (op->large_buffer()->size() == 0)
+    ReadLargeBufferComplete(op, 0);
+}
+
+void GeneratedCodeCache::ReadLargeBufferComplete(PendingOperation* op, int rv) {
+  DCHECK_EQ(Operation::kFetch, op->operation());
+  if (op->AddBufferCompletion(rv == op->large_buffer()->size()))
+    ReadComplete(op);
+}
+
+void GeneratedCodeCache::ReadComplete(PendingOperation* op) {
+  DCHECK_EQ(Operation::kFetch, op->operation());
+  if (!op->succeeded()) {
     op->TakeReadCallback().Run(base::Time(), mojo_base::BigBuffer());
     // Doom this entry since it is inaccessible.
     DoomEntry(op);
   } else {
-    int64_t raw_response_time =
-        *(reinterpret_cast<int64_t*>(op->time_buffer()->data()));
-    base::Time response_time = base::Time::FromDeltaSinceWindowsEpoch(
-        base::TimeDelta::FromMicroseconds(raw_response_time));
-    op->TakeReadCallback().Run(response_time, op->data_buffer()->TakeBuffer());
+    base::Time response_time;
+    uint32_t data_size = 0;
+    ReadSmallDataHeader(op->small_buffer(), &response_time, &data_size);
+    if (data_size <= kSmallDataLimit) {
+      // Small data, copy the data from the small buffer.
+      DCHECK_EQ(0, op->large_buffer()->size());
+      mojo_base::BigBuffer data(data_size);
+      memcpy(data.data(), op->small_buffer()->data() + kHeaderSizeInBytes,
+             data_size);
+      op->TakeReadCallback().Run(response_time, std::move(data));
+    } else {
+      op->TakeReadCallback().Run(response_time,
+                                 op->large_buffer()->TakeBuffer());
+    }
   }
   CloseOperationAndIssueNext(op);
 }
diff --git a/content/browser/code_cache/generated_code_cache.h b/content/browser/code_cache/generated_code_cache.h
index 69bb0b5..71304e0 100644
--- a/content/browser/code_cache/generated_code_cache.h
+++ b/content/browser/code_cache/generated_code_cache.h
@@ -122,7 +122,7 @@
   enum Operation { kFetch, kWrite, kDelete, kGetBackend };
 
   // Data streams corresponding to each entry.
-  enum { kResponseTimeStream = 0, kDataStream = 1 };
+  enum { kSmallDataStream = 0, kLargeDataStream = 1 };
 
   // Creates a simple_disk_cache backend.
   void CreateBackend();
@@ -138,15 +138,17 @@
   void WriteEntryImpl(PendingOperation* op);
   void OpenCompleteForWrite(PendingOperation* op,
                             disk_cache::EntryResult result);
-  void WriteResponseTimeComplete(PendingOperation* op, int rv);
-  void WriteDataComplete(PendingOperation* op, int rv);
+  void WriteSmallBufferComplete(PendingOperation* op, int rv);
+  void WriteLargeBufferComplete(PendingOperation* op, int rv);
+  void WriteComplete(PendingOperation* op);
 
   // Fetches entry from cache.
   void FetchEntryImpl(PendingOperation* op);
   void OpenCompleteForRead(PendingOperation* op,
                            disk_cache::EntryResult result);
-  void ReadResponseTimeComplete(PendingOperation* op, int rv);
-  void ReadDataComplete(PendingOperation* op, int rv);
+  void ReadSmallBufferComplete(PendingOperation* op, int rv);
+  void ReadLargeBufferComplete(PendingOperation* op, int rv);
+  void ReadComplete(PendingOperation* op);
 
   // Deletes entry from cache.
   void DeleteEntryImpl(PendingOperation* op);
diff --git a/content/browser/code_cache/generated_code_cache_unittest.cc b/content/browser/code_cache/generated_code_cache_unittest.cc
index 243236a..953ae5a 100644
--- a/content/browser/code_cache/generated_code_cache_unittest.cc
+++ b/content/browser/code_cache/generated_code_cache_unittest.cc
@@ -17,6 +17,7 @@
 
 class GeneratedCodeCacheTest : public testing::Test {
  public:
+  static const int kLargeSizeInBytes = 8192;
   static const int kMaxSizeInBytes = 1024 * 1024;
   static constexpr char kInitialUrl[] = "http://example.com/script.js";
   static constexpr char kInitialOrigin[] = "http://example.com";
@@ -41,6 +42,10 @@
     generated_code_cache_ = std::make_unique<GeneratedCodeCache>(
         cache_path_, kMaxSizeInBytes, cache_type);
 
+    GeneratedCodeCache::GetBackendCallback callback = base::BindOnce(
+        &GeneratedCodeCacheTest::GetBackendCallback, base::Unretained(this));
+    generated_code_cache_->GetBackend(std::move(callback));
+
     GURL url(kInitialUrl);
     GURL origin_lock = GURL(kInitialOrigin);
     WriteToCache(url, origin_lock, kInitialData, base::Time::Now());
@@ -76,6 +81,16 @@
     generated_code_cache_->FetchEntry(url, origin_lock, callback);
   }
 
+  void DoomAll() {
+    net::CompletionOnceCallback callback = base::BindOnce(
+        &GeneratedCodeCacheTest::DoomAllCallback, base::Unretained(this));
+    backend_->DoomAllEntries(std::move(callback));
+  }
+
+  void GetBackendCallback(disk_cache::Backend* backend) { backend_ = backend; }
+
+  void DoomAllCallback(int rv) {}
+
   void FetchEntryCallback(const base::Time& response_time,
                           mojo_base::BigBuffer data) {
     if (data.size() == 0) {
@@ -100,6 +115,7 @@
   bool received_;
   bool received_null_;
   base::FilePath cache_path_;
+  disk_cache::Backend* backend_;
 };
 
 constexpr char GeneratedCodeCacheTest::kInitialUrl[];
@@ -153,6 +169,23 @@
   EXPECT_EQ(response_time, received_response_time_);
 }
 
+TEST_F(GeneratedCodeCacheTest, WriteLargeEntry) {
+  GURL new_url("http://example1.com/script.js");
+  GURL origin_lock = GURL(kInitialOrigin);
+
+  InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
+  std::string large_data(kLargeSizeInBytes, 'x');
+  base::Time response_time = base::Time::Now();
+  WriteToCache(new_url, origin_lock, large_data, response_time);
+  task_environment_.RunUntilIdle();
+  FetchFromCache(new_url, origin_lock);
+  task_environment_.RunUntilIdle();
+
+  ASSERT_TRUE(received_);
+  EXPECT_EQ(large_data, received_data_);
+  EXPECT_EQ(response_time, received_response_time_);
+}
+
 TEST_F(GeneratedCodeCacheTest, DeleteEntry) {
   GURL url(kInitialUrl);
   GURL origin_lock = GURL(kInitialOrigin);
@@ -200,6 +233,28 @@
   EXPECT_EQ(base::Time(), received_response_time_);
 }
 
+TEST_F(GeneratedCodeCacheTest, WriteEntryFailureOutOfOrder) {
+  GURL url(kInitialUrl);
+  GURL origin_lock = GURL(kInitialOrigin);
+
+  InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
+  // Dooming adds pending activity for all entries. This makes the following
+  // write block for stream 0, while the stream 1 write fails synchronously. The
+  // two callbacks are received in reverse order.
+  DoomAll();
+  base::Time response_time = base::Time::Now();
+  std::string too_big_data(kMaxSizeInBytes * 8, 0);
+  WriteToCache(url, origin_lock, too_big_data, response_time);
+  task_environment_.RunUntilIdle();
+  FetchFromCache(url, origin_lock);
+  task_environment_.RunUntilIdle();
+
+  // Fetch should return empty data, with invalid response time.
+  ASSERT_TRUE(received_);
+  ASSERT_TRUE(received_null_);
+  EXPECT_EQ(base::Time(), received_response_time_);
+}
+
 TEST_F(GeneratedCodeCacheTest, FetchEntryPendingOp) {
   GURL url(kInitialUrl);
   GURL origin_lock = GURL(kInitialOrigin);
@@ -229,6 +284,23 @@
   EXPECT_EQ(response_time, received_response_time_);
 }
 
+TEST_F(GeneratedCodeCacheTest, WriteLargeEntryPendingOp) {
+  GURL new_url("http://example1.com/script1.js");
+  GURL origin_lock = GURL(kInitialOrigin);
+
+  InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
+  std::string large_data(kLargeSizeInBytes, 'x');
+  base::Time response_time = base::Time::Now();
+  WriteToCache(new_url, origin_lock, large_data, response_time);
+  task_environment_.RunUntilIdle();
+  FetchFromCache(new_url, origin_lock);
+  task_environment_.RunUntilIdle();
+
+  ASSERT_TRUE(received_);
+  EXPECT_EQ(large_data, received_data_);
+  EXPECT_EQ(response_time, received_response_time_);
+}
+
 TEST_F(GeneratedCodeCacheTest, DeleteEntryPendingOp) {
   GURL url(kInitialUrl);
   GURL origin_lock = GURL(kInitialOrigin);
@@ -259,6 +331,63 @@
   EXPECT_EQ(response_time, received_response_time_);
 }
 
+TEST_F(GeneratedCodeCacheTest, UpdateDataOfSmallExistingEntry) {
+  GURL url(kInitialUrl);
+  GURL origin_lock = GURL(kInitialOrigin);
+
+  InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
+  std::string new_data(kLargeSizeInBytes, 'x');
+  base::Time response_time = base::Time::Now();
+  WriteToCache(url, origin_lock, new_data, response_time);
+  task_environment_.RunUntilIdle();
+  FetchFromCache(url, origin_lock);
+  task_environment_.RunUntilIdle();
+
+  ASSERT_TRUE(received_);
+  EXPECT_EQ(new_data, received_data_);
+  EXPECT_EQ(response_time, received_response_time_);
+}
+
+TEST_F(GeneratedCodeCacheTest, UpdateDataOfLargeExistingEntry) {
+  GURL url(kInitialUrl);
+  GURL origin_lock = GURL(kInitialOrigin);
+
+  InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
+  std::string large_data(kLargeSizeInBytes, 'x');
+  base::Time response_time = base::Time::Now();
+  WriteToCache(url, origin_lock, large_data, response_time);
+  std::string new_data = large_data + "Overwrite";
+  response_time = base::Time::Now();
+  WriteToCache(url, origin_lock, new_data, response_time);
+  task_environment_.RunUntilIdle();
+  FetchFromCache(url, origin_lock);
+  task_environment_.RunUntilIdle();
+
+  ASSERT_TRUE(received_);
+  EXPECT_EQ(new_data, received_data_);
+  EXPECT_EQ(response_time, received_response_time_);
+}
+
+TEST_F(GeneratedCodeCacheTest, TruncateDataOfLargeExistingEntry) {
+  GURL url(kInitialUrl);
+  GURL origin_lock = GURL(kInitialOrigin);
+
+  InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
+  std::string large_data(kLargeSizeInBytes, 'x');
+  base::Time response_time = base::Time::Now();
+  WriteToCache(url, origin_lock, large_data, response_time);
+  std::string new_data = "SerializedCodeForScriptOverwrite";
+  response_time = base::Time::Now();
+  WriteToCache(url, origin_lock, new_data, response_time);
+  task_environment_.RunUntilIdle();
+  FetchFromCache(url, origin_lock);
+  task_environment_.RunUntilIdle();
+
+  ASSERT_TRUE(received_);
+  EXPECT_EQ(new_data, received_data_);
+  EXPECT_EQ(response_time, received_response_time_);
+}
+
 TEST_F(GeneratedCodeCacheTest, FetchFailsForNonexistingOrigin) {
   InitializeCache(GeneratedCodeCache::CodeCacheType::kJavaScript);
   GURL new_origin_lock = GURL("http://not-example.com");
diff --git a/content/browser/data_url_loader_factory.cc b/content/browser/data_url_loader_factory.cc
index 906ae87a..79f80147 100644
--- a/content/browser/data_url_loader_factory.cc
+++ b/content/browser/data_url_loader_factory.cc
@@ -100,8 +100,8 @@
 }
 
 void DataURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest loader) {
-  bindings_.AddBinding(this, std::move(loader));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) {
+  receivers_.Add(this, std::move(loader));
 }
 
 }  // namespace content
diff --git a/content/browser/data_url_loader_factory.h b/content/browser/data_url_loader_factory.h
index c2a6d7f0..2c48848 100644
--- a/content/browser/data_url_loader_factory.h
+++ b/content/browser/data_url_loader_factory.h
@@ -6,7 +6,8 @@
 #define CONTENT_BROWSER_DATA_URL_LOADER_FACTORY_H_
 
 #include "base/macros.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
 namespace content {
@@ -33,11 +34,12 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest loader) override;
+  void Clone(
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) override;
 
   GURL url_;
 
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   DISALLOW_COPY_AND_ASSIGN(DataURLLoaderFactory);
 };
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.cc b/content/browser/devtools/devtools_url_loader_interceptor.cc
index 9247c39..26cd6ad 100644
--- a/content/browser/devtools/devtools_url_loader_interceptor.cc
+++ b/content/browser/devtools/devtools_url_loader_interceptor.cc
@@ -17,7 +17,7 @@
 #include "content/browser/loader/download_utils_impl.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/storage_partition.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/system/data_pipe_drainer.h"
 #include "net/base/load_flags.h"
 #include "net/base/mime_sniffer.h"
@@ -446,7 +446,7 @@
       const base::UnguessableToken& frame_token,
       int32_t process_id,
       bool is_download,
-      network::mojom::URLLoaderFactoryRequest loader_request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
       network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
       mojo::PendingRemote<network::mojom::CookieManager> cookie_manager,
       base::WeakPtr<DevToolsURLLoaderInterceptor> interceptor);
@@ -462,7 +462,8 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
 
   void OnProxyBindingError();
   void OnTargetFactoryError();
@@ -474,7 +475,7 @@
   network::mojom::URLLoaderFactoryPtr target_factory_;
   mojo::Remote<network::mojom::CookieManager> cookie_manager_;
   base::WeakPtr<DevToolsURLLoaderInterceptor> interceptor_;
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   SEQUENCE_CHECKER(sequence_checker_);
 };
@@ -485,7 +486,7 @@
     const base::UnguessableToken& frame_token,
     int32_t process_id,
     bool is_download,
-    network::mojom::URLLoaderFactoryRequest loader_request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
     network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
     mojo::PendingRemote<network::mojom::CookieManager> cookie_manager,
     base::WeakPtr<DevToolsURLLoaderInterceptor> interceptor)
@@ -498,8 +499,8 @@
       base::BindOnce(&DevToolsURLLoaderFactoryProxy::OnTargetFactoryError,
                      base::Unretained(this)));
 
-  bindings_.AddBinding(this, std::move(loader_request));
-  bindings_.set_connection_error_handler(
+  receivers_.Add(this, std::move(loader_receiver));
+  receivers_.set_disconnect_handler(
       base::BindRepeating(&DevToolsURLLoaderFactoryProxy::OnProxyBindingError,
                           base::Unretained(this)));
 
@@ -542,9 +543,9 @@
 }
 
 void DevToolsURLLoaderFactoryProxy::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  bindings_.AddBinding(this, std::move(request));
+  receivers_.Add(this, std::move(receiver));
 }
 
 void DevToolsURLLoaderFactoryProxy::OnTargetFactoryError() {
@@ -552,7 +553,7 @@
 }
 
 void DevToolsURLLoaderFactoryProxy::OnProxyBindingError() {
-  if (bindings_.empty())
+  if (receivers_.empty())
     delete this;
 }
 
@@ -626,10 +627,9 @@
   if (patterns_.empty())
     return false;
 
-  // TODO(crbug.com/955171): Replace these with PendingReceiver and
-  // PendingRemote.
-  network::mojom::URLLoaderFactoryRequest original_request =
+  mojo::PendingReceiver<network::mojom::URLLoaderFactory> original_receiver =
       std::move(*receiver);
+  // TODO(crbug.com/955171): Replace |target_ptr_info| with PendingRemote.
   network::mojom::URLLoaderFactoryPtrInfo target_ptr_info;
   *receiver = MakeRequest(&target_ptr_info);
   mojo::PendingRemote<network::mojom::CookieManager> cookie_manager;
@@ -637,7 +637,7 @@
   rph->GetStoragePartition()->GetNetworkContext()->GetCookieManager(
       cookie_manager.InitWithNewPipeAndPassReceiver());
   new DevToolsURLLoaderFactoryProxy(
-      frame_token, process_id, is_download, std::move(original_request),
+      frame_token, process_id, is_download, std::move(original_receiver),
       std::move(target_ptr_info), std::move(cookie_manager),
       weak_factory_.GetWeakPtr());
   return true;
@@ -1418,8 +1418,8 @@
 }
 
 void DevToolsURLLoaderFactoryAdapter::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
-  factory_->Clone(std::move(request));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
+  factory_->Clone(std::move(receiver));
 }
 
 }  // namespace content
diff --git a/content/browser/devtools/devtools_url_loader_interceptor.h b/content/browser/devtools/devtools_url_loader_interceptor.h
index 7a381736..6189168 100644
--- a/content/browser/devtools/devtools_url_loader_interceptor.h
+++ b/content/browser/devtools/devtools_url_loader_interceptor.h
@@ -12,6 +12,7 @@
 #include "base/unguessable_token.h"
 #include "content/browser/devtools/protocol/network.h"
 #include "content/public/common/resource_type.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "net/base/auth.h"
 #include "net/base/net_errors.h"
@@ -259,7 +260,8 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
 
   network::mojom::URLLoaderFactoryPtr factory_;
 };
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index bd94ac13..4d6d555 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -65,6 +65,7 @@
 #include "content/public/common/previews_state.h"
 #include "content/public/common/referrer.h"
 #include "content/public/common/url_utils.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "net/base/elements_upload_data_stream.h"
 #include "net/base/load_flags.h"
@@ -219,10 +220,11 @@
 CreateSharedURLLoaderFactoryInfo(StoragePartitionImpl* storage_partition,
                                  RenderFrameHost* rfh,
                                  bool is_download) {
-  // TODO(crbug.com/955171): Replace these with PendingRemote and
-  // PendingReceiver.
+  // TODO(crbug.com/955171): Replace |proxy_factory_ptr_info| with
+  // PendingRemote.
   network::mojom::URLLoaderFactoryPtrInfo proxy_factory_ptr_info;
-  network::mojom::URLLoaderFactoryRequest proxy_factory_request;
+  mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+      proxy_factory_receiver;
   if (rfh) {
     bool should_proxy = false;
 
@@ -250,13 +252,13 @@
     // intermediate pipe along to the NetworkDownloadURLLoaderFactoryInfo.
     if (should_proxy) {
       proxy_factory_ptr_info = std::move(maybe_proxy_factory_ptr_info);
-      proxy_factory_request = std::move(maybe_proxy_factory_receiver);
+      proxy_factory_receiver = std::move(maybe_proxy_factory_receiver);
     }
   }
 
   return std::make_unique<NetworkDownloadURLLoaderFactoryInfo>(
       storage_partition->url_loader_factory_getter(),
-      std::move(proxy_factory_ptr_info), std::move(proxy_factory_request));
+      std::move(proxy_factory_ptr_info), std::move(proxy_factory_receiver));
 }
 
 std::unique_ptr<network::SharedURLLoaderFactoryInfo>
diff --git a/content/browser/download/network_download_url_loader_factory_info.cc b/content/browser/download/network_download_url_loader_factory_info.cc
index ecc6a7e8..9ef25ce4 100644
--- a/content/browser/download/network_download_url_loader_factory_info.cc
+++ b/content/browser/download/network_download_url_loader_factory_info.cc
@@ -14,10 +14,11 @@
 NetworkDownloadURLLoaderFactoryInfo::NetworkDownloadURLLoaderFactoryInfo(
     scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
     network::mojom::URLLoaderFactoryPtrInfo proxy_factory_ptr_info,
-    network::mojom::URLLoaderFactoryRequest proxy_factory_request)
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+        proxy_factory_receiver)
     : url_loader_factory_getter_(url_loader_factory_getter),
       proxy_factory_ptr_info_(std::move(proxy_factory_ptr_info)),
-      proxy_factory_request_(std::move(proxy_factory_request)) {}
+      proxy_factory_receiver_(std::move(proxy_factory_receiver)) {}
 
 NetworkDownloadURLLoaderFactoryInfo::~NetworkDownloadURLLoaderFactoryInfo() =
     default;
@@ -28,9 +29,9 @@
   DCHECK(download::GetIOTaskRunner()->BelongsToCurrentThread());
   if (lazy_factory_)
     return lazy_factory_;
-  if (proxy_factory_request_.is_pending()) {
+  if (proxy_factory_receiver_.is_valid()) {
     url_loader_factory_getter_->CloneNetworkFactory(
-        std::move(proxy_factory_request_));
+        std::move(proxy_factory_receiver_));
     lazy_factory_ =
         base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
             std::move(proxy_factory_ptr_info_));
diff --git a/content/browser/download/network_download_url_loader_factory_info.h b/content/browser/download/network_download_url_loader_factory_info.h
index 660afc3..6e54158 100644
--- a/content/browser/download/network_download_url_loader_factory_info.h
+++ b/content/browser/download/network_download_url_loader_factory_info.h
@@ -5,6 +5,7 @@
 #ifndef CONTENT_BROWSER_DOWNLOAD_NETWORK_DOWNLOAD_URL_LOADER_FACTORY_INFO_H_
 #define CONTENT_BROWSER_DOWNLOAD_NETWORK_DOWNLOAD_URL_LOADER_FACTORY_INFO_H_
 
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
@@ -20,7 +21,8 @@
   NetworkDownloadURLLoaderFactoryInfo(
       scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter,
       network::mojom::URLLoaderFactoryPtrInfo proxy_factory_ptr_info,
-      network::mojom::URLLoaderFactoryRequest proxy_factory_request);
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+          proxy_factory_receiver);
   ~NetworkDownloadURLLoaderFactoryInfo() override;
 
  protected:
@@ -31,7 +33,8 @@
   scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter_;
   scoped_refptr<network::SharedURLLoaderFactory> lazy_factory_;
   network::mojom::URLLoaderFactoryPtrInfo proxy_factory_ptr_info_;
-  network::mojom::URLLoaderFactoryRequest proxy_factory_request_;
+  mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+      proxy_factory_receiver_;
 
   DISALLOW_COPY_AND_ASSIGN(NetworkDownloadURLLoaderFactoryInfo);
 };
diff --git a/content/browser/fileapi/file_system_url_loader_factory.cc b/content/browser/fileapi/file_system_url_loader_factory.cc
index 7935baf..4d6e73d2 100644
--- a/content/browser/fileapi/file_system_url_loader_factory.cc
+++ b/content/browser/fileapi/file_system_url_loader_factory.cc
@@ -26,7 +26,9 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/common/child_process_host.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/system/data_pipe_producer.h"
 #include "mojo/public/cpp/system/string_data_source.h"
 #include "net/base/completion_repeating_callback.h"
@@ -602,7 +604,7 @@
 
   network::mojom::URLLoaderFactoryPtr CreateBinding() {
     network::mojom::URLLoaderFactoryPtr factory;
-    bindings_.AddBinding(this, mojo::MakeRequest(&factory));
+    receivers_.Add(this, mojo::MakeRequest(&factory));
     return factory;
   }
 
@@ -634,12 +636,13 @@
                                             io_task_runner_);
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest loader) override {
-    bindings_.AddBinding(this, std::move(loader));
+  void Clone(
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) override {
+    receivers_.Add(this, std::move(loader));
   }
 
   const FactoryParams params_;
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
   scoped_refptr<base::SequencedTaskRunner> io_task_runner_;
 
   DISALLOW_COPY_AND_ASSIGN(FileSystemURLLoaderFactory);
diff --git a/content/browser/frame_host/back_forward_cache_impl.cc b/content/browser/frame_host/back_forward_cache_impl.cc
index 641bda2..5832ebfa 100644
--- a/content/browser/frame_host/back_forward_cache_impl.cc
+++ b/content/browser/frame_host/back_forward_cache_impl.cc
@@ -350,8 +350,10 @@
   for (auto& stored_entry : entries_) {
     if (stored_entry->render_frame_host->is_evicted_from_back_forward_cache())
       continue;
-    if (++available_count > size_limit)
-      stored_entry->render_frame_host->EvictFromBackForwardCache();
+    if (++available_count > size_limit) {
+      stored_entry->render_frame_host->EvictFromBackForwardCacheWithReason(
+          BackForwardCacheMetrics::EvictedReason::kCacheLimit);
+    }
   }
 }
 
diff --git a/content/browser/frame_host/back_forward_cache_metrics.cc b/content/browser/frame_host/back_forward_cache_metrics.cc
index e55d2e81..4a22d44b 100644
--- a/content/browser/frame_host/back_forward_cache_metrics.cc
+++ b/content/browser/frame_host/back_forward_cache_metrics.cc
@@ -101,8 +101,8 @@
   if (navigation->IsInMainFrame() && !navigation->IsSameDocument() &&
       is_history_navigation) {
     RecordMetricsForHistoryNavigationCommit(navigation);
-    evicted_ = false;
     disallowed_reasons_.clear();
+    evicted_reason_ = base::nullopt;
   }
 
   if (last_committed_main_frame_navigation_id_ != -1 &&
@@ -178,15 +178,16 @@
   }
 }
 
-void BackForwardCacheMetrics::MarkEvictedFromBackForwardCache() {
-  evicted_ = true;
-}
-
 void BackForwardCacheMetrics::MarkDisableForRenderFrameHost(
     const base::StringPiece& reason) {
   disallowed_reasons_.push_back(reason.as_string());
 }
 
+void BackForwardCacheMetrics::MarkEvictedFromBackForwardCacheWithReason(
+    BackForwardCacheMetrics::EvictedReason reason) {
+  evicted_reason_ = reason;
+}
+
 void BackForwardCacheMetrics::RecordMetricsForHistoryNavigationCommit(
     NavigationRequest* navigation) {
   // TODO(hajimehoshi): Use kNotCachedDueToExperimentCondition if the
@@ -199,12 +200,24 @@
         "BackForwardCache.EvictedAfterDocumentRestoredReason",
         BackForwardCacheMetrics::EvictedAfterDocumentRestoredReason::kRestored);
   }
-  if (evicted_ || last_committed_main_frame_navigation_id_ == -1) {
+
+  // |last_committed_main_frame_navigation_id_ == -1| checks the case when the
+  // browser is restored. In this case, the page has history items but does not
+  // have back-forward cache. Just after restoring, |evicted_reason_| does not
+  // have a value.
+  if (evicted_reason_.has_value() ||
+      last_committed_main_frame_navigation_id_ == -1) {
     DCHECK(!navigation->is_served_from_back_forward_cache());
     outcome = HistoryNavigationOutcome::kEvicted;
   }
   UMA_HISTOGRAM_ENUMERATION("BackForwardCache.HistoryNavigationOutcome",
-                            outcome, HistoryNavigationOutcome::kMaxValue);
+                            outcome);
+
+  if (evicted_reason_.has_value()) {
+    UMA_HISTOGRAM_ENUMERATION(
+        "BackForwardCache.HistoryNavigationOutcome.EvictedReason",
+        evicted_reason_.value());
+  }
 
   for (const std::string& reason : disallowed_reasons_) {
     // Use SparseHistogram instead of other simple macros for metrics. It is
diff --git a/content/browser/frame_host/back_forward_cache_metrics.h b/content/browser/frame_host/back_forward_cache_metrics.h
index 9b922c5..f7ae1461 100644
--- a/content/browser/frame_host/back_forward_cache_metrics.h
+++ b/content/browser/frame_host/back_forward_cache_metrics.h
@@ -55,6 +55,20 @@
     kMaxValue = kNotCachedDueToExperimentCondition,
   };
 
+  // Please keep in sync with BackForwardCacheEvictedReason in
+  // tools/metrics/histograms/enums.xml. These values should not be renumbered.
+  enum class EvictedReason {
+    kTimeout = 0,
+    kCacheLimit = 1,
+    kJavaScriptExecution = 2,
+    kRendererProcessKilled = 3,
+    kRendererProcessCrashed = 4,
+    kDialog = 5,
+    kGrantedMediaStreamAccess = 6,
+    kSchedulerTrackedFeatureUsed = 7,
+    kMaxValue = kSchedulerTrackedFeatureUsed,
+  };
+
   // Please keep in sync with BackForwardCacheEvictedAfterDocumentRestoredReason
   // in tools/metrics/histograms/enums.xml. These values should not be
   // renumbered.
@@ -107,9 +121,10 @@
   // placed in the back-forward cache.
   void RecordFeatureUsage(RenderFrameHostImpl* main_frame);
 
-  // Marks when the page is evicted.
-  // TODO(hajimehoshi): Add the parameter representing the reason.
-  void MarkEvictedFromBackForwardCache();
+  // Marks when the page is evicted with the reason. This information is useful
+  // e.g., to know the major cause of eviction.
+  void MarkEvictedFromBackForwardCacheWithReason(
+      BackForwardCacheMetrics::EvictedReason reason);
 
   // Marks the frame disabled the back forward cache with the reason.
   void MarkDisableForRenderFrameHost(const base::StringPiece& reason);
@@ -155,8 +170,8 @@
   base::Optional<base::TimeTicks> started_navigation_timestamp_;
   base::Optional<base::TimeTicks> navigated_away_from_main_document_timestamp_;
 
-  bool evicted_ = false;
   std::vector<std::string> disallowed_reasons_;
+  base::Optional<EvictedReason> evicted_reason_;
 
   DISALLOW_COPY_AND_ASSIGN(BackForwardCacheMetrics);
 };
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index 667e28d..9b2628d 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -3460,38 +3460,35 @@
 
 std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
 NavigationRequest::MakeDidCommitProvisionalLoadParamsForBFCache() {
+  // Use the DidCommitProvisionalLoad_Params last used to commit the frame
+  // being restored as a starting point.
   std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params> params =
-      std::make_unique<FrameHostMsg_DidCommitProvisionalLoad_Params>();
+      render_frame_host_->TakeLastCommitParams();
 
-  params->http_status_code = net::HTTP_OK;
-  params->url_is_unreachable = false;
+  // Params must have been set when the RFH being restored from the cache last
+  // navigated.
+  CHECK(params);
+
+  DCHECK_EQ(params->http_status_code, net::HTTP_OK);
+  DCHECK_EQ(params->url_is_unreachable, false);
+
   params->intended_as_new_entry = commit_params().intended_as_new_entry;
   params->should_replace_current_entry =
       common_params().should_replace_current_entry;
-  params->post_id = -1;
+  DCHECK_EQ(params->post_id, -1);
   params->nav_entry_id = commit_params().nav_entry_id;
   params->navigation_token = commit_params().navigation_token;
   params->did_create_new_entry = false;
-  // TODO(crbug.com/1005718): Is origin ever unset?
-  if (commit_params().origin_to_commit.has_value()) {
-    params->origin = commit_params().origin_to_commit.value();
-  }
-  // TODO(crbug.com/1005718): Set insecure_request_policy.
-  // TODO(crbug.com/1005718): Set insecure_navigations_set.
-  // TODO(crbug.com/1005718): Set has_potentially_trustworthy_unique_origin.
-  params->url = common_params().url;
+  DCHECK_EQ(params->origin, commit_params().origin_to_commit.value());
+  DCHECK_EQ(params->url, common_params().url);
   params->should_update_history = true;
   params->gesture = common_params().has_user_gesture ? NavigationGestureUser
                                                      : NavigationGestureAuto;
   params->page_state = commit_params().page_state;
-  params->method = common_params().method;
+  DCHECK_EQ(params->method, common_params().method);
   params->item_sequence_number = frame_entry_item_sequence_number_;
   params->document_sequence_number = frame_entry_document_sequence_number_;
-  // TODO(crbug.com/1005718): Set the actual mime type.
-  params->contents_mime_type = "text/html";
   params->transition = common_params().transition;
-  // TODO(crbug.com/1005718): Set is_overriding_user_agent.
-  // TODO(crbug.com/1005718): Set original_request_url.
   params->history_list_was_cleared = false;
   params->request_id = GetGlobalRequestID().request_id;
 
diff --git a/content/browser/frame_host/navigator.h b/content/browser/frame_host/navigator.h
index f77cd9f..007c04c3 100644
--- a/content/browser/frame_host/navigator.h
+++ b/content/browser/frame_host/navigator.h
@@ -10,6 +10,7 @@
 #include "content/browser/frame_host/navigation_request.h"
 #include "content/browser/frame_host/navigator_delegate.h"
 #include "content/common/content_export.h"
+#include "content/common/frame_messages.h"
 #include "content/common/navigation_params.mojom.h"
 #include "content/public/browser/navigation_controller.h"
 #include "mojo/public/cpp/bindings/pending_associated_remote.h"
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index df23041..553f51e 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -171,14 +171,8 @@
 #include "media/mojo/services/media_interface_provider.h"
 #include "media/mojo/services/media_metrics_provider.h"
 #include "media/mojo/services/video_decode_perf_history.h"
-#include "mojo/public/cpp/bindings/associated_receiver.h"
-#include "mojo/public/cpp/bindings/associated_remote.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 #include "mojo/public/cpp/bindings/message.h"
-#include "mojo/public/cpp/bindings/pending_associated_remote.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "mojo/public/cpp/system/data_pipe.h"
@@ -1153,6 +1147,11 @@
     child->current_frame_host()->LeaveBackForwardCache();
 }
 
+std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
+RenderFrameHostImpl::TakeLastCommitParams() {
+  return std::move(last_commit_params_);
+}
+
 void RenderFrameHostImpl::StartBackForwardCacheEvictionTimer() {
   DCHECK(is_in_back_forward_cache_);
   base::TimeDelta evict_after =
@@ -1165,19 +1164,21 @@
 
   back_forward_cache_eviction_timer_.Start(
       FROM_HERE, evict_after,
-      base::BindOnce(&RenderFrameHostImpl::EvictFromBackForwardCache,
-                     weak_ptr_factory_.GetWeakPtr()));
+      base::BindOnce(&RenderFrameHostImpl::EvictFromBackForwardCacheWithReason,
+                     weak_ptr_factory_.GetWeakPtr(),
+                     BackForwardCacheMetrics::EvictedReason::kTimeout));
 }
 
 void RenderFrameHostImpl::DisallowBackForwardCache() {
   is_back_forward_cache_disallowed_ = true;
   if (is_in_back_forward_cache())
-    EvictFromBackForwardCache();
+    EvictFromBackForwardCacheWithReason(base::nullopt);
 }
 
 void RenderFrameHostImpl::OnGrantedMediaStreamAccess() {
   was_granted_media_access_ = true;
-  MaybeEvictFromBackForwardCache();
+  MaybeEvictFromBackForwardCache(
+      BackForwardCacheMetrics::EvictedReason::kGrantedMediaStreamAccess);
 }
 
 void RenderFrameHostImpl::OnPortalActivated(
@@ -1299,10 +1300,11 @@
 }
 
 bool RenderFrameHostImpl::CreateNetworkServiceDefaultFactory(
-    network::mojom::URLLoaderFactoryRequest default_factory_request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+        default_factory_receiver) {
   return CreateNetworkServiceDefaultFactoryInternal(
       last_committed_origin_, network_isolation_key_,
-      std::move(default_factory_request));
+      std::move(default_factory_receiver));
 }
 
 void RenderFrameHostImpl::MarkIsolatedWorldsAsRequiringSeparateURLLoaderFactory(
@@ -1701,8 +1703,6 @@
 void RenderFrameHostImpl::RenderProcessExited(
     RenderProcessHost* host,
     const ChildProcessTerminationInfo& info) {
-  render_process_has_died_ = true;
-
   if (base::FeatureList::IsEnabled(features::kCrashReporting))
     MaybeGenerateCrashReport(info.status, info.exit_code);
 
@@ -1770,11 +1770,16 @@
   // the last block of code here.
 }
 
-void RenderFrameHostImpl::RenderProcessGone(SiteInstanceImpl* site_instance) {
+void RenderFrameHostImpl::RenderProcessGone(
+    SiteInstanceImpl* site_instance,
+    const ChildProcessTerminationInfo& info) {
   DCHECK_EQ(site_instance_.get(), site_instance);
 
   if (is_in_back_forward_cache_) {
-    EvictFromBackForwardCache();
+    EvictFromBackForwardCacheWithReason(
+        info.status == base::TERMINATION_STATUS_PROCESS_CRASHED
+            ? BackForwardCacheMetrics::EvictedReason::kRendererProcessCrashed
+            : BackForwardCacheMetrics::EvictedReason::kRendererProcessKilled);
     return;
   }
 
@@ -2422,7 +2427,8 @@
   TRACE_EVENT0("toplevel", "UpdateActiveSchedulerTrackedFeatures");
   renderer_reported_scheduler_tracked_features_ = features_mask;
 
-  MaybeEvictFromBackForwardCache();
+  MaybeEvictFromBackForwardCache(
+      BackForwardCacheMetrics::EvictedReason::kSchedulerTrackedFeatureUsed);
 }
 
 void RenderFrameHostImpl::OnSchedulerTrackedFeatureUsed(
@@ -2431,7 +2437,8 @@
   browser_reported_scheduler_tracked_features_ |=
       1 << static_cast<uint64_t>(feature);
 
-  MaybeEvictFromBackForwardCache();
+  MaybeEvictFromBackForwardCache(
+      BackForwardCacheMetrics::EvictedReason::kSchedulerTrackedFeatureUsed);
 }
 
 bool RenderFrameHostImpl::IsFrozen() {
@@ -2508,7 +2515,8 @@
   // been fired.
   is_loading_ = true;
 
-  DidCommitNavigationInternal(std::move(owned_request), validated_params.get(),
+  DidCommitNavigationInternal(std::move(owned_request),
+                              std::move(validated_params),
                               /*is_same_document_navigation=*/false);
 
   // Now that the restored frame has been committed, unfreeze it.
@@ -2577,7 +2585,7 @@
   if (!DidCommitNavigationInternal(
           is_browser_initiated ? std::move(same_document_navigation_request_)
                                : nullptr,
-          validated_params.get(), true /* is_same_document_navigation*/)) {
+          std::move(validated_params), true /* is_same_document_navigation*/)) {
     return;
   }
 
@@ -2974,7 +2982,8 @@
     IPC::Message* reply_msg) {
   // If a dialog tries to show for a document in the BackForwardCache, evict it.
   if (is_in_back_forward_cache_) {
-    EvictFromBackForwardCache();
+    EvictFromBackForwardCacheWithReason(
+        BackForwardCacheMetrics::EvictedReason::kDialog);
     return;
   }
 
@@ -3546,6 +3555,15 @@
 
 void RenderFrameHostImpl::EvictFromBackForwardCache() {
   TRACE_EVENT0("navigation", "RenderFrameHostImpl::EvictFromBackForwardCache");
+
+  // TODO(hajimehoshi): This function should take the reason from the renderer
+  // side.
+  EvictFromBackForwardCacheWithReason(
+      BackForwardCacheMetrics::EvictedReason::kJavaScriptExecution);
+}
+
+void RenderFrameHostImpl::EvictFromBackForwardCacheWithReason(
+    base::Optional<BackForwardCacheMetrics::EvictedReason> reason) {
   DCHECK(IsBackForwardCacheEnabled());
 
   if (is_evicted_from_back_forward_cache_)
@@ -3559,10 +3577,11 @@
     DCHECK_EQ(top_document->is_in_back_forward_cache(), in_back_forward_cache);
   }
 
-  if (BackForwardCacheMetrics* metrics =
-          top_document->GetBackForwardCacheMetrics()) {
-    metrics->MarkEvictedFromBackForwardCache();
-  }
+  // TODO(hajimehoshi): Record the 'race condition' by JavaScript execution when
+  // |is_in_back_forward_cache()| is false.
+  BackForwardCacheMetrics* metrics = top_document->GetBackForwardCacheMetrics();
+  if (is_in_back_forward_cache() && reason && metrics)
+    metrics->MarkEvictedFromBackForwardCacheWithReason(reason.value());
 
   if (!in_back_forward_cache) {
     BackForwardCacheMetrics::RecordEvictedAfterDocumentRestored(
@@ -6931,7 +6950,8 @@
 
 bool RenderFrameHostImpl::DidCommitNavigationInternal(
     std::unique_ptr<NavigationRequest> navigation_request,
-    FrameHostMsg_DidCommitProvisionalLoad_Params* validated_params,
+    std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
+        validated_params,
     bool is_same_document_navigation) {
   // Sanity-check the page transition for frame type.
   DCHECK_EQ(ui::PageTransitionIsMainFrame(validated_params->transition),
@@ -6985,7 +7005,7 @@
     }
   }
 
-  if (!ValidateDidCommitParams(navigation_request.get(), validated_params,
+  if (!ValidateDidCommitParams(navigation_request.get(), validated_params.get(),
                                is_same_document_navigation)) {
     return false;
   }
@@ -7049,6 +7069,12 @@
                                               std::move(navigation_request),
                                               is_same_document_navigation);
 
+  if (IsBackForwardCacheEnabled()) {
+    // Store the Commit params so they can be reused if the page is ever
+    // restored from the BackForwardCache.
+    last_commit_params_ = std::move(validated_params);
+  }
+
   if (!is_same_document_navigation) {
     cookie_no_samesite_deprecation_url_hashes_.clear();
     cookie_samesite_none_insecure_deprecation_url_hashes_.clear();
@@ -7356,7 +7382,7 @@
   }
 
   if (!DidCommitNavigationInternal(std::move(committing_navigation_request),
-                                   validated_params.get(),
+                                   std::move(validated_params),
                                    false /* is_same_document_navigation */)) {
     return;
   }
@@ -7701,7 +7727,8 @@
   }
 }
 
-void RenderFrameHostImpl::MaybeEvictFromBackForwardCache() {
+void RenderFrameHostImpl::MaybeEvictFromBackForwardCache(
+    BackForwardCacheMetrics::EvictedReason reason) {
   if (!is_in_back_forward_cache_)
     return;
 
@@ -7715,7 +7742,7 @@
   if (can_store)
     return;
 
-  EvictFromBackForwardCache();
+  EvictFromBackForwardCacheWithReason(reason);
 }
 
 void RenderFrameHostImpl::LogCannotCommitOriginCrashKeys(
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index 7827f67..3e2a5a3 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -34,6 +34,7 @@
 #include "content/browser/bad_message.h"
 #include "content/browser/browser_interface_broker_impl.h"
 #include "content/browser/can_commit_status.h"
+#include "content/browser/frame_host/back_forward_cache_metrics.h"
 #include "content/browser/renderer_host/media/old_render_frame_audio_input_stream_factory.h"
 #include "content/browser/renderer_host/media/old_render_frame_audio_output_stream_factory.h"
 #include "content/browser/renderer_host/media/render_frame_audio_input_stream_factory.h"
@@ -153,7 +154,6 @@
 namespace content {
 class AppCacheNavigationHandle;
 class AuthenticatorImpl;
-class BackForwardCacheMetrics;
 class BundledExchangesHandle;
 class FrameTree;
 class FrameTreeNode;
@@ -224,7 +224,7 @@
   // This method must be called either on the UI thread or before threads start.
   // This callback is run on the UI thread.
   using CreateNetworkFactoryCallback = base::RepeatingCallback<void(
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       int process_id,
       network::mojom::URLLoaderFactoryPtrInfo original_factory)>;
   static void SetNetworkFactoryForTesting(
@@ -299,7 +299,8 @@
       const gfx::Point&,
       const blink::WebMediaPlayerAction& action) override;
   bool CreateNetworkServiceDefaultFactory(
-      network::mojom::URLLoaderFactoryRequest default_factory_request) override;
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+          default_factory_receiver) override;
   void MarkIsolatedWorldsAsRequiringSeparateURLLoaderFactory(
       base::flat_set<url::Origin> isolated_world_origins,
       bool push_to_renderer_now) override;
@@ -317,7 +318,9 @@
 
   void SendAccessibilityEventsToManager(
       const AXEventNotificationDetails& details);
-  void EvictFromBackForwardCache() override;
+
+  void EvictFromBackForwardCacheWithReason(
+      base::Optional<BackForwardCacheMetrics::EvictedReason> reason);
 
   // IPC::Sender
   bool Send(IPC::Message* msg) override;
@@ -347,7 +350,8 @@
                            const ChildProcessTerminationInfo& info) override;
 
   // SiteInstanceImpl::Observer
-  void RenderProcessGone(SiteInstanceImpl* site_instance) override;
+  void RenderProcessGone(SiteInstanceImpl* site_instance,
+                         const ChildProcessTerminationInfo& info) override;
 
   // CSPContext
   void ReportContentSecurityPolicyViolation(
@@ -946,6 +950,13 @@
   // occurs immediately before a restored document is committed.
   void LeaveBackForwardCache();
 
+  // Take ownership over the DidCommitProvisionalLoad_Params that
+  // were last used to commit this navigation.
+  // This is used by the BackForwardCache to re-commit when navigating to a
+  // restored page.
+  std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
+  TakeLastCommitParams();
+
   // Start a timer that will evict this RenderFrameHost from the
   // BackForwardCache after time to live.
   void StartBackForwardCacheEvictionTimer();
@@ -1155,13 +1166,6 @@
       std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
           validated_params);
 
-  // Return true if the process this RenderFrameHost is using has crashed.
-  //
-  // This is not exactly the opposite of IsRenderFrameLive().
-  // IsRenderFrameLive() is false when the RenderProcess died, but it is also
-  // false when it hasn't been initialized.
-  bool render_process_has_died() const { return render_process_has_died_; }
-
   // Returns the network isolation key used for subresources from the currently
   // committed navigation. It is reset on each document commit.
   const net::NetworkIsolationKey& network_isolation_key() const {
@@ -1440,6 +1444,7 @@
           validated_params,
       mojom::DidCommitProvisionalLoadInterfaceParamsPtr interface_params)
       override;
+  void EvictFromBackForwardCache() override;
 
   // This function mimics DidCommitProvisionalLoad but is a direct mojo
   // callback from NavigationClient::CommitNavigation.
@@ -1796,7 +1801,8 @@
   // state should be restored to its pre-commit value.
   bool DidCommitNavigationInternal(
       std::unique_ptr<NavigationRequest> navigation_request,
-      FrameHostMsg_DidCommitProvisionalLoad_Params* validated_params,
+      std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
+          validated_params,
       bool is_same_document_navigation);
 
   // Called by the renderer process when it is done processing a same-document
@@ -1901,7 +1907,8 @@
 
   // Evicts the document from the BackForwardCache if it is in the cache,
   // and ineligible for caching.
-  void MaybeEvictFromBackForwardCache();
+  void MaybeEvictFromBackForwardCache(
+      BackForwardCacheMetrics::EvictedReason reason);
 
   // Helper for handling download-related IPCs.
   void DownloadUrl(
@@ -2189,7 +2196,6 @@
   PreviewsState last_navigation_previews_state_;
 
   bool has_committed_any_navigation_ = false;
-  bool render_process_has_died_ = false;
 
   mojo::AssociatedReceiver<mojom::FrameHost> frame_host_associated_receiver_{
       this};
@@ -2420,6 +2426,12 @@
   bool is_back_forward_cache_disallowed_ = false;
   base::OneShotTimer back_forward_cache_eviction_timer_;
 
+  // This used to re-commit when restoring from the BackForwardCache, with the
+  // same params as the original navigation.
+  // Note: If BackForwardCache is not enabled, this field is not set.
+  std::unique_ptr<FrameHostMsg_DidCommitProvisionalLoad_Params>
+      last_commit_params_;
+
   blink::mojom::FrameVisibility visibility_ =
       blink::mojom::FrameVisibility::kRenderedInViewport;
 
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
index 5c81ce3..7a136b4e 100644
--- a/content/browser/frame_host/render_frame_host_manager.cc
+++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -685,11 +685,6 @@
   // The SiteInstance determines whether to switch RenderFrameHost or not.
   bool use_current_rfh = current_site_instance == dest_site_instance;
 
-  // A crashed RenderFrameHost is never reused, but replaced by a new one
-  // immediately.
-  if (render_frame_host_->render_process_has_died())
-    use_current_rfh = false;
-
   bool notify_webui_of_rf_creation = false;
   if (use_current_rfh) {
     // GetFrameHostForNavigation will be called more than once during a
@@ -741,8 +736,7 @@
     // create a new one if needed.
     if (!speculative_render_frame_host_ ||
         speculative_render_frame_host_->GetSiteInstance() !=
-            dest_site_instance.get() ||
-        speculative_render_frame_host_->render_process_has_died()) {
+            dest_site_instance.get()) {
       // If there is a speculative RenderFrameHost trying to commit a
       // navigation, inform the NavigationController that the load of the
       // corresponding NavigationEntry stopped if needed. This is the case if
@@ -786,11 +780,6 @@
     }
     navigation_rfh = speculative_render_frame_host_.get();
 
-    // Ensure that if the current RenderFrameHost is crashed, the following code
-    // path will always be used.
-    DCHECK(!render_frame_host_->render_process_has_died() ||
-           !render_frame_host_->IsRenderFrameLive());
-
     // Check if our current RFH is live.
     if (!render_frame_host_->IsRenderFrameLive()) {
       // The current RFH is not live. There's no reason to sit around with a
@@ -825,11 +814,9 @@
   DCHECK(navigation_rfh &&
          (navigation_rfh == render_frame_host_.get() ||
           navigation_rfh == speculative_render_frame_host_.get()));
-  DCHECK(!render_frame_host_->render_process_has_died());
-  DCHECK(!navigation_rfh->render_process_has_died());
 
   // If the RenderFrame that needs to navigate is not live (its process was just
-  // created), initialize it.
+  // created or has crashed), initialize it.
   if (!navigation_rfh->IsRenderFrameLive()) {
     if (!ReinitializeRenderFrame(navigation_rfh))
       return nullptr;
@@ -1037,7 +1024,9 @@
       browser_context(browser_context),
       relation(relation_to_current) {}
 
-void RenderFrameHostManager::RenderProcessGone(SiteInstanceImpl* instance) {
+void RenderFrameHostManager::RenderProcessGone(
+    SiteInstanceImpl* instance,
+    const ChildProcessTerminationInfo& info) {
   GetRenderFrameProxyHost(instance)->SetRenderFrameProxyCreated(false);
 }
 
@@ -2004,16 +1993,7 @@
     SiteInstance* old_instance,
     SiteInstance* new_instance) {
   CHECK(new_instance);
-  // We are creating a speculative RFH here. We should never create it in the
-  // same SiteInstance as our current RFH.
-  //
-  // This DCHECK is going to be fully removed as part of RenderDocument [1].
-  // Right now, the only case where a speculative RFH is created for a same-site
-  // navigation is when the old RenderFramehost has crashed.
-  //
-  // [1] http://crbug.com/936696
-  DCHECK(old_instance != new_instance ||
-         render_frame_host_->render_process_has_died());
+  CHECK_NE(old_instance, new_instance);
 
   // The process for the new SiteInstance may (if we're sharing a process with
   // another host that already initialized it) or may not (we have our own
@@ -2042,16 +2022,10 @@
 std::unique_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
     SiteInstance* instance) {
   CHECK(instance);
+
   // We are creating a pending or speculative RFH here. We should never create
   // it in the same SiteInstance as our current RFH.
-  //
-  // This DCHECK is going to be fully removed as part of RenderDocument [1].
-  // Right now, the only case where a speculative RFH is created for a same-site
-  // navigation is when the old RenderFramehost has crashed.
-  //
-  // [1] http://crbug.com/936696
-  DCHECK(render_frame_host_->GetSiteInstance() != instance ||
-         render_frame_host_->render_process_has_died());
+  CHECK_NE(render_frame_host_->GetSiteInstance(), instance);
 
   // A RenderFrame in a different process from its parent RenderFrame
   // requires a RenderWidget for input/layout/painting.
@@ -2075,15 +2049,6 @@
   RenderViewHostImpl* render_view_host =
       new_render_frame_host->render_view_host();
   if (frame_tree_node_->IsMainFrame()) {
-    // Same-site navigation from a crashed RenderFrameHost is reinitializing
-    // the RenderViewHost with a new main RenderFrame with a new routing ID.
-    SiteInstance* current_site_instance = render_frame_host_->GetSiteInstance();
-    bool is_same_site = current_site_instance == instance;
-    if (is_same_site && render_frame_host_->render_process_has_died()) {
-      render_view_host->SetMainFrameRoutingId(
-          new_render_frame_host->GetRoutingID());
-    }
-
     if (!InitRenderView(render_view_host, GetRenderFrameProxyHost(instance)))
       return nullptr;
 
@@ -2570,7 +2535,8 @@
   // happen for each same-site navigation.
   RenderViewHostImpl* old_rvh = old_render_frame_host->render_view_host();
   RenderViewHostImpl* new_rvh = render_frame_host_->render_view_host();
-  if (is_main_frame && old_view && old_rvh != new_rvh) {
+  if (is_main_frame && old_view) {
+    DCHECK_NE(old_rvh, new_rvh);
     // Note that this hides the RenderWidget but does not hide the Page. If it
     // did hide the Page then making a new RenderFrameHost on another call to
     // here would need to make sure it showed the RenderView when the
@@ -2614,7 +2580,7 @@
 
   // Make the new view show the contents of old view until it has something
   // useful to show.
-  if (is_main_frame && old_view && new_view && old_view != new_view)
+  if (is_main_frame && old_view && new_view)
     new_view->TakeFallbackContentFrom(old_view);
 
   // The RenderViewHost keeps track of the main RenderFrameHost routing id.
@@ -2637,8 +2603,7 @@
 
     new_rvh->set_is_swapped_out(false);
     new_rvh->SetMainFrameRoutingId(render_frame_host_->routing_id());
-    if (old_rvh != new_rvh)
-      old_rvh->SetMainFrameRoutingId(MSG_ROUTING_NONE);
+    old_rvh->SetMainFrameRoutingId(MSG_ROUTING_NONE);
   }
 
   // Store the old_render_frame_host's current frame size so that it can be used
diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h
index c49e69f..5166fca 100644
--- a/content/browser/frame_host/render_frame_host_manager.h
+++ b/content/browser/frame_host/render_frame_host_manager.h
@@ -473,7 +473,8 @@
 
   // SiteInstanceImpl::Observer
   void ActiveFrameCountIsZero(SiteInstanceImpl* site_instance) override;
-  void RenderProcessGone(SiteInstanceImpl* site_instance) override;
+  void RenderProcessGone(SiteInstanceImpl* site_instance,
+                         const ChildProcessTerminationInfo& info) override;
 
   // Cancels and destroys the pending or speculative RenderFrameHost if they
   // match the provided |render_frame_host|.
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
index 76ecf0a9..3a88d933 100644
--- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -6420,146 +6420,4 @@
   SetBrowserClientForTesting(old_client);
 }
 
-// 1. Navigate to A1(B2, B3(B4), C5)
-// 2. Crash process B
-// 3. Reload B2, creating RFH B6.
-//
-// Along the way, check the RenderFrameProxies.
-IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest,
-                       CrashFrameReloadAndCheckProxy) {
-  // This test explicitly requires multiple processes to be used. It won't mean
-  // anything without SiteIsolation.
-  if (!AreAllSitesIsolatedForTesting())
-    return;
-
-  // 1. Navigate to A1(B2, B3(B4), C5).
-  StartEmbeddedServer();
-  GURL url(embedded_test_server()->GetURL(
-      "a.com", "/cross_site_iframe_factory.html?a(b,b(b),c)"));
-  EXPECT_TRUE(NavigateToURL(shell(), url));
-
-  WebContentsImpl* web_contents =
-      static_cast<WebContentsImpl*>(shell()->web_contents());
-  RenderFrameHostImpl* a1 = web_contents->GetMainFrame();
-  RenderFrameHostImpl* b2 = a1->child_at(0)->current_frame_host();
-  RenderFrameHostImpl* b3 = a1->child_at(1)->current_frame_host();
-  RenderFrameHostImpl* b4 = b3->child_at(0)->current_frame_host();
-  RenderFrameHostImpl* c5 = a1->child_at(2)->current_frame_host();
-
-  RenderFrameDeletedObserver delete_a1(a1);
-  RenderFrameDeletedObserver delete_b2(b2);
-  RenderFrameDeletedObserver delete_b3(b3);
-  RenderFrameDeletedObserver delete_b4(b4);
-  RenderFrameDeletedObserver delete_c5(c5);
-
-  GURL b2_url = b2->GetLastCommittedURL();
-  int b2_routing_id = b2->routing_id();
-
-  auto proxy_count = [](RenderFrameHostImpl* rfh) {
-    return rfh->frame_tree_node()->render_manager()->GetProxyCount();
-  };
-
-  // There are 3 processes, so every frame has 2 frame proxies.
-  EXPECT_EQ(2u, proxy_count(a1));
-  EXPECT_EQ(2u, proxy_count(b2));
-  EXPECT_EQ(2u, proxy_count(b3));
-  EXPECT_EQ(2u, proxy_count(b4));
-  EXPECT_EQ(2u, proxy_count(c5));
-
-  auto is_proxy_live = [](RenderFrameHostImpl* rfh,
-                          scoped_refptr<SiteInstance> site_instance) {
-    return rfh->frame_tree_node()
-        ->render_manager()
-        ->GetRenderFrameProxyHost(site_instance.get())
-        ->is_render_frame_proxy_live();
-  };
-
-  // Store SiteInstance for later comparison.
-  scoped_refptr<SiteInstance> a_site_instance(a1->GetSiteInstance());
-  scoped_refptr<SiteInstance> b_site_instance(b2->GetSiteInstance());
-  scoped_refptr<SiteInstance> c_site_instance(c5->GetSiteInstance());
-
-  // Check the state of the proxies before the crash:
-  EXPECT_TRUE(is_proxy_live(a1, b_site_instance));
-  EXPECT_TRUE(is_proxy_live(a1, c_site_instance));
-  EXPECT_TRUE(is_proxy_live(b2, a_site_instance));
-  EXPECT_TRUE(is_proxy_live(b2, c_site_instance));
-  EXPECT_TRUE(is_proxy_live(b3, a_site_instance));
-  EXPECT_TRUE(is_proxy_live(b3, c_site_instance));
-  EXPECT_TRUE(is_proxy_live(c5, a_site_instance));
-  EXPECT_TRUE(is_proxy_live(c5, b_site_instance));
-
-  // 2. Crash process B.
-  RenderProcessHost* process = b2->GetProcess();
-  RenderProcessHostWatcher crash_observer(
-      process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
-  process->Shutdown(0);
-  crash_observer.Wait();
-
-  // Only B4 is deleted. B2 and B3 are still there in a "crashed" state.
-  delete_b4.WaitUntilDeleted();
-
-  // B2, B3, B4 RenderFrame are gone.
-  EXPECT_FALSE(delete_a1.deleted());
-  EXPECT_TRUE(delete_b2.deleted());
-  EXPECT_TRUE(delete_b3.deleted());
-  EXPECT_TRUE(delete_b4.deleted());
-  EXPECT_FALSE(delete_c5.deleted());
-
-  // B2 and B3 RenderFrameHost are still there, but B4 is definitely gone.
-  ASSERT_EQ(3u, a1->child_count());
-  EXPECT_EQ(b2, a1->child_at(0)->current_frame_host());
-  EXPECT_EQ(b3, a1->child_at(1)->current_frame_host());
-  ASSERT_EQ(0u, b3->child_count());
-
-  EXPECT_FALSE(a1->render_process_has_died());
-  EXPECT_TRUE(b2->render_process_has_died());
-  EXPECT_TRUE(b3->render_process_has_died());
-  EXPECT_FALSE(c5->render_process_has_died());
-
-  EXPECT_EQ(2u, proxy_count(a1));
-  EXPECT_EQ(2u, proxy_count(b2));
-  EXPECT_EQ(2u, proxy_count(b3));
-  EXPECT_EQ(2u, proxy_count(c5));
-
-  // Check the state of the proxies after the crash:
-  EXPECT_FALSE(is_proxy_live(a1, b_site_instance));
-  EXPECT_TRUE(is_proxy_live(a1, c_site_instance));
-  EXPECT_TRUE(is_proxy_live(b2, a_site_instance));
-  EXPECT_TRUE(is_proxy_live(b2, c_site_instance));
-  EXPECT_TRUE(is_proxy_live(b3, a_site_instance));
-  EXPECT_TRUE(is_proxy_live(b3, c_site_instance));
-  EXPECT_TRUE(is_proxy_live(c5, a_site_instance));
-  EXPECT_FALSE(is_proxy_live(c5, b_site_instance));
-
-  // 3. Reload B2, B6 is created.
-  NavigateFrameToURL(b2->frame_tree_node(), b2_url);
-
-  // B2 has been replaced, B3 hasn't.
-  EXPECT_NE(b2_routing_id, a1->child_at(0)->current_frame_host()->routing_id());
-  EXPECT_EQ(b3, a1->child_at(1)->current_frame_host());
-  RenderFrameHostImpl* b6 = a1->child_at(0)->current_frame_host();
-  EXPECT_TRUE(b3->render_process_has_died());
-  EXPECT_FALSE(b6->render_process_has_died());
-
-  EXPECT_EQ(a_site_instance, a1->GetSiteInstance());
-  EXPECT_EQ(b_site_instance, b6->GetSiteInstance());
-  EXPECT_EQ(c_site_instance, c5->GetSiteInstance());
-
-  EXPECT_EQ(2u, proxy_count(a1));
-  EXPECT_EQ(2u, proxy_count(b6));
-  EXPECT_EQ(2u, proxy_count(b3));
-  EXPECT_EQ(2u, proxy_count(c5));
-
-  // Check the state of the proxies after the reload.
-  EXPECT_TRUE(is_proxy_live(a1, b_site_instance));
-  EXPECT_TRUE(is_proxy_live(a1, c_site_instance));
-  EXPECT_TRUE(is_proxy_live(b6, a_site_instance));
-  EXPECT_TRUE(is_proxy_live(b6, c_site_instance));
-  EXPECT_TRUE(is_proxy_live(b3, a_site_instance));
-  EXPECT_TRUE(is_proxy_live(b3, c_site_instance));
-  EXPECT_TRUE(is_proxy_live(c5, a_site_instance));
-  EXPECT_TRUE(is_proxy_live(c5, b_site_instance));
-}
-
 }  // namespace content
diff --git a/content/browser/frame_host/render_frame_host_manager_unittest.cc b/content/browser/frame_host/render_frame_host_manager_unittest.cc
index 704bb79..711f83aa 100644
--- a/content/browser/frame_host/render_frame_host_manager_unittest.cc
+++ b/content/browser/frame_host/render_frame_host_manager_unittest.cc
@@ -2007,7 +2007,7 @@
   EXPECT_TRUE(contents1->GetMainFrame()->IsRenderFrameLive());
   EXPECT_FALSE(contents2->GetMainFrame()->IsRenderFrameLive());
   EXPECT_EQ(contents1->GetSiteInstance(), contents2->GetSiteInstance());
-  EXPECT_TRUE(contents1->GetMainFrame()->GetView());
+  EXPECT_FALSE(contents1->GetMainFrame()->GetView());
   EXPECT_FALSE(contents2->GetMainFrame()->GetView());
 
   // |contents1| creates an out of process iframe.
diff --git a/content/browser/geolocation/geolocation_service_impl.cc b/content/browser/geolocation/geolocation_service_impl.cc
index 42b9a4d..67b3263 100644
--- a/content/browser/geolocation/geolocation_service_impl.cc
+++ b/content/browser/geolocation/geolocation_service_impl.cc
@@ -24,7 +24,7 @@
 void GeolocationServiceImplContext::RequestPermission(
     RenderFrameHost* render_frame_host,
     bool user_gesture,
-    const base::Callback<void(blink::mojom::PermissionStatus)>& callback) {
+    base::OnceCallback<void(blink::mojom::PermissionStatus)> callback) {
   if (request_id_ != PermissionController::kNoPendingOperation) {
     mojo::ReportBadMessage(
         "GeolocationService client may only create one Geolocation at a "
@@ -35,15 +35,15 @@
   request_id_ = permission_controller_->RequestPermission(
       PermissionType::GEOLOCATION, render_frame_host,
       render_frame_host->GetLastCommittedOrigin().GetURL(), user_gesture,
-      base::Bind(&GeolocationServiceImplContext::HandlePermissionStatus,
-                 weak_factory_.GetWeakPtr(), std::move(callback)));
+      base::BindOnce(&GeolocationServiceImplContext::HandlePermissionStatus,
+                     weak_factory_.GetWeakPtr(), std::move(callback)));
 }
 
 void GeolocationServiceImplContext::HandlePermissionStatus(
-    const base::Callback<void(blink::mojom::PermissionStatus)>& callback,
+    base::OnceCallback<void(blink::mojom::PermissionStatus)> callback,
     blink::mojom::PermissionStatus permission_status) {
   request_id_ = PermissionController::kNoPendingOperation;
-  callback.Run(permission_status);
+  std::move(callback).Run(permission_status);
 }
 
 GeolocationServiceImpl::GeolocationServiceImpl(
@@ -86,9 +86,10 @@
       render_frame_host_, user_gesture,
       // There is an assumption here that the GeolocationServiceImplContext will
       // outlive the GeolocationServiceImpl.
-      base::Bind(&GeolocationServiceImpl::CreateGeolocationWithPermissionStatus,
-                 base::Unretained(this), base::Passed(&receiver),
-                 base::Passed(&scoped_callback)));
+      base::BindOnce(
+          &GeolocationServiceImpl::CreateGeolocationWithPermissionStatus,
+          base::Unretained(this), base::Passed(&receiver),
+          base::Passed(&scoped_callback)));
 }
 
 void GeolocationServiceImpl::CreateGeolocationWithPermissionStatus(
diff --git a/content/browser/geolocation/geolocation_service_impl.h b/content/browser/geolocation/geolocation_service_impl.h
index d737f1d..840bc6b 100644
--- a/content/browser/geolocation/geolocation_service_impl.h
+++ b/content/browser/geolocation/geolocation_service_impl.h
@@ -30,14 +30,14 @@
   void RequestPermission(
       RenderFrameHost* render_frame_host,
       bool user_gesture,
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback);
+      base::OnceCallback<void(blink::mojom::PermissionStatus)> callback);
 
  private:
   PermissionControllerImpl* permission_controller_;
   int request_id_;
 
   void HandlePermissionStatus(
-      const base::Callback<void(blink::mojom::PermissionStatus)>& callback,
+      base::OnceCallback<void(blink::mojom::PermissionStatus)> callback,
       blink::mojom::PermissionStatus permission_status);
 
   base::WeakPtrFactory<GeolocationServiceImplContext> weak_factory_{this};
diff --git a/content/browser/histogram_synchronizer.cc b/content/browser/histogram_synchronizer.cc
index 9c792bb..833d972 100644
--- a/content/browser/histogram_synchronizer.cc
+++ b/content/browser/histogram_synchronizer.cc
@@ -47,12 +47,11 @@
   // A map from sequence_number_ to the actual RequestContexts.
   typedef std::map<int, RequestContext*> RequestContextMap;
 
-  RequestContext(const base::Closure& callback, int sequence_number)
-      : callback_(callback),
+  RequestContext(base::OnceClosure callback, int sequence_number)
+      : callback_(std::move(callback)),
         sequence_number_(sequence_number),
         received_process_group_count_(0),
-        processes_pending_(0) {
-  }
+        processes_pending_(0) {}
   ~RequestContext() {}
 
   void SetReceivedProcessGroupCount(bool done) {
@@ -84,10 +83,11 @@
 
   // Register |callback| in |outstanding_requests_| map for the given
   // |sequence_number|.
-  static void Register(const base::Closure& callback, int sequence_number) {
+  static void Register(base::OnceClosure callback, int sequence_number) {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-    RequestContext* request = new RequestContext(callback, sequence_number);
+    RequestContext* request =
+        new RequestContext(std::move(callback), sequence_number);
     outstanding_requests_.Get()[sequence_number] = request;
   }
 
@@ -120,7 +120,7 @@
     bool received_process_group_count = request->received_process_group_count_;
     int unresponsive_processes = request->processes_pending_;
 
-    request->callback_.Run();
+    std::move(request->callback_).Run();
 
     delete request;
     outstanding_requests_.Get().erase(it);
@@ -142,7 +142,7 @@
   }
 
   // Requests are made to asynchronously send data to the |callback_|.
-  base::Closure callback_;
+  base::OnceClosure callback_;
 
   // The sequence number used by the most recent update request to contact all
   // processes.
@@ -236,10 +236,9 @@
 
   int sequence_number = GetNextAvailableSequenceNumber(requester);
 
-  base::Closure callback = base::Bind(
+  base::OnceClosure callback = base::BindOnce(
       &HistogramSynchronizer::ForceHistogramSynchronizationDoneCallback,
-      base::Unretained(this),
-      sequence_number);
+      base::Unretained(this), sequence_number);
 
   RequestContext::Register(std::move(callback), sequence_number);
 
diff --git a/content/browser/installedapp/OWNERS b/content/browser/installedapp/OWNERS
index 9fcecf4..9b8a629 100644
--- a/content/browser/installedapp/OWNERS
+++ b/content/browser/installedapp/OWNERS
@@ -1,3 +1,5 @@
-mgiuca@chromium.org
+peter@chromium.org
+rayankans@chromium.org
+
 # COMPONENT: Blink>AppManifest
 # TEAM: platform-capabilities@chromium.org 
diff --git a/content/browser/loader/file_url_loader_factory.cc b/content/browser/loader/file_url_loader_factory.cc
index b676584..b6fadf64 100644
--- a/content/browser/loader/file_url_loader_factory.cc
+++ b/content/browser/loader/file_url_loader_factory.cc
@@ -858,10 +858,10 @@
 }
 
 void FileURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest loader) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
-  bindings_.AddBinding(this, std::move(loader));
+  receivers_.Add(this, std::move(loader));
 }
 
 void CreateFileURLLoader(
diff --git a/content/browser/loader/file_url_loader_factory.h b/content/browser/loader/file_url_loader_factory.h
index fb6f236b..4c0c865c 100644
--- a/content/browser/loader/file_url_loader_factory.h
+++ b/content/browser/loader/file_url_loader_factory.h
@@ -13,7 +13,8 @@
 #include "base/task/task_traits.h"
 #include "base/threading/thread_checker.h"
 #include "content/common/content_export.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
 namespace content {
@@ -47,7 +48,8 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest loader) override;
+  void Clone(
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) override;
 
   void CreateLoaderAndStartInternal(const network::ResourceRequest request,
                                     network::mojom::URLLoaderRequest loader,
@@ -58,7 +60,7 @@
   const scoped_refptr<SharedCorsOriginAccessList>
       shared_cors_origin_access_list_;
   const scoped_refptr<base::SequencedTaskRunner> task_runner_;
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   THREAD_CHECKER(thread_checker_);
 
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc
index 0a540e61..6a9b309 100644
--- a/content/browser/loader/navigation_url_loader_impl.cc
+++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -297,7 +297,8 @@
       BrowserContext* browser_context,
       const GURL& url,
       bool is_main_frame,
-      network::mojom::URLLoaderFactoryRequest proxied_factory_request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+          proxied_factory_receiver,
       network::mojom::URLLoaderFactoryPtrInfo proxied_factory_info,
       std::set<std::string> known_schemes,
       bool bypass_redirect_checks,
@@ -307,12 +308,11 @@
         url_(url),
         owner_(owner),
         response_loader_binding_(this),
-        proxied_factory_request_(std::move(proxied_factory_request)),
+        proxied_factory_receiver_(std::move(proxied_factory_receiver)),
         proxied_factory_info_(std::move(proxied_factory_info)),
         known_schemes_(std::move(known_schemes)),
         bypass_redirect_checks_(bypass_redirect_checks),
-        browser_context_(browser_context) {
-  }
+        browser_context_(browser_context) {}
 
   ~URLLoaderRequestController() override {
     DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -385,9 +385,10 @@
     if (needs_loader_factory_interceptor &&
         g_loader_factory_interceptor.Get()) {
       network::mojom::URLLoaderFactoryPtr factory;
-      auto request = mojo::MakeRequest(&factory);
-      g_loader_factory_interceptor.Get().Run(&request);
-      network_loader_factory_->Clone(std::move(request));
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver =
+          mojo::MakeRequest(&factory);
+      g_loader_factory_interceptor.Get().Run(&receiver);
+      network_loader_factory_->Clone(std::move(receiver));
       network_loader_factory_ =
           base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
               std::move(factory));
@@ -676,7 +677,7 @@
         network::mojom::URLLoaderFactoryPtr& non_network_factory =
             non_network_url_loader_factories_[resource_request_->url.scheme()];
         if (!non_network_factory.is_bound()) {
-          owner_->BindNonNetworkURLLoaderFactoryRequest(
+          owner_->BindNonNetworkURLLoaderFactoryReceiver(
               frame_tree_node_id_, resource_request_->url,
               mojo::MakeRequest(&non_network_factory));
         }
@@ -687,9 +688,10 @@
 
       if (g_loader_factory_interceptor.Get()) {
         network::mojom::URLLoaderFactoryPtr factory_ptr;
-        auto request = mojo::MakeRequest(&factory_ptr);
-        g_loader_factory_interceptor.Get().Run(&request);
-        factory->Clone(std::move(request));
+        mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver =
+            mojo::MakeRequest(&factory_ptr);
+        g_loader_factory_interceptor.Get().Run(&receiver);
+        factory->Clone(std::move(receiver));
         factory = base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
             std::move(factory_ptr));
       }
@@ -701,10 +703,10 @@
       // or AppCache). Hence this code is only reachable when one of the above
       // interceptors isn't used and the URL is either a data URL or has a
       // scheme which is handled by the network service.
-      if (proxied_factory_request_.is_pending()) {
+      if (proxied_factory_receiver_.is_valid()) {
         DCHECK(proxied_factory_info_.is_valid());
         // We don't worry about reconnection since it's a single navigation.
-        network_loader_factory_->Clone(std::move(proxied_factory_request_));
+        network_loader_factory_->Clone(std::move(proxied_factory_receiver_));
         factory = base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
             std::move(proxied_factory_info_));
       } else {
@@ -1183,13 +1185,14 @@
   base::Optional<network::URLLoaderCompletionStatus> status_;
 
   // Before creating this URLLoaderRequestController on UI thread, the embedder
-  // may have elected to proxy the URLLoaderFactory request, in which case these
-  // fields will contain input (info) and output (request) endpoints for the
-  // proxy. If this controller is handling a request for which proxying is
-  // supported, requests will be plumbed through these endpoints.
+  // may have elected to proxy the URLLoaderFactory receiver, in which case
+  // these fields will contain input (info) and output (receiver) endpoints for
+  // the proxy. If this controller is handling a receiver for which proxying is
+  // supported, receivers will be plumbed through these endpoints.
   //
-  // Note that these are only used for requests that go to the Network Service.
-  network::mojom::URLLoaderFactoryRequest proxied_factory_request_;
+  // Note that these are only used for receivers that go to the Network Service.
+  mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+      proxied_factory_receiver_;
   network::mojom::URLLoaderFactoryPtrInfo proxied_factory_info_;
 
   // The schemes that this loader can use. For anything else we'll try external
@@ -1280,7 +1283,8 @@
   }
 
   network::mojom::URLLoaderFactoryPtrInfo proxied_factory_info;
-  network::mojom::URLLoaderFactoryRequest proxied_factory_request;
+  mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+      proxied_factory_receiver;
   mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
       header_client;
   bool bypass_redirect_checks = false;
@@ -1292,7 +1296,7 @@
             frame_tree_node_id, &non_network_url_loader_factories_);
 
     // The embedder may want to proxy all network-bound URLLoaderFactory
-    // requests that it can. If it elects to do so, we'll pass its proxy
+    // receivers that it can. If it elects to do so, we'll pass its proxy
     // endpoints off to the URLLoaderRequestController where wthey will be
     // connected if the request type supports proxying.
     mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_factory;
@@ -1308,7 +1312,7 @@
       use_proxy = true;
     }
     if (use_proxy) {
-      proxied_factory_request = std::move(factory_receiver);
+      proxied_factory_receiver = std::move(factory_receiver);
       proxied_factory_info = std::move(pending_factory);
     }
 
@@ -1371,7 +1375,7 @@
   request_controller_ = std::make_unique<URLLoaderRequestController>(
       std::move(initial_interceptors), std::move(new_request), browser_context,
       request_info->common_params->url, request_info->is_main_frame,
-      std::move(proxied_factory_request), std::move(proxied_factory_info),
+      std::move(proxied_factory_receiver), std::move(proxied_factory_info),
       std::move(known_schemes), bypass_redirect_checks,
       weak_factory_.GetWeakPtr());
   request_controller_->Start(
@@ -1484,7 +1488,7 @@
   delegate_->OnRequestStarted(timestamp);
 }
 
-void NavigationURLLoaderImpl::BindNonNetworkURLLoaderFactoryRequest(
+void NavigationURLLoaderImpl::BindNonNetworkURLLoaderFactoryReceiver(
     int frame_tree_node_id,
     const GURL& url,
     mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory_receiver) {
diff --git a/content/browser/loader/navigation_url_loader_impl.h b/content/browser/loader/navigation_url_loader_impl.h
index baf6bd11..400e80b 100644
--- a/content/browser/loader/navigation_url_loader_impl.h
+++ b/content/browser/loader/navigation_url_loader_impl.h
@@ -14,6 +14,7 @@
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/ssl_status.h"
 #include "content/public/common/previews_state.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
@@ -71,7 +72,7 @@
   // schemes not handled by network service (e.g. files). This must be called on
   // the UI thread or before threads start.
   using URLLoaderFactoryInterceptor = base::RepeatingCallback<void(
-      network::mojom::URLLoaderFactoryRequest* request)>;
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory>* receiver)>;
   static void SetURLLoaderFactoryInterceptorForTesting(
       const URLLoaderFactoryInterceptor& interceptor);
 
@@ -92,7 +93,7 @@
   class URLLoaderRequestController;
   void OnRequestStarted(base::TimeTicks timestamp);
 
-  void BindNonNetworkURLLoaderFactoryRequest(
+  void BindNonNetworkURLLoaderFactoryReceiver(
       int frame_tree_node_id,
       const GURL& url,
       mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory_receiver);
diff --git a/content/browser/loader/prefetch_url_loader_service.cc b/content/browser/loader/prefetch_url_loader_service.cc
index 66109901..1facb6a 100644
--- a/content/browser/loader/prefetch_url_loader_service.cc
+++ b/content/browser/loader/prefetch_url_loader_service.cc
@@ -273,10 +273,10 @@
 }
 
 void PrefetchURLLoaderService::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   loader_factory_receivers_.Add(
-      this, std::move(request),
+      this, std::move(receiver),
       std::make_unique<BindContext>(
           loader_factory_receivers_.current_context()));
 }
diff --git a/content/browser/loader/prefetch_url_loader_service.h b/content/browser/loader/prefetch_url_loader_service.h
index c1d4b99b..d8404519 100644
--- a/content/browser/loader/prefetch_url_loader_service.h
+++ b/content/browser/loader/prefetch_url_loader_service.h
@@ -13,6 +13,7 @@
 #include "content/browser/web_package/signed_exchange_prefetch_metric_recorder.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 #include "third_party/blink/public/common/loader/url_loader_factory_bundle.h"
@@ -81,7 +82,8 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
 
   // This ensures that the BindContext's |cross_origin_factory| member exists
   // by setting it to a special URLLoaderFactory created by the current
diff --git a/content/browser/loader/single_request_url_loader_factory.cc b/content/browser/loader/single_request_url_loader_factory.cc
index 22d6ab4e..6e955913 100644
--- a/content/browser/loader/single_request_url_loader_factory.cc
+++ b/content/browser/loader/single_request_url_loader_factory.cc
@@ -93,7 +93,7 @@
 }
 
 void SingleRequestURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   NOTREACHED();
 }
 
diff --git a/content/browser/loader/single_request_url_loader_factory.h b/content/browser/loader/single_request_url_loader_factory.h
index dcf8336b..996d0d0 100644
--- a/content/browser/loader/single_request_url_loader_factory.h
+++ b/content/browser/loader/single_request_url_loader_factory.h
@@ -8,6 +8,7 @@
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
 #include "base/memory/ref_counted.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 
 namespace content {
@@ -33,7 +34,8 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
   std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override;
 
  private:
diff --git a/content/browser/notifications/notification_database_conversions_unittest.cc b/content/browser/notifications/notification_database_conversions_unittest.cc
index e6f6b28..dda490bf 100644
--- a/content/browser/notifications/notification_database_conversions_unittest.cc
+++ b/content/browser/notifications/notification_database_conversions_unittest.cc
@@ -17,9 +17,9 @@
 #include "content/public/browser/notification_database_data.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/notifications/notification_constants.h"
 #include "third_party/blink/public/common/notifications/notification_resources.h"
 #include "third_party/blink/public/mojom/notifications/notification.mojom.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_constants.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 
 namespace content {
@@ -89,7 +89,7 @@
   notification_data.show_trigger_timestamp =
       base::Time::FromJsTime(kShowTriggerTimestamp);
   notification_data.data = developer_data;
-  for (size_t i = 0; i < blink::kWebNotificationMaxActions; i++) {
+  for (size_t i = 0; i < blink::kNotificationMaxActions; i++) {
     blink::PlatformNotificationAction notification_action;
     notification_action.type = kNotificationActionType;
     notification_action.action = base::NumberToString(i);
@@ -196,7 +196,7 @@
 TEST(NotificationDatabaseConversionsTest, ActionDeserializationIsNotAdditive) {
   NotificationDatabaseData database_data;
 
-  for (size_t i = 0; i < blink::kWebNotificationMaxActions; ++i)
+  for (size_t i = 0; i < blink::kNotificationMaxActions; ++i)
     database_data.notification_data.actions.emplace_back();
 
   std::string serialized_data;
@@ -210,7 +210,7 @@
                                                   &copied_database_data));
 
   EXPECT_EQ(copied_database_data.notification_data.actions.size(),
-            blink::kWebNotificationMaxActions);
+            blink::kNotificationMaxActions);
 
   // Deserialize it again in the same |copied_database_data|. The number of
   // actions in the structure should not be affected.
@@ -218,7 +218,7 @@
                                                   &copied_database_data));
 
   EXPECT_EQ(copied_database_data.notification_data.actions.size(),
-            blink::kWebNotificationMaxActions);
+            blink::kNotificationMaxActions);
 }
 
 TEST(NotificationDatabaseConversionsTest, SerializeAndDeserializeActionTypes) {
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index dfa66db..c9a43d78 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -194,7 +194,6 @@
 #include "media/mojo/services/video_decode_perf_history.h"
 #include "media/webrtc/webrtc_switches.h"
 #include "mojo/public/cpp/bindings/receiver.h"
-#include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/system/platform_handle.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "ppapi/buildflags/buildflags.h"
@@ -2490,7 +2489,7 @@
 }
 
 void RenderProcessHostImpl::CreateURLLoaderFactoryForRendererProcess(
-    network::mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   base::Optional<url::Origin> request_initiator_site_lock;
@@ -2511,7 +2510,7 @@
                          network::mojom::CrossOriginEmbedderPolicy::kNone,
                          nullptr /* preferences */, net::NetworkIsolationKey(),
                          mojo::NullRemote() /* header_client */,
-                         std::move(request));
+                         std::move(receiver));
 }
 
 void RenderProcessHostImpl::CreateURLLoaderFactory(
@@ -2521,10 +2520,10 @@
     const net::NetworkIsolationKey& network_isolation_key,
     mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
         header_client,
-    network::mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   CreateURLLoaderFactoryInternal(
       origin, embedder_policy, preferences, network_isolation_key,
-      std::move(header_client), std::move(request), false /* is_trusted */);
+      std::move(header_client), std::move(receiver), false /* is_trusted */);
 }
 
 void RenderProcessHostImpl::CreateTrustedURLLoaderFactory(
@@ -2533,10 +2532,10 @@
     const WebPreferences* preferences,
     mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
         header_client,
-    network::mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   CreateURLLoaderFactoryInternal(origin, embedder_policy, preferences,
                                  base::nullopt, std::move(header_client),
-                                 std::move(request), true /* is_trusted */);
+                                 std::move(receiver), true /* is_trusted */);
 }
 
 void RenderProcessHostImpl::CreateURLLoaderFactoryInternal(
@@ -2546,7 +2545,7 @@
     const base::Optional<net::NetworkIsolationKey>& network_isolation_key,
     mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
         header_client,
-    network::mojom::URLLoaderFactoryRequest request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
     bool is_trusted) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
@@ -2557,7 +2556,8 @@
 
   network::mojom::NetworkContext* network_context =
       storage_partition_impl_->GetNetworkContext();
-  network::mojom::URLLoaderFactoryPtrInfo embedder_provided_factory;
+  mojo::PendingRemote<network::mojom::URLLoaderFactory>
+      embedder_provided_factory;
   if (origin.has_value()) {
     embedder_provided_factory =
         GetContentClient()->browser()->CreateURLLoaderFactoryForNetworkRequests(
@@ -2565,8 +2565,7 @@
             network_isolation_key);
   }
   if (embedder_provided_factory) {
-    mojo::FuseInterface(std::move(request),
-                        std::move(embedder_provided_factory));
+    mojo::FusePipes(std::move(receiver), std::move(embedder_provided_factory));
   } else {
     network::mojom::URLLoaderFactoryParamsPtr params =
         network::mojom::URLLoaderFactoryParams::New();
@@ -2600,7 +2599,7 @@
       params->is_corb_enabled = true;
     }
 
-    network_context->CreateURLLoaderFactory(std::move(request),
+    network_context->CreateURLLoaderFactory(std::move(receiver),
                                             std::move(params));
   }
 }
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h
index 173f73c..0e3484f1 100644
--- a/content/browser/renderer_host/render_process_host_impl.h
+++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -58,6 +58,7 @@
 #include "mojo/public/cpp/bindings/generic_pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_associated_receiver.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/system/invitation.h"
 #include "net/base/network_isolation_key.h"
@@ -234,7 +235,8 @@
       const net::NetworkIsolationKey& network_isolation_key,
       mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
           header_client,
-      network::mojom::URLLoaderFactoryRequest request) override;
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
 
   void SetIsNeverSuitableForReuse() override;
   bool MayReuseHost() override;
@@ -280,7 +282,7 @@
       const WebPreferences* preferences,
       mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
           header_client,
-      network::mojom::URLLoaderFactoryRequest request);
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver);
 
   // Call this function when it is evident that the child process is actively
   // performing some operation, for example if we just received an IPC message.
@@ -776,7 +778,7 @@
   // URLLoaderFactories are associated with a specific origin and an execution
   // context (e.g. a frame, a service worker or any other kind of worker).
   void CreateURLLoaderFactoryForRendererProcess(
-      network::mojom::URLLoaderFactoryRequest request);
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver);
 
   // Creates a URLLoaderFactory whose NetworkIsolationKey is set if
   // |network_isoation_key| has a value, and whose trust is given by
@@ -789,7 +791,7 @@
       const base::Optional<net::NetworkIsolationKey>& network_isolation_key,
       mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
           header_client,
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       bool is_trusted);
 
   // Handles incoming requests to bind a process-scoped receiver from the
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc
index aefea830..bc736a1 100644
--- a/content/browser/service_manager/service_manager_context.cc
+++ b/content/browser/service_manager/service_manager_context.cc
@@ -228,9 +228,10 @@
   }
 
   // SharedURLLoaderFactory implementation:
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
     GetContentClient()->browser()->GetSystemSharedURLLoaderFactory()->Clone(
-        std::move(request));
+        std::move(receiver));
   }
 
   std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override {
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
index 3596ee36..b39886155 100644
--- a/content/browser/service_worker/embedded_worker_instance.cc
+++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -36,8 +36,6 @@
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_switches.h"
 #include "ipc/ipc_message.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/mojom/loader/url_loader_factory_bundle.mojom.h"
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h
index bf977e7..d8523ee 100644
--- a/content/browser/service_worker/embedded_worker_instance.h
+++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -26,8 +26,10 @@
 #include "content/common/content_export.h"
 #include "content/public/browser/content_browser_client.h"
 #include "mojo/public/cpp/bindings/associated_receiver.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
 #include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom.h"
 #include "third_party/blink/public/mojom/service_worker/controller_service_worker.mojom.h"
@@ -208,7 +210,7 @@
   static std::string StartingPhaseToString(StartingPhase phase);
 
   using CreateNetworkFactoryCallback = base::RepeatingCallback<void(
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       int process_id,
       network::mojom::URLLoaderFactoryPtrInfo original_factory)>;
   // Allows overriding the URLLoaderFactory creation for loading subresources
@@ -364,7 +366,7 @@
   // thread.
   base::SequenceBound<ServiceWorkerContentSettingsProxyImpl> content_settings_;
 
-  mojo::StrongBindingPtr<network::mojom::URLLoaderFactory>
+  mojo::SelfOwnedReceiverRef<network::mojom::URLLoaderFactory>
       script_loader_factory_;
 
   const scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
diff --git a/content/browser/service_worker/service_worker_script_loader_factory.cc b/content/browser/service_worker/service_worker_script_loader_factory.cc
index ff766d7..862a1e2 100644
--- a/content/browser/service_worker/service_worker_script_loader_factory.cc
+++ b/content/browser/service_worker/service_worker_script_loader_factory.cc
@@ -149,8 +149,8 @@
 }
 
 void ServiceWorkerScriptLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
-  bindings_.AddBinding(this, std::move(request));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
+  receivers_.Add(this, std::move(receiver));
 }
 
 void ServiceWorkerScriptLoaderFactory::Update(
diff --git a/content/browser/service_worker/service_worker_script_loader_factory.h b/content/browser/service_worker/service_worker_script_loader_factory.h
index 928e4b8..c7a5d4d1c 100644
--- a/content/browser/service_worker/service_worker_script_loader_factory.h
+++ b/content/browser/service_worker/service_worker_script_loader_factory.h
@@ -9,7 +9,8 @@
 
 #include "base/macros.h"
 #include "content/common/content_export.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
 namespace network {
@@ -62,7 +63,8 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
 
   void Update(scoped_refptr<network::SharedURLLoaderFactory> loader_factory);
 
@@ -99,7 +101,7 @@
   scoped_refptr<network::SharedURLLoaderFactory>
       loader_factory_for_new_scripts_;
 
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   // Used to copy script started at CopyScript().
   std::unique_ptr<ServiceWorkerCacheWriter> cache_writer_;
diff --git a/content/browser/service_worker/service_worker_test_utils.cc b/content/browser/service_worker/service_worker_test_utils.cc
index c3ee035..1fc80d4 100644
--- a/content/browser/service_worker/service_worker_test_utils.cc
+++ b/content/browser/service_worker/service_worker_test_utils.cc
@@ -27,6 +27,7 @@
 #include "content/public/common/child_process_host.h"
 #include "content/public/common/transferrable_url_loader.mojom.h"
 #include "mojo/public/cpp/bindings/pending_associated_remote.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "net/base/io_buffer.h"
 #include "net/base/test_completion_callback.h"
@@ -56,7 +57,8 @@
     client->OnComplete(
         network::URLLoaderCompletionStatus(net::ERR_NOT_IMPLEMENTED));
   }
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
     NOTREACHED();
   }
 
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc
index 2cee6bf..b5efd8f5 100644
--- a/content/browser/site_instance_impl.cc
+++ b/content/browser/site_instance_impl.cc
@@ -986,7 +986,7 @@
     RenderProcessHost* host,
     const ChildProcessTerminationInfo& info) {
   for (auto& observer : observers_)
-    observer.RenderProcessGone(this);
+    observer.RenderProcessGone(this, info);
 }
 
 void SiteInstanceImpl::LockToOriginIfNeeded() {
diff --git a/content/browser/site_instance_impl.h b/content/browser/site_instance_impl.h
index 1edb9fd6..79fa3347 100644
--- a/content/browser/site_instance_impl.h
+++ b/content/browser/site_instance_impl.h
@@ -32,7 +32,8 @@
     virtual void ActiveFrameCountIsZero(SiteInstanceImpl* site_instance) {}
 
     // Called when the renderer process of this SiteInstance has exited.
-    virtual void RenderProcessGone(SiteInstanceImpl* site_instance) = 0;
+    virtual void RenderProcessGone(SiteInstanceImpl* site_instance,
+                                   const ChildProcessTerminationInfo& info) = 0;
   };
 
   static scoped_refptr<SiteInstanceImpl> Create(
diff --git a/content/browser/startup_task_runner.cc b/content/browser/startup_task_runner.cc
index 51c98506..62deb23 100644
--- a/content/browser/startup_task_runner.cc
+++ b/content/browser/startup_task_runner.cc
@@ -18,7 +18,7 @@
 StartupTaskRunner::~StartupTaskRunner() {}
 
 void StartupTaskRunner::AddTask(StartupTask callback) {
-  task_list_.push_back(callback);
+  task_list_.push_back(std::move(callback));
 }
 
 void StartupTaskRunner::StartRunningTasksAsync() {
@@ -29,16 +29,16 @@
       std::move(startup_complete_callback_).Run(result);
     }
   } else {
-    const base::Closure next_task =
-        base::Bind(&StartupTaskRunner::WrappedTask, base::Unretained(this));
-    proxy_->PostNonNestableTask(FROM_HERE, next_task);
+    base::OnceClosure next_task =
+        base::BindOnce(&StartupTaskRunner::WrappedTask, base::Unretained(this));
+    proxy_->PostNonNestableTask(FROM_HERE, std::move(next_task));
   }
 }
 
 void StartupTaskRunner::RunAllTasksNow() {
   int result = 0;
   for (auto it = task_list_.begin(); it != task_list_.end(); it++) {
-    result = it->Run();
+    result = std::move(*it).Run();
     if (result > 0) break;
   }
   task_list_.clear();
@@ -54,7 +54,7 @@
     // so there is nothing to do
     return;
   }
-  int result = task_list_.front().Run();
+  int result = std::move(task_list_.front()).Run();
   task_list_.pop_front();
   if (result > 0) {
     // Stop now and throw away the remaining tasks
@@ -65,9 +65,9 @@
       std::move(startup_complete_callback_).Run(result);
     }
   } else {
-    const base::Closure next_task =
-        base::Bind(&StartupTaskRunner::WrappedTask, base::Unretained(this));
-    proxy_->PostNonNestableTask(FROM_HERE, next_task);
+    base::OnceClosure next_task =
+        base::BindOnce(&StartupTaskRunner::WrappedTask, base::Unretained(this));
+    proxy_->PostNonNestableTask(FROM_HERE, std::move(next_task));
   }
 }
 
diff --git a/content/browser/startup_task_runner.h b/content/browser/startup_task_runner.h
index a38776d14..012cb0c 100644
--- a/content/browser/startup_task_runner.h
+++ b/content/browser/startup_task_runner.h
@@ -20,7 +20,7 @@
 // A startup task is a void function returning the status on completion.
 // a status of > 0 indicates a failure, and that no further startup tasks should
 // be run.
-typedef base::Callback<int(void)> StartupTask;
+typedef base::OnceCallback<int(void)> StartupTask;
 
 // This class runs startup tasks. The tasks are either run immediately inline,
 // or are queued one at a time on the UI thread's message loop. If the events
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index e366564..c8154bd 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -69,8 +69,6 @@
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "mojo/public/cpp/bindings/callback_helpers.h"
-#include "mojo/public/cpp/bindings/pending_remote.h"
-#include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "net/base/net_errors.h"
 #include "net/cookies/canonical_cookie.h"
@@ -891,12 +889,13 @@
                                traffic_annotation);
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
     if (!storage_partition_)
       return;
     storage_partition_
         ->GetURLLoaderFactoryForBrowserProcessInternal(corb_enabled_)
-        ->Clone(std::move(request));
+        ->Clone(std::move(receiver));
   }
 
   // SharedURLLoaderFactory implementation:
diff --git a/content/browser/url_loader_factory_getter.cc b/content/browser/url_loader_factory_getter.cc
index 9f06bfc..0d8f01f 100644
--- a/content/browser/url_loader_factory_getter.cc
+++ b/content/browser/url_loader_factory_getter.cc
@@ -88,11 +88,12 @@
                                traffic_annotation);
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
     if (!factory_getter_)
       return;
     factory_getter_->GetURLLoaderFactory(is_corb_enabled_)
-        ->Clone(std::move(request));
+        ->Clone(std::move(receiver));
   }
 
   // SharedURLLoaderFactory implementation:
@@ -134,11 +135,11 @@
   // TODO(mmenke):  Is one less thread hop on startup worth the extra complexity
   // of two different pipe creation paths?
   network::mojom::URLLoaderFactoryPtr network_factory;
-  network::mojom::URLLoaderFactoryRequest pending_network_factory_request =
-      MakeRequest(&network_factory);
+  mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+      pending_network_factory_receiver = MakeRequest(&network_factory);
 
   HandleNetworkFactoryRequestOnUIThread(
-      std::move(pending_network_factory_request), false);
+      std::move(pending_network_factory_receiver), false);
 
   base::PostTask(FROM_HERE, {BrowserThread::IO},
                  base::BindOnce(&URLLoaderFactoryGetter::InitializeOnIOThread,
@@ -203,9 +204,10 @@
 }
 
 void URLLoaderFactoryGetter::CloneNetworkFactory(
-    network::mojom::URLLoaderFactoryRequest network_factory_request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+        network_factory_receiver) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
-  GetURLLoaderFactory(false)->Clone(std::move(network_factory_request));
+  GetURLLoaderFactory(false)->Clone(std::move(network_factory_receiver));
 }
 
 void URLLoaderFactoryGetter::SetNetworkFactoryForTesting(
@@ -277,7 +279,8 @@
 }
 
 void URLLoaderFactoryGetter::HandleNetworkFactoryRequestOnUIThread(
-    network::mojom::URLLoaderFactoryRequest network_factory_request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+        network_factory_receiver,
     bool is_corb_enabled) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // |StoragePartitionImpl| may have went away while |URLLoaderFactoryGetter| is
@@ -294,7 +297,7 @@
       base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kDisableWebSecurity);
   partition_->GetNetworkContext()->CreateURLLoaderFactory(
-      std::move(network_factory_request), std::move(params));
+      std::move(network_factory_receiver), std::move(params));
 }
 
 }  // namespace content
diff --git a/content/browser/url_loader_factory_getter.h b/content/browser/url_loader_factory_getter.h
index 6ec4c56a..fcf2e707 100644
--- a/content/browser/url_loader_factory_getter.h
+++ b/content/browser/url_loader_factory_getter.h
@@ -12,6 +12,7 @@
 #include "base/memory/ref_counted.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
 namespace network {
@@ -75,7 +76,8 @@
   // When NetworkService is disabled, this clones the non-NetworkService direct
   // network factory.
   CONTENT_EXPORT void CloneNetworkFactory(
-      network::mojom::URLLoaderFactoryRequest network_factory_request);
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+          network_factory_receiver);
 
   // Overrides the network URLLoaderFactory for subsequent requests. Passing a
   // null pointer will restore the default behavior.
@@ -125,7 +127,8 @@
 
   // Send |network_factory_request| to cached |StoragePartitionImpl|.
   void HandleNetworkFactoryRequestOnUIThread(
-      network::mojom::URLLoaderFactoryRequest network_factory_request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+          network_factory_receiver,
       bool is_corb_enabled);
 
   // Called on the IO thread to get the URLLoaderFactory to the network service.
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 0660fdd8..70cf3d2 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -5277,7 +5277,6 @@
 
 void WebContentsImpl::NotifyViewSwapped(RenderViewHost* old_host,
                                         RenderViewHost* new_host) {
-  DCHECK_NE(old_host, new_host);
   // After sending out a swap notification, we need to send a disconnect
   // notification so that clients that pick up a pointer to |this| can NULL the
   // pointer.  See Bug 1230284.
@@ -6532,14 +6531,8 @@
                                                      RenderFrameHost* new_host,
                                                      bool is_main_frame) {
   if (is_main_frame) {
-    RenderViewHost* old_rvh =
-        old_host ? old_host->GetRenderViewHost() : nullptr;
-    RenderViewHost* new_rvh = new_host->GetRenderViewHost();
-    // |old_rvh| and |new_rvh| might be equal when navigating from a crashed
-    // RenderFrameHost to a new same-site one. With RenderDocument, this will
-    // happen for every same-site navigation.
-    if (old_rvh != new_rvh)
-      NotifyViewSwapped(old_rvh, new_rvh);
+    NotifyViewSwapped(old_host ? old_host->GetRenderViewHost() : nullptr,
+                      new_host->GetRenderViewHost());
 
     // Make sure the visible RVH reflects the new delegate's preferences.
     if (delegate_)
diff --git a/content/browser/web_package/bundled_exchanges_url_loader_factory.cc b/content/browser/web_package/bundled_exchanges_url_loader_factory.cc
index 1d1b43c..d5409bf7 100644
--- a/content/browser/web_package/bundled_exchanges_url_loader_factory.cc
+++ b/content/browser/web_package/bundled_exchanges_url_loader_factory.cc
@@ -217,8 +217,8 @@
 }
 
 void BundledExchangesURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
-  bindings_.AddBinding(this, std::move(request));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
+  receivers_.Add(this, std::move(receiver));
 }
 
 }  // namespace content
diff --git a/content/browser/web_package/bundled_exchanges_url_loader_factory.h b/content/browser/web_package/bundled_exchanges_url_loader_factory.h
index ae6961a..dac1746 100644
--- a/content/browser/web_package/bundled_exchanges_url_loader_factory.h
+++ b/content/browser/web_package/bundled_exchanges_url_loader_factory.h
@@ -8,8 +8,9 @@
 #include "base/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "content/common/content_export.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
@@ -41,7 +42,8 @@
                             network::mojom::URLLoaderClientPtr loader_client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
 
   const scoped_refptr<BundledExchangesReader>& reader() const {
     return reader_;
@@ -51,7 +53,7 @@
   class EntryLoader;
   friend class EntryLoader;
 
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
   scoped_refptr<BundledExchangesReader> reader_;
   mojo::Remote<network::mojom::URLLoaderFactory> fallback_factory_;
 
diff --git a/content/browser/web_package/prefetched_signed_exchange_cache.cc b/content/browser/web_package/prefetched_signed_exchange_cache.cc
index 50162f6..1bf7de4 100644
--- a/content/browser/web_package/prefetched_signed_exchange_cache.cc
+++ b/content/browser/web_package/prefetched_signed_exchange_cache.cc
@@ -18,8 +18,9 @@
 #include "content/public/browser/browser_thread.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/navigation_policy.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "net/http/http_cache.h"
 #include "net/http/http_util.h"
@@ -330,14 +331,14 @@
     : public network::mojom::URLLoaderFactory {
  public:
   SubresourceSignedExchangeURLLoaderFactory(
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       std::unique_ptr<const PrefetchedSignedExchangeCache::Entry> entry,
       const url::Origin& request_initiator_site_lock)
       : entry_(std::move(entry)),
         request_initiator_site_lock_(request_initiator_site_lock) {
-    bindings_.AddBinding(this, std::move(request));
-    bindings_.set_connection_error_handler(base::BindRepeating(
-        &SubresourceSignedExchangeURLLoaderFactory::OnConnectionError,
+    receivers_.Add(this, std::move(receiver));
+    receivers_.set_disconnect_handler(base::BindRepeating(
+        &SubresourceSignedExchangeURLLoaderFactory::OnMojoDisconnect,
         base::Unretained(this)));
   }
   ~SubresourceSignedExchangeURLLoaderFactory() override {}
@@ -361,20 +362,21 @@
             false /* is_navigation_request */),
         std::move(loader));
   }
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
-    bindings_.AddBinding(this, std::move(request));
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
+    receivers_.Add(this, std::move(receiver));
   }
 
  private:
-  void OnConnectionError() {
-    if (!bindings_.empty())
+  void OnMojoDisconnect() {
+    if (!receivers_.empty())
       return;
     delete this;
   }
 
   std::unique_ptr<const PrefetchedSignedExchangeCache::Entry> entry_;
   const url::Origin request_initiator_site_lock_;
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   DISALLOW_COPY_AND_ASSIGN(SubresourceSignedExchangeURLLoaderFactory);
 };
diff --git a/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc b/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
index 99ffb31..d3ea563 100644
--- a/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
+++ b/content/browser/web_package/signed_exchange_cert_fetcher_unittest.cc
@@ -14,6 +14,7 @@
 #include "components/cbor/writer.h"
 #include "content/public/common/resource_type.h"
 #include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/system/data_pipe_utils.h"
 #include "net/base/load_flags.h"
 #include "net/cert/x509_util.h"
@@ -119,7 +120,8 @@
     client_ptr_ = std::move(client);
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest factory) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory)
+      override {
     NOTREACHED();
   }
 
diff --git a/content/browser/web_package/signed_exchange_loader_unittest.cc b/content/browser/web_package/signed_exchange_loader_unittest.cc
index 233c35d9..d5d8166f 100644
--- a/content/browser/web_package/signed_exchange_loader_unittest.cc
+++ b/content/browser/web_package/signed_exchange_loader_unittest.cc
@@ -18,6 +18,7 @@
 #include "content/browser/web_package/signed_exchange_reporter.h"
 #include "content/public/common/content_features.h"
 #include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/system/data_pipe_producer.h"
 #include "mojo/public/cpp/system/string_data_source.h"
 #include "net/http/http_status_code.h"
@@ -117,7 +118,8 @@
       ping_loader_ = std::make_unique<MockURLLoader>(std::move(request));
       ping_loader_client_ = std::move(client);
     }
-    void Clone(network::mojom::URLLoaderFactoryRequest request) override {}
+    void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+        override {}
 
     std::unique_ptr<MockURLLoader> ping_loader_;
     network::mojom::URLLoaderClientPtr ping_loader_client_;
diff --git a/content/browser/webui/web_ui_url_loader_factory.cc b/content/browser/webui/web_ui_url_loader_factory.cc
index 1e26a4e..5c152c58 100644
--- a/content/browser/webui/web_ui_url_loader_factory.cc
+++ b/content/browser/webui/web_ui_url_loader_factory.cc
@@ -30,7 +30,8 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/common/url_constants.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/mojom/network_service.mojom.h"
 #include "ui/base/template_expressions.h"
 
@@ -233,9 +234,9 @@
 
   ~WebUIURLLoaderFactory() override {}
 
-  void AddBinding(mojo::PendingReceiver<network::mojom::URLLoaderFactory>
-                      factory_receiver) {
-    loader_factory_bindings_.AddBinding(this, std::move(factory_receiver));
+  void AddReceiver(mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+                       factory_receiver) {
+    loader_factory_receivers_.Add(this, std::move(factory_receiver));
   }
 
   // network::mojom::URLLoaderFactory implementation:
@@ -300,8 +301,9 @@
             GetStoragePartition()->browser_context()->GetResourceContext()));
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
-    loader_factory_bindings_.AddBinding(this, std::move(request));
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
+    loader_factory_receivers_.Add(this, std::move(receiver));
   }
 
   // WebContentsObserver implementation:
@@ -324,7 +326,7 @@
   RenderFrameHost* render_frame_host_;
   std::string scheme_;
   const base::flat_set<std::string> allowed_hosts_;  // if empty all allowed.
-  mojo::BindingSet<network::mojom::URLLoaderFactory> loader_factory_bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> loader_factory_receivers_;
 
   DISALLOW_COPY_AND_ASSIGN(WebUIURLLoaderFactory);
 };
@@ -352,7 +354,7 @@
         std::make_unique<WebUIURLLoaderFactory>(render_frame_host, scheme,
                                                 base::flat_set<std::string>());
   }
-  g_web_ui_url_loader_factories.Get()[routing_id]->AddBinding(
+  g_web_ui_url_loader_factories.Get()[routing_id]->AddReceiver(
       std::move(factory_receiver));
 }
 
diff --git a/content/browser/worker_host/shared_worker_host.h b/content/browser/worker_host/shared_worker_host.h
index b5612e11..33c73934 100644
--- a/content/browser/worker_host/shared_worker_host.h
+++ b/content/browser/worker_host/shared_worker_host.h
@@ -75,7 +75,7 @@
   // This method must be called either on the UI thread or before threads start.
   // This callback is run on the UI thread.
   using CreateNetworkFactoryCallback = base::RepeatingCallback<void(
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       int worker_process_id,
       network::mojom::URLLoaderFactoryPtrInfo original_factory)>;
   static void SetNetworkFactoryForSubresourcesForTesting(
diff --git a/content/browser/worker_host/worker_script_loader_factory.cc b/content/browser/worker_host/worker_script_loader_factory.cc
index cd7b4d8b..56cd2baf 100644
--- a/content/browser/worker_host/worker_script_loader_factory.cc
+++ b/content/browser/worker_host/worker_script_loader_factory.cc
@@ -68,7 +68,7 @@
 }
 
 void WorkerScriptLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   // This method is required to support synchronous requests, which shared
   // worker script requests are not.
   NOTREACHED();
diff --git a/content/browser/worker_host/worker_script_loader_factory.h b/content/browser/worker_host/worker_script_loader_factory.h
index 94a652f7..3862b65 100644
--- a/content/browser/worker_host/worker_script_loader_factory.h
+++ b/content/browser/worker_host/worker_script_loader_factory.h
@@ -8,6 +8,7 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "content/browser/navigation_subresource_loader_params.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
 namespace network {
@@ -61,7 +62,8 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
 
   base::WeakPtr<WorkerScriptLoader> GetScriptLoader() { return script_loader_; }
 
diff --git a/content/common/throttling_url_loader_unittest.cc b/content/common/throttling_url_loader_unittest.cc
index 8b768fd4..145bd2f 100644
--- a/content/common/throttling_url_loader_unittest.cc
+++ b/content/common/throttling_url_loader_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/run_loop.h"
 #include "base/test/bind_test_util.h"
 #include "base/test/task_environment.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
@@ -113,7 +114,8 @@
       on_create_loader_and_start_callback_.Run(url_request);
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
     NOTREACHED();
   }
 
diff --git a/content/public/browser/bluetooth_chooser.h b/content/public/browser/bluetooth_chooser.h
index c7fa6e12..652fad37 100644
--- a/content/public/browser/bluetooth_chooser.h
+++ b/content/public/browser/bluetooth_chooser.h
@@ -47,7 +47,7 @@
   // After the EventHandler is called with Event::CANCELLED, Event::SELECTED,
   // Event::DENIED_PERMISSION or Event::SHOW_*, it won't be called again, and
   // users must not call any more BluetoothChooser methods.
-  typedef base::Callback<void(Event, const std::string& opt_device_id)>
+  typedef base::RepeatingCallback<void(Event, const std::string& opt_device_id)>
       EventHandler;
 
   BluetoothChooser() {}
diff --git a/content/public/browser/browser_context.h b/content/public/browser/browser_context.h
index a7f24a6a..37c9639 100644
--- a/content/public/browser/browser_context.h
+++ b/content/public/browser/browser_context.h
@@ -135,7 +135,8 @@
       BrowserContext* browser_context,
       const GURL& site,
       bool can_create = true);
-  using StoragePartitionCallback = base::Callback<void(StoragePartition*)>;
+  using StoragePartitionCallback =
+      base::RepeatingCallback<void(StoragePartition*)>;
   static void ForEachStoragePartition(
       BrowserContext* browser_context,
       const StoragePartitionCallback& callback);
diff --git a/content/public/browser/browsing_data_filter_builder.h b/content/public/browser/browsing_data_filter_builder.h
index b1f05a4e..f1080fc 100644
--- a/content/public/browser/browsing_data_filter_builder.h
+++ b/content/public/browser/browsing_data_filter_builder.h
@@ -82,7 +82,7 @@
 
   // A convenience method to produce an empty blacklist, a filter that matches
   // everything.
-  static base::Callback<bool(const GURL&)> BuildNoopFilter();
+  static base::RepeatingCallback<bool(const GURL&)> BuildNoopFilter();
 
   // The mode of the filter.
   virtual Mode GetMode() = 0;
diff --git a/content/public/browser/devtools_agent_host.h b/content/public/browser/devtools_agent_host.h
index 096b6c2..3bc7d2f 100644
--- a/content/public/browser/devtools_agent_host.h
+++ b/content/public/browser/devtools_agent_host.h
@@ -74,7 +74,7 @@
       std::unique_ptr<DevToolsExternalAgentProxyDelegate> delegate);
 
   using CreateServerSocketCallback =
-      base::Callback<std::unique_ptr<net::ServerSocket>(std::string*)>;
+      base::RepeatingCallback<std::unique_ptr<net::ServerSocket>(std::string*)>;
 
   // Creates DevToolsAgentHost for the browser, which works with browser-wide
   // debugging protocol.
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h
index 0beaa27..9a8caf0 100644
--- a/content/public/browser/render_frame_host.h
+++ b/content/public/browser/render_frame_host.h
@@ -19,6 +19,7 @@
 #include "content/public/common/isolated_world_ids.h"
 #include "ipc/ipc_listener.h"
 #include "ipc/ipc_sender.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
 #include "third_party/blink/public/common/feature_policy/feature_policy.h"
@@ -354,7 +355,8 @@
   // If this returns true, any redirect safety checks should be bypassed in
   // downstream loaders.
   virtual bool CreateNetworkServiceDefaultFactory(
-      network::mojom::URLLoaderFactoryRequest default_factory_request) = 0;
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+          default_factory_receiver) = 0;
 
   // Requests that future URLLoaderFactoryBundle(s) sent to the renderer should
   // use a separate URLLoaderFactory for requests initiated by isolated worlds
diff --git a/content/public/browser/render_process_host.h b/content/public/browser/render_process_host.h
index dda7734..1ecdeca 100644
--- a/content/public/browser/render_process_host.h
+++ b/content/public/browser/render_process_host.h
@@ -415,11 +415,11 @@
   // Create an URLLoaderFactory that can be used by |origin| being hosted in
   // |this| process.
   //
-  // When NetworkService is enabled, |request| will be bound with a new
+  // When NetworkService is enabled, |receiver| will be bound with a new
   // URLLoaderFactory created from the storage partition's Network Context. Note
   // that the URLLoaderFactory returned by this method does NOT support
   // auto-reconnect after a crash of Network Service.
-  // When NetworkService is not enabled, |request| will be bound with a
+  // When NetworkService is not enabled, |receiver| will be bound with a
   // URLLoaderFactory which routes requests to ResourceDispatcherHost.
   //
   // |preferences| is an optional argument that might be used to control some
@@ -442,7 +442,7 @@
       const net::NetworkIsolationKey& network_isolation_key,
       mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
           header_client,
-      network::mojom::URLLoaderFactoryRequest request) = 0;
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) = 0;
 
   // Whether this process is locked out from ever being reused for sites other
   // than the ones it currently has.
diff --git a/content/public/renderer/document_state.cc b/content/public/renderer/document_state.cc
index c8c83fe3..99929fc3 100644
--- a/content/public/renderer/document_state.cc
+++ b/content/public/renderer/document_state.cc
@@ -6,23 +6,12 @@
 
 namespace content {
 
-DocumentState::DocumentState()
-    : was_fetched_via_spdy_(false),
-      was_alpn_negotiated_(false),
-      was_alternate_protocol_available_(false),
-      connection_info_(net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN),
-      was_load_data_with_base_url_request_(false) {}
+DocumentState::DocumentState() : was_load_data_with_base_url_request_(false) {}
 
 DocumentState::~DocumentState() {}
 
 std::unique_ptr<DocumentState> DocumentState::Clone() {
   std::unique_ptr<DocumentState> new_document_state(new DocumentState());
-  new_document_state->set_was_fetched_via_spdy(was_fetched_via_spdy_);
-  new_document_state->set_was_alpn_negotiated(was_alpn_negotiated_);
-  new_document_state->set_alpn_negotiated_protocol(alpn_negotiated_protocol_);
-  new_document_state->set_was_alternate_protocol_available(
-      was_alternate_protocol_available_);
-  new_document_state->set_connection_info(connection_info_);
   new_document_state->set_was_load_data_with_base_url_request(
       was_load_data_with_base_url_request_);
   new_document_state->set_data_url(data_url_);
diff --git a/content/public/renderer/document_state.h b/content/public/renderer/document_state.h
index a3a78bb..c78fba876 100644
--- a/content/public/renderer/document_state.h
+++ b/content/public/renderer/document_state.h
@@ -35,35 +35,6 @@
   // user data is not copied.
   std::unique_ptr<DocumentState> Clone();
 
-  // Indicator if SPDY was used as part of this page load.
-  bool was_fetched_via_spdy() const { return was_fetched_via_spdy_; }
-  void set_was_fetched_via_spdy(bool value) { was_fetched_via_spdy_ = value; }
-
-  bool was_alpn_negotiated() const { return was_alpn_negotiated_; }
-  void set_was_alpn_negotiated(bool value) { was_alpn_negotiated_ = value; }
-
-  const std::string& alpn_negotiated_protocol() const {
-    return alpn_negotiated_protocol_;
-  }
-  void set_alpn_negotiated_protocol(const std::string& value) {
-    alpn_negotiated_protocol_ = value;
-  }
-
-  bool was_alternate_protocol_available() const {
-    return was_alternate_protocol_available_;
-  }
-  void set_was_alternate_protocol_available(bool value) {
-    was_alternate_protocol_available_ = value;
-  }
-
-  net::HttpResponseInfo::ConnectionInfo connection_info() const {
-    return connection_info_;
-  }
-  void set_connection_info(
-      net::HttpResponseInfo::ConnectionInfo connection_info) {
-    connection_info_ = connection_info;
-  }
-
   // For LoadDataWithBaseURL navigations, |was_load_data_with_base_url_request_|
   // is set to true and |data_url_| is set to the data URL of the navigation.
   // Otherwise, |was_load_data_with_base_url_request_| is false and |data_url_|
@@ -82,12 +53,6 @@
   }
 
  private:
-  bool was_fetched_via_spdy_;
-  bool was_alpn_negotiated_;
-  std::string alpn_negotiated_protocol_;
-  bool was_alternate_protocol_available_;
-  net::HttpResponseInfo::ConnectionInfo connection_info_;
-
   bool was_load_data_with_base_url_request_;
   GURL data_url_;
 };
diff --git a/content/public/test/mock_render_process_host.cc b/content/public/test/mock_render_process_host.cc
index 325dd58..b3a14cc7 100644
--- a/content/public/test/mock_render_process_host.cc
+++ b/content/public/test/mock_render_process_host.cc
@@ -422,7 +422,7 @@
     const net::NetworkIsolationKey& network_isolation_key,
     mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
         header_client,
-    network::mojom::URLLoaderFactoryRequest receiver) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   if (GetNetworkFactoryCallback().is_null()) {
     url_loader_factory_->Clone(std::move(receiver));
     return;
diff --git a/content/public/test/mock_render_process_host.h b/content/public/test/mock_render_process_host.h
index ec7cfe0..441744d6 100644
--- a/content/public/test/mock_render_process_host.h
+++ b/content/public/test/mock_render_process_host.h
@@ -71,7 +71,7 @@
                                  int exit_code);
 
   using CreateNetworkFactoryCallback = base::RepeatingCallback<void(
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       int process_id,
       network::mojom::URLLoaderFactoryPtrInfo original_factory)>;
   static void SetNetworkFactory(
@@ -159,7 +159,8 @@
       const net::NetworkIsolationKey& network_isolation_key,
       mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
           header_client,
-      network::mojom::URLLoaderFactoryRequest request) override;
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
 
   void SetIsNeverSuitableForReuse() override;
   bool MayReuseHost() override;
diff --git a/content/public/test/url_loader_interceptor.cc b/content/public/test/url_loader_interceptor.cc
index a548ec10..20b958a 100644
--- a/content/public/test/url_loader_interceptor.cc
+++ b/content/public/test/url_loader_interceptor.cc
@@ -26,7 +26,7 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/test/mock_render_process_host.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "net/http/http_util.h"
 #include "net/test/embedded_test_server/request_handler_util.h"
 #include "services/network/public/cpp/features.h"
@@ -90,7 +90,7 @@
       scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter);
 
   void CreateURLLoaderFactoryForSubresources(
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       int process_id,
       network::mojom::URLLoaderFactoryPtrInfo original_factory);
 
@@ -135,16 +135,16 @@
   // URLLoaderFactory with a network::mojom::TrustedURLLoaderHeaderClient or
   // for a non-network-service scheme.
   void InterceptNavigationRequestCallback(
-      network::mojom::URLLoaderFactoryRequest* request) {
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory>* receiver) {
     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 
-    auto proxied_request = std::move(*request);
+    auto proxied_receiver = std::move(*receiver);
     network::mojom::URLLoaderFactoryPtr target_factory;
-    *request = mojo::MakeRequest(&target_factory);
+    *receiver = mojo::MakeRequest(&target_factory);
 
     navigation_wrappers_.emplace(
         std::make_unique<URLLoaderFactoryNavigationWrapper>(
-            std::move(proxied_request), std::move(target_factory), this));
+            std::move(proxied_receiver), std::move(target_factory), this));
   }
 
   URLLoaderCompletionStatusCallback GetCompletionStatusCallback() {
@@ -253,14 +253,15 @@
       : parent_(parent),
         process_id_getter_(process_id_getter),
         original_factory_getter_(original_factory_getter) {
-    bindings_.set_connection_error_handler(base::BindRepeating(
+    receivers_.set_disconnect_handler(base::BindRepeating(
         &Interceptor::OnConnectionError, base::Unretained(this)));
   }
 
   ~Interceptor() override {}
 
-  void BindRequest(network::mojom::URLLoaderFactoryRequest request) {
-    bindings_.AddBinding(this, std::move(request));
+  void BindReceiver(
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
+    receivers_.Add(this, std::move(receiver));
   }
 
   void SetConnectionErrorHandler(base::OnceClosure handler) {
@@ -296,19 +297,20 @@
             parent_->GetCompletionStatusCallback()));
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
-    BindRequest(std::move(request));
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
+    BindReceiver(std::move(receiver));
   }
 
   void OnConnectionError() {
-    if (bindings_.empty() && error_handler_)
+    if (receivers_.empty() && error_handler_)
       std::move(error_handler_).Run();
   }
 
   URLLoaderInterceptor::IOState* parent_;
   ProcessIdGetter process_id_getter_;
   OriginalFactoryGetter original_factory_getter_;
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
   base::OnceClosure error_handler_;
   std::vector<std::unique_ptr<URLLoaderClientInterceptor>>
       url_loader_client_interceptors_;
@@ -349,7 +351,7 @@
 class URLLoaderInterceptor::URLLoaderFactoryNavigationWrapper {
  public:
   URLLoaderFactoryNavigationWrapper(
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       network::mojom::URLLoaderFactoryPtr target_factory,
       URLLoaderInterceptor::IOState* parent)
       : target_factory_(std::move(target_factory)) {
@@ -358,7 +360,7 @@
         base::BindLambdaForTesting([=]() -> network::mojom::URLLoaderFactory* {
           return this->target_factory_.get();
         }));
-    interceptor_->BindRequest(std::move(request));
+    interceptor_->BindReceiver(std::move(receiver));
   }
 
  private:
@@ -370,16 +372,17 @@
 // StoragePartition::GetURLLoaderFactoryForBrowserProcess.
 class URLLoaderInterceptor::BrowserProcessWrapper {
  public:
-  BrowserProcessWrapper(network::mojom::URLLoaderFactoryRequest factory_request,
-                        URLLoaderInterceptor::IOState* parent,
-                        network::mojom::URLLoaderFactoryPtr original_factory)
+  BrowserProcessWrapper(
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory_receiver,
+      URLLoaderInterceptor::IOState* parent,
+      network::mojom::URLLoaderFactoryPtr original_factory)
       : interceptor_(
             parent,
             base::BindRepeating([]() { return 0; }),
             base::BindRepeating(&BrowserProcessWrapper::GetOriginalFactory,
                                 base::Unretained(this))),
         original_factory_(std::move(original_factory)) {
-    interceptor_.BindRequest(std::move(factory_request));
+    interceptor_.BindReceiver(std::move(factory_receiver));
   }
 
   ~BrowserProcessWrapper() {}
@@ -399,10 +402,11 @@
 // loader so that it can intercept subresource requests.
 class URLLoaderInterceptor::SubresourceWrapper {
  public:
-  SubresourceWrapper(network::mojom::URLLoaderFactoryRequest factory_request,
-                     int process_id,
-                     URLLoaderInterceptor::IOState* parent,
-                     network::mojom::URLLoaderFactoryPtrInfo original_factory)
+  SubresourceWrapper(
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory_receiver,
+      int process_id,
+      URLLoaderInterceptor::IOState* parent,
+      network::mojom::URLLoaderFactoryPtrInfo original_factory)
       : interceptor_(
             parent,
             base::BindRepeating([](int process_id) { return process_id; },
@@ -410,7 +414,7 @@
             base::BindRepeating(&SubresourceWrapper::GetOriginalFactory,
                                 base::Unretained(this))),
         original_factory_(std::move(original_factory)) {
-    interceptor_.BindRequest(std::move(factory_request));
+    interceptor_.BindReceiver(std::move(factory_receiver));
     interceptor_.SetConnectionErrorHandler(base::BindOnce(
         &URLLoaderInterceptor::IOState::SubresourceWrapperBindingError,
         base::Unretained(parent), this));
@@ -605,7 +609,7 @@
 }
 
 void URLLoaderInterceptor::CreateURLLoaderFactoryForSubresources(
-    network::mojom::URLLoaderFactoryRequest request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
     int process_id,
     network::mojom::URLLoaderFactoryPtrInfo original_factory) {
   if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
@@ -613,12 +617,12 @@
         FROM_HERE, {BrowserThread::IO},
         base::BindOnce(
             &URLLoaderInterceptor::CreateURLLoaderFactoryForSubresources,
-            base::Unretained(this), std::move(request), process_id,
+            base::Unretained(this), std::move(receiver), process_id,
             std::move(original_factory)));
     return;
   }
   io_thread_->CreateURLLoaderFactoryForSubresources(
-      std::move(request), process_id, std::move(original_factory));
+      std::move(receiver), process_id, std::move(original_factory));
 }
 
 network::mojom::URLLoaderFactoryPtr
@@ -633,16 +637,16 @@
 }
 
 void URLLoaderInterceptor::InterceptNavigationRequestCallback(
-    network::mojom::URLLoaderFactoryRequest* request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory>* receiver) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  auto proxied_request = std::move(*request);
+  auto proxied_receiver = std::move(*receiver);
   network::mojom::URLLoaderFactoryPtr target_factory;
-  *request = mojo::MakeRequest(&target_factory);
+  *receiver = mojo::MakeRequest(&target_factory);
 
   navigation_wrappers_.emplace(
       std::make_unique<URLLoaderFactoryNavigationWrapper>(
-          std::move(proxied_request), std::move(target_factory),
+          std::move(proxied_receiver), std::move(target_factory),
           io_thread_.get()));
 }
 
@@ -697,12 +701,12 @@
 }
 
 void URLLoaderInterceptor::IOState::CreateURLLoaderFactoryForSubresources(
-    network::mojom::URLLoaderFactoryRequest request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
     int process_id,
     network::mojom::URLLoaderFactoryPtrInfo original_factory) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
   subresource_wrappers_.emplace(std::make_unique<SubresourceWrapper>(
-      std::move(request), process_id, this, std::move(original_factory)));
+      std::move(receiver), process_id, this, std::move(original_factory)));
 }
 
 // static
diff --git a/content/public/test/url_loader_interceptor.h b/content/public/test/url_loader_interceptor.h
index 4c73a58..ce534d2f 100644
--- a/content/public/test/url_loader_interceptor.h
+++ b/content/public/test/url_loader_interceptor.h
@@ -12,7 +12,7 @@
 #include "base/files/file_path.h"
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "net/base/net_errors.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
@@ -148,7 +148,7 @@
 
   // Used to create a factory for subresources in the network service case.
   void CreateURLLoaderFactoryForSubresources(
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       int process_id,
       network::mojom::URLLoaderFactoryPtrInfo original_factory);
 
@@ -174,7 +174,7 @@
   // URLLoaderFactory with a network::mojom::TrustedURLLoaderHeaderClient or
   // for a non-network-service scheme.
   void InterceptNavigationRequestCallback(
-      network::mojom::URLLoaderFactoryRequest* request);
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory>* receiver);
 
   // Attempts to intercept the given request, returning true if it was
   // intercepted.
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index 50b27ec0..25d2f66 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -200,12 +200,8 @@
     "media/renderer_webmediaplayer_delegate.h",
     "media/webrtc/media_stream_track_metrics.cc",
     "media/webrtc/media_stream_track_metrics.h",
-    "media/webrtc/media_stream_video_webrtc_sink.cc",
-    "media/webrtc/media_stream_video_webrtc_sink.h",
     "media/webrtc/peer_connection_tracker.cc",
     "media/webrtc/peer_connection_tracker.h",
-    "media/webrtc/rtc_certificate_generator.cc",
-    "media/webrtc/rtc_certificate_generator.h",
     "media/webrtc/rtc_peer_connection_handler.cc",
     "media/webrtc/rtc_peer_connection_handler.h",
     "media/webrtc/rtc_rtp_receiver.cc",
@@ -216,10 +212,6 @@
     "media/webrtc/rtc_rtp_transceiver.h",
     "media/webrtc/transceiver_state_surfacer.cc",
     "media/webrtc/transceiver_state_surfacer.h",
-    "media/webrtc/webrtc_media_stream_track_adapter.cc",
-    "media/webrtc/webrtc_media_stream_track_adapter.h",
-    "media/webrtc/webrtc_media_stream_track_adapter_map.cc",
-    "media/webrtc/webrtc_media_stream_track_adapter_map.h",
     "media/webrtc/webrtc_set_description_observer.cc",
     "media/webrtc/webrtc_set_description_observer.h",
     "menu_item_builder.cc",
diff --git a/content/renderer/internal_document_state_data.cc b/content/renderer/internal_document_state_data.cc
index 53e95359..2497e2b2 100644
--- a/content/renderer/internal_document_state_data.cc
+++ b/content/renderer/internal_document_state_data.cc
@@ -20,9 +20,7 @@
 
 InternalDocumentStateData::InternalDocumentStateData()
     : is_overriding_user_agent_(false),
-      must_reset_scroll_and_scale_state_(false),
-      cache_policy_override_set_(false),
-      cache_policy_override_(blink::mojom::FetchCacheMode::kDefault) {}
+      must_reset_scroll_and_scale_state_(false) {}
 
 // static
 InternalDocumentStateData* InternalDocumentStateData::FromDocumentLoader(
@@ -52,8 +50,6 @@
   is_overriding_user_agent_ = other->is_overriding_user_agent_;
   must_reset_scroll_and_scale_state_ =
       other->must_reset_scroll_and_scale_state_;
-  cache_policy_override_set_ = other->cache_policy_override_set_;
-  cache_policy_override_ = other->cache_policy_override_;
   effective_connection_type_ = other->effective_connection_type_;
   request_id_ = other->request_id_;
 }
diff --git a/content/renderer/internal_document_state_data.h b/content/renderer/internal_document_state_data.h
index 731fe2f..7aa1cfc7 100644
--- a/content/renderer/internal_document_state_data.h
+++ b/content/renderer/internal_document_state_data.h
@@ -50,24 +50,6 @@
     must_reset_scroll_and_scale_state_ = state;
   }
 
-  // Sets the cache policy. The cache policy is only used if explicitly set and
-  // by default is not set. You can mark a NavigationState as not having a cache
-  // state by way of clear_cache_policy_override.
-  void set_cache_policy_override(blink::mojom::FetchCacheMode cache_policy) {
-    cache_policy_override_ = cache_policy;
-    cache_policy_override_set_ = true;
-  }
-  blink::mojom::FetchCacheMode cache_policy_override() const {
-    return cache_policy_override_;
-  }
-  void clear_cache_policy_override() {
-    cache_policy_override_set_ = false;
-    cache_policy_override_ = blink::mojom::FetchCacheMode::kDefault;
-  }
-  bool is_cache_policy_override_set() const {
-    return cache_policy_override_set_;
-  }
-
   net::EffectiveConnectionType effective_connection_type() const {
     return effective_connection_type_;
   }
@@ -89,8 +71,6 @@
  private:
   bool is_overriding_user_agent_;
   bool must_reset_scroll_and_scale_state_;
-  bool cache_policy_override_set_;
-  blink::mojom::FetchCacheMode cache_policy_override_;
   net::EffectiveConnectionType effective_connection_type_ =
       net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN;
   int request_id_ = -1;
diff --git a/content/renderer/loader/resource_dispatcher_unittest.cc b/content/renderer/loader/resource_dispatcher_unittest.cc
index 9e9a600..2e973dc 100644
--- a/content/renderer/loader/resource_dispatcher_unittest.cc
+++ b/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -26,6 +26,7 @@
 #include "content/renderer/loader/navigation_response_override_parameters.h"
 #include "content/renderer/loader/request_extra_data.h"
 #include "content/renderer/loader/test_request_peer.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "net/base/net_errors.h"
 #include "net/base/request_priority.h"
 #include "net/http/http_response_headers.h"
@@ -95,7 +96,8 @@
     loader_and_clients_.emplace_back(std::move(request), std::move(client));
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
     NOTREACHED();
   }
 
diff --git a/content/renderer/loader/sync_load_context_unittest.cc b/content/renderer/loader/sync_load_context_unittest.cc
index 023fda7..ced6b20 100644
--- a/content/renderer/loader/sync_load_context_unittest.cc
+++ b/content/renderer/loader/sync_load_context_unittest.cc
@@ -6,6 +6,7 @@
 #include "base/bind.h"
 #include "base/threading/thread.h"
 #include "content/renderer/loader/sync_load_response.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/system/data_pipe_utils.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
@@ -33,7 +34,9 @@
         std::move(client), traffic_annotation);
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest) override { NOTREACHED(); }
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory>) override {
+    NOTREACHED();
+  }
 
   std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override {
     NOTREACHED();
diff --git a/content/renderer/loader/url_loader_client_impl_unittest.cc b/content/renderer/loader/url_loader_client_impl_unittest.cc
index 1318502..78a33600 100644
--- a/content/renderer/loader/url_loader_client_impl_unittest.cc
+++ b/content/renderer/loader/url_loader_client_impl_unittest.cc
@@ -10,8 +10,8 @@
 #include "content/renderer/loader/navigation_response_override_parameters.h"
 #include "content/renderer/loader/resource_dispatcher.h"
 #include "content/renderer/loader/test_request_peer.h"
-#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/interface_ptr.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "net/url_request/redirect_info.h"
 #include "services/network/public/cpp/resource_response.h"
@@ -86,7 +86,8 @@
     url_loader_client_ = std::move(client);
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
     NOTREACHED();
   }
 
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc
index 8ce83f37a..8c6b4675 100644
--- a/content/renderer/loader/web_url_loader_impl.cc
+++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -1070,8 +1070,11 @@
       head.did_service_worker_navigation_preload);
   response->SetEncodedDataLength(head.encoded_data_length);
   response->SetEncodedBodyLength(head.encoded_body_length);
+  response->SetWasAlpnNegotiated(head.was_alpn_negotiated);
   response->SetAlpnNegotiatedProtocol(
       WebString::FromUTF8(head.alpn_negotiated_protocol));
+  response->SetWasAlternateProtocolAvailable(
+      head.was_alternate_protocol_available);
   response->SetConnectionInfo(head.connection_info);
   response->SetAsyncRevalidationRequested(head.async_revalidation_requested);
   response->SetNetworkAccessed(head.network_accessed);
diff --git a/content/renderer/loader/web_url_loader_impl_unittest.cc b/content/renderer/loader/web_url_loader_impl_unittest.cc
index d0e11dc..b8131d5b 100644
--- a/content/renderer/loader/web_url_loader_impl_unittest.cc
+++ b/content/renderer/loader/web_url_loader_impl_unittest.cc
@@ -24,6 +24,7 @@
 #include "content/renderer/loader/request_extra_data.h"
 #include "content/renderer/loader/resource_dispatcher.h"
 #include "content/renderer/loader/sync_load_response.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/ip_endpoint.h"
@@ -154,7 +155,8 @@
     NOTREACHED();
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
     NOTREACHED();
   }
 
diff --git a/content/renderer/loader/web_worker_fetch_context_impl.cc b/content/renderer/loader/web_worker_fetch_context_impl.cc
index 4d1d40a..cd6f553 100644
--- a/content/renderer/loader/web_worker_fetch_context_impl.cc
+++ b/content/renderer/loader/web_worker_fetch_context_impl.cc
@@ -47,14 +47,14 @@
         remote_container_host,
     const std::string& client_id,
     std::unique_ptr<network::SharedURLLoaderFactoryInfo> fallback_factory,
-    network::mojom::URLLoaderFactoryRequest request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
     scoped_refptr<base::SequencedTaskRunner> task_runner) {
   ServiceWorkerSubresourceLoaderFactory::Create(
       base::MakeRefCounted<ControllerServiceWorkerConnector>(
           std::move(remote_container_host),
           mojo::NullRemote() /* remote_controller */, client_id),
       network::SharedURLLoaderFactory::Create(std::move(fallback_factory)),
-      std::move(request), std::move(task_runner));
+      std::move(receiver), std::move(task_runner));
 }
 
 }  // namespace
diff --git a/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc b/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc
index 56be875c..65d4f155 100644
--- a/content/renderer/media/webrtc/media_stream_video_webrtc_sink_unittest.cc
+++ b/content/renderer/media/webrtc/media_stream_video_webrtc_sink_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 "content/renderer/media/webrtc/media_stream_video_webrtc_sink.h"
+#include "third_party/blink/public/web/modules/peerconnection/media_stream_video_webrtc_sink.h"
 
 #include "base/test/task_environment.h"
 #include "content/child/child_process.h"
@@ -57,7 +57,7 @@
 
 TEST_F(MediaStreamVideoWebRtcSinkTest, NoiseReductionDefaultsToNotSet) {
   SetVideoTrack();
-  MediaStreamVideoWebRtcSink my_sink(
+  blink::MediaStreamVideoWebRtcSink my_sink(
       track_, &dependency_factory_,
       blink::scheduler::GetSingleThreadTaskRunnerForTesting());
   EXPECT_TRUE(my_sink.webrtc_video_track());
diff --git a/content/renderer/media/webrtc/rtc_certificate_generator.h b/content/renderer/media/webrtc/rtc_certificate_generator.h
deleted file mode 100644
index 76ce08f8..0000000
--- a/content/renderer/media/webrtc/rtc_certificate_generator.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_RTC_CERTIFICATE_GENERATOR_H_
-#define CONTENT_RENDERER_MEDIA_WEBRTC_RTC_CERTIFICATE_GENERATOR_H_
-
-#include "base/macros.h"
-#include "base/single_thread_task_runner.h"
-#include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
-#include "third_party/blink/public/platform/web_rtc_key_params.h"
-#include "third_party/webrtc/api/peer_connection_interface.h"
-
-namespace content {
-
-// Chromium's WebRTCCertificateGenerator implementation; uses the
-// PeerConnectionIdentityStore/SSLIdentity::Generate to generate the identity,
-// rtc::RTCCertificate and content::RTCCertificate.
-class RTCCertificateGenerator : public blink::WebRTCCertificateGenerator {
- public:
-  RTCCertificateGenerator() {}
-  ~RTCCertificateGenerator() override {}
-
-  // blink::WebRTCCertificateGenerator implementation.
-  void GenerateCertificate(
-      const blink::WebRTCKeyParams& key_params,
-      blink::WebRTCCertificateCallback completion_callback,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
-  void GenerateCertificateWithExpiration(
-      const blink::WebRTCKeyParams& key_params,
-      uint64_t expires_ms,
-      blink::WebRTCCertificateCallback completion_callback,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
-  bool IsSupportedKeyParams(const blink::WebRTCKeyParams& key_params) override;
-  rtc::scoped_refptr<rtc::RTCCertificate> FromPEM(
-      blink::WebString pem_private_key,
-      blink::WebString pem_certificate) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(RTCCertificateGenerator);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_RENDERER_MEDIA_WEBRTC_RTC_CERTIFICATE_GENERATOR_H_
diff --git a/content/renderer/media/webrtc/rtc_peer_connection_handler.cc b/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
index 28489fe52..7885f94 100644
--- a/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
+++ b/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
@@ -980,8 +980,8 @@
       is_closed_(false),
       dependency_factory_(dependency_factory),
       track_adapter_map_(
-          new WebRtcMediaStreamTrackAdapterMap(dependency_factory_,
-                                               task_runner)),
+          new blink::WebRtcMediaStreamTrackAdapterMap(dependency_factory_,
+                                                      task_runner)),
       task_runner_(std::move(task_runner)) {
   CHECK(client_);
 
@@ -1602,8 +1602,8 @@
     const webrtc::RtpTransceiverInit& init) {
   DCHECK_EQ(configuration_.sdp_semantics, webrtc::SdpSemantics::kUnifiedPlan);
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref =
-      track_adapter_map_->GetOrCreateLocalTrackAdapter(web_track);
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      track_ref = track_adapter_map_->GetOrCreateLocalTrackAdapter(web_track);
   TransceiverStateSurfacer transceiver_state_surfacer(task_runner_,
                                                       signaling_thread());
   webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
@@ -1705,8 +1705,8 @@
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
   TRACE_EVENT0("webrtc", "RTCPeerConnectionHandler::AddTrack");
 
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref =
-      track_adapter_map_->GetOrCreateLocalTrackAdapter(track);
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      track_ref = track_adapter_map_->GetOrCreateLocalTrackAdapter(track);
   std::vector<std::string> stream_ids(streams.size());
   for (size_t i = 0; i < streams.size(); ++i)
     stream_ids[i] = streams[i].Id().Utf8();
diff --git a/content/renderer/media/webrtc/rtc_peer_connection_handler.h b/content/renderer/media/webrtc/rtc_peer_connection_handler.h
index 64a7156..08f0100 100644
--- a/content/renderer/media/webrtc/rtc_peer_connection_handler.h
+++ b/content/renderer/media/webrtc/rtc_peer_connection_handler.h
@@ -23,13 +23,13 @@
 #include "content/renderer/media/webrtc/rtc_rtp_receiver.h"
 #include "content/renderer/media/webrtc/rtc_rtp_sender.h"
 #include "content/renderer/media/webrtc/transceiver_state_surfacer.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/blink/public/platform/web_media_stream_source.h"
 #include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
 #include "third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h"
 #include "third_party/blink/public/platform/web_rtc_stats.h"
 #include "third_party/blink/public/platform/web_rtc_stats_request.h"
 #include "third_party/blink/public/platform/web_rtc_stats_response.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/webrtc/api/stats/rtc_stats.h"
 #include "third_party/webrtc/api/stats/rtc_stats_collector_callback.h"
 
@@ -363,7 +363,7 @@
   // Track adapters are created on the fly when a component (such as a stream)
   // needs to reference it, and automatically disposed when there are no longer
   // any components referencing it.
-  scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
   // In Plan B, senders and receivers are added or removed independently of one
   // another. In Unified Plan, senders and receivers are created in pairs as
   // transceivers. Transceivers may become inactive, but are never removed.
diff --git a/content/renderer/media/webrtc/rtc_rtp_receiver.cc b/content/renderer/media/webrtc/rtc_rtp_receiver.cc
index a5438de..c5399ee 100644
--- a/content/renderer/media/webrtc/rtc_rtp_receiver.cc
+++ b/content/renderer/media/webrtc/rtc_rtp_receiver.cc
@@ -17,7 +17,8 @@
     scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
     scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
-    std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+    std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+        track_ref,
     std::vector<std::string> stream_id)
     : main_task_runner_(std::move(main_task_runner)),
       signaling_task_runner_(std::move(signaling_task_runner)),
@@ -114,7 +115,7 @@
   return webrtc_dtls_transport_information_;
 }
 
-const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+const std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
 RtpReceiverState::track_ref() const {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   return track_ref_;
diff --git a/content/renderer/media/webrtc/rtc_rtp_receiver.h b/content/renderer/media/webrtc/rtc_rtp_receiver.h
index 54e2ead..25cb2089 100644
--- a/content/renderer/media/webrtc/rtc_rtp_receiver.h
+++ b/content/renderer/media/webrtc/rtc_rtp_receiver.h
@@ -11,12 +11,12 @@
 #include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
 #include "content/common/content_export.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/blink/public/platform/web_media_stream.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
 #include "third_party/blink/public/platform/web_rtc_rtp_receiver.h"
 #include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
 #include "third_party/blink/public/platform/web_rtc_stats.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/webrtc/api/media_stream_interface.h"
 #include "third_party/webrtc/api/peer_connection_interface.h"
 #include "third_party/webrtc/api/rtp_receiver_interface.h"
@@ -64,7 +64,8 @@
       scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
       scoped_refptr<webrtc::RtpReceiverInterface> webrtc_receiver,
-      std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+      std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+          track_ref,
       std::vector<std::string> stream_ids);
   RtpReceiverState(RtpReceiverState&&);
   RtpReceiverState(const RtpReceiverState&) = delete;
@@ -86,7 +87,7 @@
       const;
   webrtc::DtlsTransportInformation webrtc_dtls_transport_information() const;
 
-  const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+  const std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
   track_ref() const;
   const std::vector<std::string>& stream_ids() const;
 
@@ -97,7 +98,8 @@
   rtc::scoped_refptr<webrtc::DtlsTransportInterface> webrtc_dtls_transport_;
   webrtc::DtlsTransportInformation webrtc_dtls_transport_information_;
   bool is_initialized_;
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref_;
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      track_ref_;
   std::vector<std::string> stream_ids_;
 };
 
diff --git a/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc b/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc
index 4feab2f..a789dd2a 100644
--- a/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc
+++ b/content/renderer/media/webrtc/rtc_rtp_receiver_unittest.cc
@@ -17,11 +17,11 @@
 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
 #include "content/renderer/media/webrtc/mock_peer_connection_impl.h"
 #include "content/renderer/media/webrtc/test/webrtc_stats_report_obtainer.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
 #include "third_party/blink/public/platform/web_rtc_stats.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/blink/public/web/web_heap.h"
 #include "third_party/webrtc/api/stats/rtc_stats_report.h"
 #include "third_party/webrtc/api/stats/rtcstats_objects.h"
@@ -34,8 +34,8 @@
   void SetUp() override {
     dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
     main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
-    track_map_ = new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
-                                                      main_thread_);
+    track_map_ = new blink::WebRtcMediaStreamTrackAdapterMap(
+        dependency_factory_.get(), main_thread_);
     peer_connection_ = new rtc::RefCountedObject<MockPeerConnectionImpl>(
         dependency_factory_.get(), nullptr);
   }
@@ -61,7 +61,8 @@
 
   std::unique_ptr<RTCRtpReceiver> CreateReceiver(
       scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track) {
-    std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
+    std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+        track_ref;
     base::RunLoop run_loop;
     dependency_factory_->GetWebRtcSignalingThread()->PostTask(
         FROM_HERE,
@@ -90,7 +91,8 @@
  protected:
   void CreateReceiverOnSignalingThread(
       scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,
-      std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>* track_ref,
+      std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>*
+          track_ref,
       base::RunLoop* run_loop) {
     mock_webrtc_receiver_ =
         new rtc::RefCountedObject<webrtc::MockRtpReceiver>();
@@ -106,7 +108,7 @@
 
   std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
-  scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map_;
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map_;
   rtc::scoped_refptr<MockPeerConnectionImpl> peer_connection_;
   rtc::scoped_refptr<webrtc::MockRtpReceiver> mock_webrtc_receiver_;
   std::unique_ptr<RTCRtpReceiver> receiver_;
diff --git a/content/renderer/media/webrtc/rtc_rtp_sender.cc b/content/renderer/media/webrtc/rtc_rtp_sender.cc
index e54ce41..75f8bab 100644
--- a/content/renderer/media/webrtc/rtc_rtp_sender.cc
+++ b/content/renderer/media/webrtc/rtc_rtp_sender.cc
@@ -41,7 +41,8 @@
     scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
     scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
-    std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+    std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+        track_ref,
     std::vector<std::string> stream_ids)
     : main_task_runner_(std::move(main_task_runner)),
       signaling_task_runner_(std::move(signaling_task_runner)),
@@ -135,14 +136,15 @@
   return webrtc_dtls_transport_information_;
 }
 
-const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+const std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
 RtpSenderState::track_ref() const {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   return track_ref_;
 }
 
 void RtpSenderState::set_track_ref(
-    std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref) {
+    std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+        track_ref) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
   DCHECK(!is_initialized_ || !track_ref || track_ref->is_initialized());
   track_ref_ = std::move(track_ref);
@@ -160,7 +162,7 @@
  public:
   RTCRtpSenderInternal(
       scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
-      scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map,
       RtpSenderState state)
       : native_peer_connection_(std::move(native_peer_connection)),
         track_map_(std::move(track_map)),
@@ -189,7 +191,8 @@
   void ReplaceTrack(blink::WebMediaStreamTrack with_track,
                     base::OnceCallback<void(bool)> callback) {
     DCHECK(main_task_runner_->BelongsToCurrentThread());
-    std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
+    std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+        track_ref;
     webrtc::MediaStreamTrackInterface* webrtc_track = nullptr;
     if (!with_track.IsNull()) {
       track_ref = track_map_->GetOrCreateLocalTrackAdapter(with_track);
@@ -296,7 +299,8 @@
   // |webrtc_track| is passed as an argument because |track_ref->webrtc_track()|
   // cannot be accessed on the signaling thread. https://crbug.com/756436
   void ReplaceTrackOnSignalingThread(
-      std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+      std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+          track_ref,
       webrtc::MediaStreamTrackInterface* webrtc_track,
       base::OnceCallback<void(bool)> callback) {
     DCHECK(signaling_task_runner_->BelongsToCurrentThread());
@@ -310,7 +314,8 @@
 
   void ReplaceTrackCallback(
       bool result,
-      std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+      std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+          track_ref,
       base::OnceCallback<void(bool)> callback) {
     DCHECK(main_task_runner_->BelongsToCurrentThread());
     if (result)
@@ -352,7 +357,7 @@
   }
 
   const scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection_;
-  const scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map_;
+  const scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map_;
   // Task runners and webrtc sender: Same information as stored in
   // |state_| but const and safe to touch on the signaling thread to
   // avoid race with set_state().
@@ -388,7 +393,7 @@
 
 RTCRtpSender::RTCRtpSender(
     scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
-    scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+    scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map,
     RtpSenderState state)
     : internal_(new RTCRtpSenderInternal(std::move(native_peer_connection),
                                          std::move(track_map),
diff --git a/content/renderer/media/webrtc/rtc_rtp_sender.h b/content/renderer/media/webrtc/rtc_rtp_sender.h
index 041b1ad0..e47e339 100644
--- a/content/renderer/media/webrtc/rtc_rtp_sender.h
+++ b/content/renderer/media/webrtc/rtc_rtp_sender.h
@@ -12,11 +12,11 @@
 #include "base/callback.h"
 #include "base/single_thread_task_runner.h"
 #include "content/common/content_export.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
 #include "third_party/blink/public/platform/web_rtc_rtp_sender.h"
 #include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
 #include "third_party/blink/public/platform/web_rtc_stats.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/webrtc/api/peer_connection_interface.h"
 #include "third_party/webrtc/api/rtp_sender_interface.h"
 #include "third_party/webrtc/api/scoped_refptr.h"
@@ -63,7 +63,8 @@
       scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
       scoped_refptr<webrtc::RtpSenderInterface> webrtc_sender,
-      std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref,
+      std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+          track_ref,
       std::vector<std::string> stream_ids);
   RtpSenderState(RtpSenderState&&);
   RtpSenderState(const RtpSenderState&) = delete;
@@ -84,10 +85,11 @@
   rtc::scoped_refptr<webrtc::DtlsTransportInterface> webrtc_dtls_transport()
       const;
   webrtc::DtlsTransportInformation webrtc_dtls_transport_information() const;
-  const std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
+  const std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>&
   track_ref() const;
   void set_track_ref(
-      std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref);
+      std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+          track_ref);
   std::vector<std::string> stream_ids() const;
 
  private:
@@ -97,7 +99,8 @@
   rtc::scoped_refptr<webrtc::DtlsTransportInterface> webrtc_dtls_transport_;
   webrtc::DtlsTransportInformation webrtc_dtls_transport_information_;
   bool is_initialized_;
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref_;
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      track_ref_;
   std::vector<std::string> stream_ids_;
 };
 
@@ -116,7 +119,7 @@
 
   RTCRtpSender(
       scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
-      scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map,
       RtpSenderState state);
   RTCRtpSender(const RTCRtpSender& other);
   ~RTCRtpSender() override;
diff --git a/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc b/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc
index 33702bf..8d646544 100644
--- a/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc
+++ b/content/renderer/media/webrtc/rtc_rtp_sender_unittest.cc
@@ -16,7 +16,6 @@
 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
 #include "content/renderer/media/webrtc/mock_peer_connection_impl.h"
 #include "content/renderer/media/webrtc/test/webrtc_stats_report_obtainer.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
@@ -25,6 +24,7 @@
 #include "third_party/blink/public/platform/web_rtc_stats.h"
 #include "third_party/blink/public/platform/web_rtc_void_request.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/blink/public/web/web_heap.h"
 #include "third_party/webrtc/api/stats/rtc_stats_report.h"
 #include "third_party/webrtc/api/stats/rtcstats_objects.h"
@@ -40,8 +40,8 @@
   void SetUp() override {
     dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
     main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
-    track_map_ = new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
-                                                      main_thread_);
+    track_map_ = new blink::WebRtcMediaStreamTrackAdapterMap(
+        dependency_factory_.get(), main_thread_);
     peer_connection_ = new rtc::RefCountedObject<MockPeerConnectionImpl>(
         dependency_factory_.get(), nullptr);
     mock_webrtc_sender_ = new rtc::RefCountedObject<webrtc::MockRtpSender>();
@@ -84,7 +84,8 @@
 
   std::unique_ptr<RTCRtpSender> CreateSender(
       blink::WebMediaStreamTrack web_track) {
-    std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
+    std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+        track_ref;
     if (!web_track.IsNull()) {
       track_ref = track_map_->GetOrCreateLocalTrackAdapter(web_track);
       DCHECK(track_ref->is_initialized());
@@ -147,7 +148,7 @@
 
   std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
-  scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map_;
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map_;
   rtc::scoped_refptr<MockPeerConnectionImpl> peer_connection_;
   rtc::scoped_refptr<webrtc::MockRtpSender> mock_webrtc_sender_;
   std::unique_ptr<RTCRtpSender> sender_;
diff --git a/content/renderer/media/webrtc/rtc_rtp_transceiver.cc b/content/renderer/media/webrtc/rtc_rtp_transceiver.cc
index ab36db4..f461c77 100644
--- a/content/renderer/media/webrtc/rtc_rtp_transceiver.cc
+++ b/content/renderer/media/webrtc/rtc_rtp_transceiver.cc
@@ -180,7 +180,7 @@
  public:
   RTCRtpTransceiverInternal(
       scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
-      scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map,
       RtpTransceiverState state)
       : main_task_runner_(state.main_task_runner()),
         signaling_task_runner_(state.signaling_task_runner()),
@@ -291,7 +291,7 @@
 
 RTCRtpTransceiver::RTCRtpTransceiver(
     scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
-    scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+    scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map,
     RtpTransceiverState transceiver_state)
     : internal_(new RTCRtpTransceiverInternal(std::move(native_peer_connection),
                                               std::move(track_map),
diff --git a/content/renderer/media/webrtc/rtc_rtp_transceiver.h b/content/renderer/media/webrtc/rtc_rtp_transceiver.h
index e99719e..aa42efc 100644
--- a/content/renderer/media/webrtc/rtc_rtp_transceiver.h
+++ b/content/renderer/media/webrtc/rtc_rtp_transceiver.h
@@ -10,8 +10,8 @@
 #include "base/single_thread_task_runner.h"
 #include "content/renderer/media/webrtc/rtc_rtp_receiver.h"
 #include "content/renderer/media/webrtc/rtc_rtp_sender.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/blink/public/platform/web_rtc_rtp_transceiver.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/webrtc/api/rtp_transceiver_interface.h"
 
 namespace content {
@@ -151,7 +151,7 @@
 
   RTCRtpTransceiver(
       scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
-      scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map,
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map,
       RtpTransceiverState state);
   RTCRtpTransceiver(const RTCRtpTransceiver& other);
   ~RTCRtpTransceiver() override;
diff --git a/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc b/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc
index b121d36..21ce760 100644
--- a/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc
+++ b/content/renderer/media/webrtc/rtc_rtp_transceiver_unittest.cc
@@ -18,13 +18,13 @@
 #include "content/child/child_process.h"
 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
 #include "content/renderer/media/webrtc/mock_peer_connection_impl.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
 #include "third_party/blink/public/platform/modules/peerconnection/webrtc_util.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
 #include "third_party/blink/public/platform/web_media_stream_source.h"
 #include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/blink/public/web/web_heap.h"
 #include "third_party/webrtc/api/test/mock_rtpreceiver.h"
 #include "third_party/webrtc/api/test/mock_rtpsender.h"
@@ -36,8 +36,8 @@
   void SetUp() override {
     dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
     main_task_runner_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
-    track_map_ = new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
-                                                      main_task_runner_);
+    track_map_ = new blink::WebRtcMediaStreamTrackAdapterMap(
+        dependency_factory_.get(), main_task_runner_);
     peer_connection_ = new rtc::RefCountedObject<MockPeerConnectionImpl>(
         dependency_factory_.get(), nullptr);
   }
@@ -64,16 +64,17 @@
     return dependency_factory_->GetWebRtcSignalingThread();
   }
 
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
   CreateLocalTrackAndAdapter(const std::string& id) {
     return track_map_->GetOrCreateLocalTrackAdapter(CreateBlinkLocalTrack(id));
   }
 
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
   CreateRemoteTrackAndAdapter(const std::string& id) {
     rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track =
         MockWebRtcAudioTrack::Create(id).get();
-    std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> track_ref;
+    std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+        track_ref;
     base::RunLoop run_loop;
     signaling_task_runner()->PostTask(
         FROM_HERE,
@@ -124,9 +125,9 @@
 
   RtpTransceiverState CreateTransceiverState(
       rtc::scoped_refptr<webrtc::RtpTransceiverInterface> webrtc_transceiver,
-      std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
           sender_track_ref,
-      std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
           receiver_track_ref) {
     std::vector<std::string> receiver_stream_ids;
     for (const auto& stream : webrtc_transceiver->receiver()->streams()) {
@@ -168,7 +169,8 @@
 
   void CreateRemoteTrackAdapterOnSignalingThread(
       rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track,
-      std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>* track_ref,
+      std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>*
+          track_ref,
       base::RunLoop* run_loop) {
     *track_ref = track_map_->GetOrCreateRemoteTrackAdapter(webrtc_track.get());
     run_loop->Quit();
@@ -180,7 +182,7 @@
  protected:
   std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
-  scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_map_;
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_map_;
   rtc::scoped_refptr<MockPeerConnectionImpl> peer_connection_;
 };
 
diff --git a/content/renderer/media/webrtc/transceiver_state_surfacer.cc b/content/renderer/media/webrtc/transceiver_state_surfacer.cc
index 03fe437..74309bb 100644
--- a/content/renderer/media/webrtc/transceiver_state_surfacer.cc
+++ b/content/renderer/media/webrtc/transceiver_state_surfacer.cc
@@ -55,7 +55,7 @@
 
 void TransceiverStateSurfacer::Initialize(
     scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
-    scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+    scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
     std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
         webrtc_transceivers) {
   DCHECK(signaling_task_runner_->BelongsToCurrentThread());
@@ -78,7 +78,7 @@
     base::Optional<RtpSenderState> sender_state;
     auto webrtc_sender = webrtc_transceiver->sender();
     if (webrtc_sender) {
-      std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
           sender_track_ref;
       if (webrtc_sender->track()) {
         // The track adapter for this track must already exist for us to obtain
diff --git a/content/renderer/media/webrtc/transceiver_state_surfacer.h b/content/renderer/media/webrtc/transceiver_state_surfacer.h
index 133a206..61eaaa8c 100644
--- a/content/renderer/media/webrtc/transceiver_state_surfacer.h
+++ b/content/renderer/media/webrtc/transceiver_state_surfacer.h
@@ -6,8 +6,8 @@
 #define CONTENT_RENDERER_MEDIA_WEBRTC_TRANSCEIVER_STATE_SURFACER_H_
 
 #include "content/renderer/media/webrtc/rtc_rtp_transceiver.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/blink/public/platform/web_rtc_peer_connection_handler_client.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/webrtc/api/rtp_transceiver_interface.h"
 #include "third_party/webrtc/api/sctp_transport_interface.h"
 #include "third_party/webrtc/rtc_base/ref_count.h"
@@ -42,7 +42,7 @@
   // Must be invoked on the signaling thread.
   void Initialize(
       scoped_refptr<webrtc::PeerConnectionInterface> native_peer_connection,
-      scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
       std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
           transceivers);
 
diff --git a/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc b/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc
index 9412dc0..0fe6c044 100644
--- a/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc
+++ b/content/renderer/media/webrtc/transceiver_state_surfacer_unittest.cc
@@ -44,7 +44,7 @@
   void SetUp() override {
     dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
     main_task_runner_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
-    track_adapter_map_ = new WebRtcMediaStreamTrackAdapterMap(
+    track_adapter_map_ = new blink::WebRtcMediaStreamTrackAdapterMap(
         dependency_factory_.get(), main_task_runner_);
     surfacer_.reset(new TransceiverStateSurfacer(main_task_runner_,
                                                  signaling_task_runner()));
@@ -66,7 +66,7 @@
     return dependency_factory_->GetWebRtcSignalingThread();
   }
 
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
   CreateLocalTrackAndAdapter(const std::string& id) {
     return track_adapter_map_->GetOrCreateLocalTrackAdapter(
         CreateBlinkLocalTrack(id));
@@ -276,7 +276,7 @@
   scoped_refptr<webrtc::PeerConnectionInterface> peer_connection_;
   std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
-  scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
   std::unique_ptr<TransceiverStateSurfacer> surfacer_;
 };
 
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc b/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc
index c7ff7b0..2656120 100644
--- a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_unittest.cc
+++ b/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map_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 "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
 
 #include <memory>
 
@@ -30,8 +30,8 @@
   void SetUp() override {
     dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
     main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
-    map_ = new WebRtcMediaStreamTrackAdapterMap(dependency_factory_.get(),
-                                                main_thread_);
+    map_ = new blink::WebRtcMediaStreamTrackAdapterMap(
+        dependency_factory_.get(), main_thread_);
   }
 
   void TearDown() override { blink::WebHeap::CollectAllGarbageForTesting(); }
@@ -57,11 +57,12 @@
     return web_track;
   }
 
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
   GetOrCreateRemoteTrackAdapter(webrtc::MediaStreamTrackInterface* webrtc_track,
                                 bool wait_for_initialization = true) {
     DCHECK(main_thread_->BelongsToCurrentThread());
-    std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> adapter;
+    std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+        adapter;
     signaling_thread()->PostTask(
         FROM_HERE,
         base::BindOnce(&WebRtcMediaStreamTrackAdapterMapTest::
@@ -80,7 +81,8 @@
 
   void GetOrCreateRemoteTrackAdapterOnSignalingThread(
       webrtc::MediaStreamTrackInterface* webrtc_track,
-      std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>* adapter) {
+      std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>*
+          adapter) {
     DCHECK(signaling_thread()->BelongsToCurrentThread());
     *adapter = map_->GetOrCreateRemoteTrackAdapter(webrtc_track);
   }
@@ -116,21 +118,21 @@
 
   std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
-  scoped_refptr<WebRtcMediaStreamTrackAdapterMap> map_;
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> map_;
 };
 
 TEST_F(WebRtcMediaStreamTrackAdapterMapTest, AddAndRemoveLocalTrackAdapter) {
   blink::WebMediaStreamTrack web_track = CreateLocalTrack("local_track");
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> adapter_ref =
-      map_->GetOrCreateLocalTrackAdapter(web_track);
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      adapter_ref = map_->GetOrCreateLocalTrackAdapter(web_track);
   EXPECT_TRUE(adapter_ref->is_initialized());
   EXPECT_EQ(adapter_ref->GetAdapterForTesting(),
             map_->GetLocalTrackAdapter(web_track)->GetAdapterForTesting());
   EXPECT_EQ(1u, map_->GetLocalTrackCount());
 
   // "GetOrCreate" for already existing track.
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> adapter_ref2 =
-      map_->GetOrCreateLocalTrackAdapter(web_track);
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      adapter_ref2 = map_->GetOrCreateLocalTrackAdapter(web_track);
   EXPECT_EQ(adapter_ref->GetAdapterForTesting(),
             adapter_ref2->GetAdapterForTesting());
   EXPECT_EQ(1u, map_->GetLocalTrackCount());
@@ -151,8 +153,8 @@
 TEST_F(WebRtcMediaStreamTrackAdapterMapTest, AddAndRemoveRemoteTrackAdapter) {
   scoped_refptr<MockWebRtcAudioTrack> webrtc_track =
       MockWebRtcAudioTrack::Create("remote_track");
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> adapter_ref =
-      GetOrCreateRemoteTrackAdapter(webrtc_track.get());
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      adapter_ref = GetOrCreateRemoteTrackAdapter(webrtc_track.get());
   EXPECT_TRUE(adapter_ref->is_initialized());
   EXPECT_EQ(
       adapter_ref->GetAdapterForTesting(),
@@ -160,8 +162,8 @@
   EXPECT_EQ(1u, map_->GetRemoteTrackCount());
 
   // "GetOrCreate" for already existing track.
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> adapter_ref2 =
-      GetOrCreateRemoteTrackAdapter(webrtc_track.get());
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      adapter_ref2 = GetOrCreateRemoteTrackAdapter(webrtc_track.get());
   EXPECT_EQ(adapter_ref->GetAdapterForTesting(),
             adapter_ref2->GetAdapterForTesting());
   EXPECT_EQ(1u, map_->GetRemoteTrackCount());
@@ -183,8 +185,8 @@
        InitializeRemoteTrackAdapterExplicitly) {
   scoped_refptr<MockWebRtcAudioTrack> webrtc_track =
       MockWebRtcAudioTrack::Create("remote_track");
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> adapter_ref =
-      GetOrCreateRemoteTrackAdapter(webrtc_track.get(), false);
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      adapter_ref = GetOrCreateRemoteTrackAdapter(webrtc_track.get(), false);
   EXPECT_FALSE(adapter_ref->is_initialized());
   adapter_ref->InitializeOnMainThread();
   EXPECT_TRUE(adapter_ref->is_initialized());
@@ -208,8 +210,8 @@
   const char* id = "id";
 
   blink::WebMediaStreamTrack local_web_track = CreateLocalTrack(id);
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> local_adapter =
-      map_->GetOrCreateLocalTrackAdapter(local_web_track);
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      local_adapter = map_->GetOrCreateLocalTrackAdapter(local_web_track);
   EXPECT_TRUE(local_adapter->is_initialized());
   EXPECT_EQ(
       local_adapter->GetAdapterForTesting(),
@@ -218,8 +220,8 @@
 
   scoped_refptr<MockWebRtcAudioTrack> remote_webrtc_track =
       MockWebRtcAudioTrack::Create(id);
-  std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef> remote_adapter =
-      GetOrCreateRemoteTrackAdapter(remote_webrtc_track.get());
+  std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>
+      remote_adapter = GetOrCreateRemoteTrackAdapter(remote_webrtc_track.get());
   EXPECT_TRUE(remote_adapter->is_initialized());
   EXPECT_EQ(remote_adapter->GetAdapterForTesting(),
             map_->GetRemoteTrackAdapter(remote_webrtc_track.get())
@@ -311,7 +313,8 @@
   }
 
   void SignalingThreadLoop() {
-    std::vector<std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>>
+    std::vector<
+        std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>>
         track_refs;
     for (size_t i = 0u; i < 5u; ++i) {
       track_refs.push_back(map_->GetOrCreateRemoteTrackAdapter(
@@ -333,7 +336,8 @@
   }
 
   void DestroyAdapterRefsOnMainThread(
-      std::vector<std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>>
+      std::vector<
+          std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>>
           track_refs) {}
 
   void QuitRunLoopOnSignalingThread(base::RunLoop* run_loop) {
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc b/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
index f6f9f02..3005478 100644
--- a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_unittest.cc
+++ b/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_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 "content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter.h"
 
 #include <memory>
 
@@ -79,13 +79,14 @@
 
   void CreateRemoteTrackAdapter(
       webrtc::MediaStreamTrackInterface* webrtc_track) {
-    track_adapter_ = WebRtcMediaStreamTrackAdapter::CreateRemoteTrackAdapter(
-        dependency_factory_.get(), main_thread_, webrtc_track);
+    track_adapter_ =
+        blink::WebRtcMediaStreamTrackAdapter::CreateRemoteTrackAdapter(
+            dependency_factory_.get(), main_thread_, webrtc_track);
   }
 
   void HoldOntoAdapterReference(
       base::WaitableEvent* waitable_event,
-      scoped_refptr<WebRtcMediaStreamTrackAdapter> adapter) {
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> adapter) {
     waitable_event->Wait();
   }
 
@@ -120,12 +121,13 @@
 
   std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
-  scoped_refptr<WebRtcMediaStreamTrackAdapter> track_adapter_;
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> track_adapter_;
 };
 
 TEST_F(WebRtcMediaStreamTrackAdapterTest, LocalAudioTrack) {
-  track_adapter_ = WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter(
-      dependency_factory_.get(), main_thread_, CreateLocalAudioTrack());
+  track_adapter_ =
+      blink::WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter(
+          dependency_factory_.get(), main_thread_, CreateLocalAudioTrack());
   EXPECT_TRUE(track_adapter_->is_initialized());
   EXPECT_TRUE(!track_adapter_->web_track().IsNull());
   EXPECT_EQ(track_adapter_->web_track().Source().GetType(),
@@ -143,8 +145,9 @@
 
 // Flaky, see https://crbug.com/982200.
 TEST_F(WebRtcMediaStreamTrackAdapterTest, DISABLED_LocalVideoTrack) {
-  track_adapter_ = WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter(
-      dependency_factory_.get(), main_thread_, CreateLocalVideoTrack());
+  track_adapter_ =
+      blink::WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter(
+          dependency_factory_.get(), main_thread_, CreateLocalVideoTrack());
   EXPECT_TRUE(track_adapter_->is_initialized());
   EXPECT_TRUE(!track_adapter_->web_track().IsNull());
   EXPECT_EQ(track_adapter_->web_track().Source().GetType(),
diff --git a/content/renderer/media/webrtc/webrtc_set_description_observer.cc b/content/renderer/media/webrtc/webrtc_set_description_observer.cc
index bb3a737..ad7962f8 100644
--- a/content/renderer/media/webrtc/webrtc_set_description_observer.cc
+++ b/content/renderer/media/webrtc/webrtc_set_description_observer.cc
@@ -37,7 +37,8 @@
         scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
         scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
         scoped_refptr<webrtc::PeerConnectionInterface> pc,
-        scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+        scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap>
+            track_adapter_map,
         scoped_refptr<WebRtcSetDescriptionObserver> observer,
         bool surface_receivers_only)
     : main_task_runner_(std::move(main_task_runner)),
@@ -100,7 +101,7 @@
     scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
     scoped_refptr<webrtc::PeerConnectionInterface> pc,
-    scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+    scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
     scoped_refptr<WebRtcSetDescriptionObserver> observer,
     bool surface_receivers_only) {
   return new rtc::RefCountedObject<WebRtcSetLocalDescriptionObserverHandler>(
@@ -114,7 +115,8 @@
         scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
         scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
         scoped_refptr<webrtc::PeerConnectionInterface> pc,
-        scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+        scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap>
+            track_adapter_map,
         scoped_refptr<WebRtcSetDescriptionObserver> observer,
         bool surface_receivers_only)
     : handler_impl_(new WebRtcSetDescriptionObserverHandlerImpl(
@@ -142,7 +144,7 @@
     scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
     scoped_refptr<webrtc::PeerConnectionInterface> pc,
-    scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+    scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
     scoped_refptr<WebRtcSetDescriptionObserver> observer,
     bool surface_receivers_only) {
   return new rtc::RefCountedObject<WebRtcSetRemoteDescriptionObserverHandler>(
@@ -156,7 +158,8 @@
         scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
         scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
         scoped_refptr<webrtc::PeerConnectionInterface> pc,
-        scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+        scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap>
+            track_adapter_map,
         scoped_refptr<WebRtcSetDescriptionObserver> observer,
         bool surface_receivers_only)
     : handler_impl_(new WebRtcSetDescriptionObserverHandlerImpl(
diff --git a/content/renderer/media/webrtc/webrtc_set_description_observer.h b/content/renderer/media/webrtc/webrtc_set_description_observer.h
index 7d8acef..b4e6be3 100644
--- a/content/renderer/media/webrtc/webrtc_set_description_observer.h
+++ b/content/renderer/media/webrtc/webrtc_set_description_observer.h
@@ -18,7 +18,7 @@
 #include "content/renderer/media/webrtc/rtc_rtp_sender.h"
 #include "content/renderer/media/webrtc/rtc_rtp_transceiver.h"
 #include "content/renderer/media/webrtc/transceiver_state_surfacer.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/webrtc/api/jsep.h"
 #include "third_party/webrtc/api/peer_connection_interface.h"
 #include "third_party/webrtc/api/rtc_error.h"
@@ -88,7 +88,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
       scoped_refptr<webrtc::PeerConnectionInterface> pc,
-      scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
       scoped_refptr<WebRtcSetDescriptionObserver> observer,
       bool surface_receivers_only);
 
@@ -109,7 +109,7 @@
   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
   scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner_;
   scoped_refptr<webrtc::PeerConnectionInterface> pc_;
-  scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
   scoped_refptr<WebRtcSetDescriptionObserver> observer_;
   bool surface_receivers_only_;
 
@@ -125,7 +125,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
       scoped_refptr<webrtc::PeerConnectionInterface> pc,
-      scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
       scoped_refptr<WebRtcSetDescriptionObserver> observer,
       bool surface_receivers_only);
 
@@ -139,7 +139,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
       scoped_refptr<webrtc::PeerConnectionInterface> pc,
-      scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
       scoped_refptr<WebRtcSetDescriptionObserver> observer,
       bool surface_receivers_only);
   ~WebRtcSetLocalDescriptionObserverHandler() override;
@@ -158,7 +158,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
       scoped_refptr<webrtc::PeerConnectionInterface> pc,
-      scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
       scoped_refptr<WebRtcSetDescriptionObserver> observer,
       bool surface_receivers_only);
 
@@ -172,7 +172,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
       scoped_refptr<webrtc::PeerConnectionInterface> pc,
-      scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
       scoped_refptr<WebRtcSetDescriptionObserver> observer,
       bool surface_receivers_only);
   ~WebRtcSetRemoteDescriptionObserverHandler() override;
diff --git a/content/renderer/media/webrtc/webrtc_set_description_observer_unittest.cc b/content/renderer/media/webrtc/webrtc_set_description_observer_unittest.cc
index ea3e3d77d..96c4b368 100644
--- a/content/renderer/media/webrtc/webrtc_set_description_observer_unittest.cc
+++ b/content/renderer/media/webrtc/webrtc_set_description_observer_unittest.cc
@@ -17,11 +17,11 @@
 #include "content/child/child_process.h"
 #include "content/renderer/media/webrtc/mock_peer_connection_dependency_factory.h"
 #include "content/renderer/media/webrtc/mock_peer_connection_impl.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_source.h"
 #include "third_party/blink/public/platform/modules/peerconnection/webrtc_util.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
 #include "third_party/blink/public/web/web_heap.h"
 #include "third_party/webrtc/api/peer_connection_interface.h"
 #include "third_party/webrtc/api/test/mock_peerconnectioninterface.h"
@@ -78,7 +78,7 @@
       scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
       scoped_refptr<base::SingleThreadTaskRunner> signaling_task_runner,
       scoped_refptr<webrtc::PeerConnectionInterface> pc,
-      scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map,
       scoped_refptr<WebRtcSetDescriptionObserver> observer,
       bool surface_receivers_only)
       : signaling_task_runner_(std::move(signaling_task_runner)),
@@ -226,7 +226,7 @@
     pc_ = new webrtc::MockPeerConnectionInterface;
     dependency_factory_.reset(new MockPeerConnectionDependencyFactory());
     main_thread_ = blink::scheduler::GetSingleThreadTaskRunnerForTesting();
-    track_adapter_map_ = new WebRtcMediaStreamTrackAdapterMap(
+    track_adapter_map_ = new blink::WebRtcMediaStreamTrackAdapterMap(
         dependency_factory_.get(), main_thread_);
     observer_ = new WebRtcSetDescriptionObserverForTest();
     observer_handler_ = std::make_unique<ObserverHandlerWrapper>(
@@ -370,7 +370,7 @@
   scoped_refptr<webrtc::MockPeerConnectionInterface> pc_;
   std::unique_ptr<MockPeerConnectionDependencyFactory> dependency_factory_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
-  scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
   scoped_refptr<WebRtcSetDescriptionObserverForTest> observer_;
 
   ObserverHandlerType handler_type_;
@@ -379,7 +379,8 @@
 
   std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>>
       transceivers_;
-  std::vector<std::unique_ptr<WebRtcMediaStreamTrackAdapterMap::AdapterRef>>
+  std::vector<
+      std::unique_ptr<blink::WebRtcMediaStreamTrackAdapterMap::AdapterRef>>
       local_track_adapters_;
   // Used instead of |transceivers_| when |surfacer_type_| is
   // StateSurfacerType::kReceiversOnly.
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index b8c0046..43c64f3 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -903,7 +903,6 @@
     mojom::FrameNavigationControl::CommitNavigationCallback commit_callback,
     mojom::NavigationClient::CommitNavigationCallback
         per_navigation_mojo_interface_commit_callback,
-    const network::mojom::URLResponseHead* head,
     std::unique_ptr<NavigationClient> navigation_client,
     int request_id,
     bool was_initiated_in_this_frame) {
@@ -914,21 +913,6 @@
   DCHECK(!common_params.navigation_start.is_null());
   DCHECK(!common_params.url.SchemeIs(url::kJavaScriptScheme));
 
-  if (common_params.navigation_type == mojom::NavigationType::RESTORE) {
-    // We're doing a load of a page that was restored from the last session.
-    // By default this prefers the cache over loading
-    // (LOAD_SKIP_CACHE_VALIDATION) which can result in stale data for pages
-    // that are set to expire. We explicitly override that by setting the
-    // policy here so that as necessary we load from the network.
-    //
-    // TODO(davidben): Remove this in favor of passing a cache policy to the
-    // loadHistoryItem call in OnNavigate. That requires not overloading
-    // UseProtocolCachePolicy to mean both "normal load" and "determine cache
-    // policy based on load type, etc".
-    internal_data->set_cache_policy_override(
-        blink::mojom::FetchCacheMode::kDefault);
-  }
-
   internal_data->set_is_overriding_user_agent(
       commit_params.is_overriding_user_agent);
   internal_data->set_must_reset_scroll_and_scale_state(
@@ -936,16 +920,6 @@
       mojom::NavigationType::RELOAD_ORIGINAL_REQUEST_URL);
   internal_data->set_request_id(request_id);
 
-  if (head) {
-    document_state->set_was_fetched_via_spdy(head->was_fetched_via_spdy);
-    document_state->set_was_alpn_negotiated(head->was_alpn_negotiated);
-    document_state->set_alpn_negotiated_protocol(
-        head->alpn_negotiated_protocol);
-    document_state->set_was_alternate_protocol_available(
-        head->was_alternate_protocol_available);
-    document_state->set_connection_info(head->connection_info);
-  }
-
   bool load_data = !common_params.base_url_for_data_url.is_empty() &&
                    !common_params.history_url_for_data_url.is_empty() &&
                    common_params.url.SchemeIs(url::kDataScheme);
@@ -1058,6 +1032,21 @@
   }
   navigation_params->appcache_host_id =
       commit_params.appcache_host_id.value_or(base::UnguessableToken());
+
+  if (common_params.navigation_type == mojom::NavigationType::RESTORE) {
+    // We're doing a load of a page that was restored from the last session.
+    // By default this prefers the cache over loading
+    // (LOAD_SKIP_CACHE_VALIDATION) which can result in stale data for pages
+    // that are set to expire. We explicitly override that by setting the
+    // policy here so that as necessary we load from the network.
+    //
+    // TODO(davidben): Remove this in favor of passing a cache policy to the
+    // loadHistoryItem call in OnNavigate. That requires not overloading
+    // UseProtocolCachePolicy to mean both "normal load" and "determine cache
+    // policy based on load type, etc".
+    navigation_params->force_fetch_cache_mode =
+        blink::mojom::FetchCacheMode::kDefault;
+  }
 }
 
 // Fills in the origin policy associated with this response, if any is present.
@@ -3428,20 +3417,12 @@
   DCHECK(common_params->url.SchemeIs(url::kJavaScriptScheme) ||
          common_params->url.IsAboutSrcdoc() || subresource_loader_factories);
 
-  // We only save metrics of the main frame's main resource to the
-  // document state. In view source mode, we effectively let the user
-  // see the source of the server's error page instead of using custom
-  // one derived from the metrics saved to document state.
-  const network::mojom::URLResponseHead* document_state_response_head =
-      (!frame_->Parent() && !frame_->IsViewSourceModeEnabled())
-          ? response_head.get()
-          : nullptr;
   int request_id = ResourceDispatcher::MakeRequestID();
   std::unique_ptr<DocumentState> document_state = BuildDocumentStateFromParams(
       *common_params, *commit_params, base::TimeTicks::Now(),
       std::move(callback), std::move(per_navigation_mojo_interface_callback),
-      document_state_response_head, std::move(navigation_client_impl_),
-      request_id, was_initiated_in_this_frame);
+      std::move(navigation_client_impl_), request_id,
+      was_initiated_in_this_frame);
 
   // Check if the navigation being committed originated as a client redirect.
   bool is_client_redirect =
@@ -3854,7 +3835,7 @@
   // |was_initiated_in_this_frame| is false.
   std::unique_ptr<DocumentState> document_state = BuildDocumentStateFromParams(
       *common_params, *commit_params, base::TimeTicks(), std::move(callback),
-      std::move(per_navigation_mojo_interface_callback), nullptr,
+      std::move(per_navigation_mojo_interface_callback),
       std::move(navigation_client_impl_), ResourceDispatcher::MakeRequestID(),
       false /* was_initiated_in_this_frame */);
 
@@ -5309,9 +5290,6 @@
   if (!new_url.is_empty())
     request.SetUrl(WebURL(new_url));
 
-  if (internal_data->is_cache_policy_override_set())
-    request.SetCacheMode(internal_data->cache_policy_override());
-
   // The request's extra data may indicate that we should set a custom user
   // agent. This needs to be done here, after WebKit is through with setting the
   // user agent on its own.
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc
index 528eccc2..9961fd9 100644
--- a/content/renderer/renderer_blink_platform_impl.cc
+++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -86,7 +86,6 @@
 #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
 #include "third_party/blink/public/platform/url_conversion.h"
 #include "third_party/blink/public/platform/web_audio_latency_hint.h"
-#include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
 #include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
 #include "third_party/blink/public/platform/web_security_origin.h"
 #include "third_party/blink/public/platform/web_theme_engine.h"
@@ -116,7 +115,6 @@
 #include "base/win/windows_version.h"
 #endif
 
-#include "content/renderer/media/webrtc/rtc_certificate_generator.h"
 #include "third_party/blink/public/platform/modules/mediastream/webrtc_uma_histograms.h"
 
 using blink::Platform;
@@ -552,13 +550,6 @@
 
 //------------------------------------------------------------------------------
 
-std::unique_ptr<blink::WebRTCCertificateGenerator>
-RendererBlinkPlatformImpl::CreateRTCCertificateGenerator() {
-  return std::make_unique<RTCCertificateGenerator>();
-}
-
-//------------------------------------------------------------------------------
-
 scoped_refptr<base::SingleThreadTaskRunner>
 RendererBlinkPlatformImpl::GetWebRtcWorkerThread() {
   auto* rtc_dependency_factory =
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h
index 16d420e5..ce554f1 100644
--- a/content/renderer/renderer_blink_platform_impl.h
+++ b/content/renderer/renderer_blink_platform_impl.h
@@ -130,8 +130,6 @@
   CreateRTCPeerConnectionHandler(
       blink::WebRTCPeerConnectionHandlerClient* client,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner) override;
-  std::unique_ptr<blink::WebRTCCertificateGenerator>
-  CreateRTCCertificateGenerator() override;
   scoped_refptr<base::SingleThreadTaskRunner> GetWebRtcWorkerThread() override;
   rtc::Thread* GetWebRtcWorkerThreadRtcThread() override;
   scoped_refptr<base::SingleThreadTaskRunner> GetWebRtcSignalingTaskRunner()
diff --git a/content/renderer/service_worker/service_worker_provider_context.cc b/content/renderer/service_worker/service_worker_provider_context.cc
index b0074e2..a4bbcd64 100644
--- a/content/renderer/service_worker/service_worker_provider_context.cc
+++ b/content/renderer/service_worker/service_worker_provider_context.cc
@@ -20,8 +20,6 @@
 #include "content/renderer/service_worker/service_worker_subresource_loader.h"
 #include "content/renderer/service_worker/web_service_worker_provider_impl.h"
 #include "content/renderer/worker/worker_thread_registry.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
-#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
 #include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
@@ -40,7 +38,7 @@
     std::unique_ptr<network::SharedURLLoaderFactoryInfo> fallback_factory_info,
     mojo::PendingReceiver<blink::mojom::ControllerServiceWorkerConnector>
         connector_receiver,
-    network::mojom::URLLoaderFactoryRequest request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
     scoped_refptr<base::SequencedTaskRunner> task_runner) {
   auto connector = base::MakeRefCounted<ControllerServiceWorkerConnector>(
       std::move(remote_container_host), std::move(remote_controller),
@@ -49,7 +47,7 @@
   ServiceWorkerSubresourceLoaderFactory::Create(
       std::move(connector),
       network::SharedURLLoaderFactory::Create(std::move(fallback_factory_info)),
-      std::move(request), std::move(task_runner));
+      std::move(receiver), std::move(task_runner));
 }
 
 }  // namespace
diff --git a/content/renderer/service_worker/service_worker_provider_context_unittest.cc b/content/renderer/service_worker/service_worker_provider_context_unittest.cc
index 53bb098..18947e9 100644
--- a/content/renderer/service_worker/service_worker_provider_context_unittest.cc
+++ b/content/renderer/service_worker/service_worker_provider_context_unittest.cc
@@ -24,6 +24,7 @@
 #include "mojo/public/cpp/bindings/associated_binding_set.h"
 #include "mojo/public/cpp/bindings/associated_receiver_set.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -138,8 +139,9 @@
   FakeURLLoaderFactory() = default;
   ~FakeURLLoaderFactory() override = default;
 
-  void AddBinding(network::mojom::URLLoaderFactoryRequest request) {
-    bindings_.AddBinding(this, std::move(request));
+  void AddReceiver(
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
+    receivers_.Add(this, std::move(receiver));
   }
 
   // network::mojom::URLLoaderFactory:
@@ -158,8 +160,9 @@
     if (start_loader_callback_)
       std::move(start_loader_callback_).Run();
   }
-  void Clone(network::mojom::URLLoaderFactoryRequest factory) override {
-    bindings_.AddBinding(this, std::move(factory));
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory)
+      override {
+    receivers_.Add(this, std::move(factory));
   }
 
   void set_start_loader_callback(base::OnceClosure closure) {
@@ -170,7 +173,7 @@
   GURL last_request_url() const { return last_url_; }
 
  private:
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
   std::vector<network::mojom::URLLoaderClientPtr> clients_;
   base::OnceClosure start_loader_callback_;
   GURL last_url_;
@@ -274,7 +277,7 @@
 
   void EnableNetworkService() {
     network::mojom::URLLoaderFactoryPtr fake_loader_factory;
-    fake_loader_factory_.AddBinding(MakeRequest(&fake_loader_factory));
+    fake_loader_factory_.AddReceiver(MakeRequest(&fake_loader_factory));
     loader_factory_ =
         base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
             std::move(fake_loader_factory));
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.cc b/content/renderer/service_worker/service_worker_subresource_loader.cc
index 8917971..9e7b54e5 100644
--- a/content/renderer/service_worker/service_worker_subresource_loader.cc
+++ b/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -21,7 +21,6 @@
 #include "content/renderer/render_thread_impl.h"
 #include "content/renderer/renderer_blink_platform_impl.h"
 #include "content/renderer/service_worker/controller_service_worker_connector.h"
-#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/strong_binding.h"
 #include "net/base/net_errors.h"
@@ -773,25 +772,25 @@
 void ServiceWorkerSubresourceLoaderFactory::Create(
     scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
     scoped_refptr<network::SharedURLLoaderFactory> fallback_factory,
-    network::mojom::URLLoaderFactoryRequest request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
     scoped_refptr<base::SequencedTaskRunner> task_runner) {
   new ServiceWorkerSubresourceLoaderFactory(
       std::move(controller_connector), std::move(fallback_factory),
-      std::move(request), std::move(task_runner));
+      std::move(receiver), std::move(task_runner));
 }
 
 ServiceWorkerSubresourceLoaderFactory::ServiceWorkerSubresourceLoaderFactory(
     scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
     scoped_refptr<network::SharedURLLoaderFactory> fallback_factory,
-    network::mojom::URLLoaderFactoryRequest request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
     scoped_refptr<base::SequencedTaskRunner> task_runner)
     : controller_connector_(std::move(controller_connector)),
       fallback_factory_(std::move(fallback_factory)),
       task_runner_(std::move(task_runner)) {
   DCHECK(fallback_factory_);
-  bindings_.AddBinding(this, std::move(request));
-  bindings_.set_connection_error_handler(base::BindRepeating(
-      &ServiceWorkerSubresourceLoaderFactory::OnConnectionError,
+  receivers_.Add(this, std::move(receiver));
+  receivers_.set_disconnect_handler(base::BindRepeating(
+      &ServiceWorkerSubresourceLoaderFactory::OnMojoDisconnect,
       base::Unretained(this)));
 }
 
@@ -817,12 +816,12 @@
 }
 
 void ServiceWorkerSubresourceLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
-  bindings_.AddBinding(this, std::move(request));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
+  receivers_.Add(this, std::move(receiver));
 }
 
-void ServiceWorkerSubresourceLoaderFactory::OnConnectionError() {
-  if (!bindings_.empty())
+void ServiceWorkerSubresourceLoaderFactory::OnMojoDisconnect() {
+  if (!receivers_.empty())
     return;
   delete this;
 }
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.h b/content/renderer/service_worker/service_worker_subresource_loader.h
index 36063d7d..47f27edd 100644
--- a/content/renderer/service_worker/service_worker_subresource_loader.h
+++ b/content/renderer/service_worker/service_worker_subresource_loader.h
@@ -12,8 +12,9 @@
 #include "base/time/time.h"
 #include "content/common/content_export.h"
 #include "content/renderer/service_worker/controller_service_worker_connector.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "net/url_request/redirect_info.h"
@@ -215,7 +216,7 @@
   static void Create(
       scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
       scoped_refptr<network::SharedURLLoaderFactory> fallback_factory,
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       scoped_refptr<base::SequencedTaskRunner> task_runner);
 
   ~ServiceWorkerSubresourceLoaderFactory() override;
@@ -229,23 +230,24 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
 
  private:
   ServiceWorkerSubresourceLoaderFactory(
       scoped_refptr<ControllerServiceWorkerConnector> controller_connector,
       scoped_refptr<network::SharedURLLoaderFactory> fallback_factory,
-      network::mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
       scoped_refptr<base::SequencedTaskRunner> task_runner);
 
-  void OnConnectionError();
+  void OnMojoDisconnect();
 
   scoped_refptr<ControllerServiceWorkerConnector> controller_connector_;
 
   // Used when a request falls back to network.
   scoped_refptr<network::SharedURLLoaderFactory> fallback_factory_;
 
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   // The task runner where this factory is running.
   scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/content/test/fake_network.h b/content/test/fake_network.h
index dec2418..71589d6 100644
--- a/content/test/fake_network.h
+++ b/content/test/fake_network.h
@@ -63,8 +63,6 @@
 
   // User-defined URL => ResponseInfo map.
   base::flat_map<GURL, ResponseInfo> response_info_map_;
-
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
 };
 
 }  // namespace content
diff --git a/content/test/fake_network_url_loader_factory.cc b/content/test/fake_network_url_loader_factory.cc
index c59b991..1cca54c 100644
--- a/content/test/fake_network_url_loader_factory.cc
+++ b/content/test/fake_network_url_loader_factory.cc
@@ -119,8 +119,8 @@
 }
 
 void FakeNetworkURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
-  bindings_.AddBinding(this, std::move(request));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
+  receivers_.Add(this, std::move(receiver));
 }
 
 }  // namespace content
diff --git a/content/test/fake_network_url_loader_factory.h b/content/test/fake_network_url_loader_factory.h
index bcbb739a..5c8ba3b 100644
--- a/content/test/fake_network_url_loader_factory.h
+++ b/content/test/fake_network_url_loader_factory.h
@@ -5,7 +5,8 @@
 #ifndef CONTENT_TEST_FAKE_NETWORK_URL_LOADER_FACTORY_H_
 #define CONTENT_TEST_FAKE_NETWORK_URL_LOADER_FACTORY_H_
 
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
 namespace content {
@@ -50,7 +51,8 @@
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
 
   // Sets the response for a specific url. CreateLoaderAndStart() uses this
   // response instead of the default.
@@ -92,7 +94,7 @@
   // User-defined URL => ResponseInfo map.
   base::flat_map<GURL, ResponseInfo> response_info_map_;
 
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeNetworkURLLoaderFactory);
 };
diff --git a/content/test/not_implemented_network_url_loader_factory.cc b/content/test/not_implemented_network_url_loader_factory.cc
index ea33208..47ced07 100644
--- a/content/test/not_implemented_network_url_loader_factory.cc
+++ b/content/test/not_implemented_network_url_loader_factory.cc
@@ -28,8 +28,8 @@
 }
 
 void NotImplementedNetworkURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
-  bindings_.AddBinding(this, std::move(request));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
+  receivers_.Add(this, std::move(receiver));
 }
 
 }  // namespace content
diff --git a/content/test/not_implemented_network_url_loader_factory.h b/content/test/not_implemented_network_url_loader_factory.h
index acfbdd90..ffdda3c 100644
--- a/content/test/not_implemented_network_url_loader_factory.h
+++ b/content/test/not_implemented_network_url_loader_factory.h
@@ -5,7 +5,8 @@
 #ifndef CONTENT_TEST_NOT_IMPLEMENTED_NETWORK_URL_LOADER_FACTORY_H_
 #define CONTENT_TEST_NOT_IMPLEMENTED_NETWORK_URL_LOADER_FACTORY_H_
 
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
 namespace content {
@@ -27,10 +28,11 @@
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
 
  private:
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   DISALLOW_COPY_AND_ASSIGN(NotImplementedNetworkURLLoaderFactory);
 };
diff --git a/content/test/test_blink_web_unit_test_support.cc b/content/test/test_blink_web_unit_test_support.cc
index d8542c74..c5eece4 100644
--- a/content/test/test_blink_web_unit_test_support.cc
+++ b/content/test/test_blink_web_unit_test_support.cc
@@ -35,7 +35,6 @@
 #include "third_party/blink/public/platform/web_connection_type.h"
 #include "third_party/blink/public/platform/web_data.h"
 #include "third_party/blink/public/platform/web_network_state_notifier.h"
-#include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
 #include "third_party/blink/public/platform/web_runtime_features.h"
 #include "third_party/blink/public/platform/web_string.h"
 #include "third_party/blink/public/platform/web_url.h"
@@ -298,43 +297,6 @@
   return threaded_animation_;
 }
 
-namespace {
-
-class TestWebRTCCertificateGenerator
-    : public blink::WebRTCCertificateGenerator {
-  void GenerateCertificate(
-      const blink::WebRTCKeyParams& key_params,
-      blink::WebRTCCertificateCallback completion_callback,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
-    NOTIMPLEMENTED();
-  }
-  void GenerateCertificateWithExpiration(
-      const blink::WebRTCKeyParams& key_params,
-      uint64_t expires_ms,
-      blink::WebRTCCertificateCallback completion_callback,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner) override {
-    NOTIMPLEMENTED();
-  }
-  bool IsSupportedKeyParams(const blink::WebRTCKeyParams& key_params) override {
-    return false;
-  }
-  rtc::scoped_refptr<rtc::RTCCertificate> FromPEM(
-      blink::WebString pem_private_key,
-      blink::WebString pem_certificate) override {
-    rtc::scoped_refptr<rtc::RTCCertificate> certificate =
-        rtc::RTCCertificate::FromPEM(rtc::RTCCertificatePEM(
-            pem_private_key.Utf8(), pem_certificate.Utf8()));
-    return certificate;
-  }
-};
-
-}  // namespace
-
-std::unique_ptr<blink::WebRTCCertificateGenerator>
-TestBlinkWebUnitTestSupport::CreateRTCCertificateGenerator() {
-  return std::make_unique<TestWebRTCCertificateGenerator>();
-}
-
 void TestBlinkWebUnitTestSupport::BindClipboardHost(
     mojo::ScopedMessagePipeHandle handle) {
   mock_clipboard_host_->Bind(
diff --git a/content/test/test_blink_web_unit_test_support.h b/content/test/test_blink_web_unit_test_support.h
index 10a26ae8..bfc5558 100644
--- a/content/test/test_blink_web_unit_test_support.h
+++ b/content/test/test_blink_web_unit_test_support.h
@@ -62,9 +62,6 @@
 
   bool IsThreadedAnimationEnabled() override;
 
-  std::unique_ptr<blink::WebRTCCertificateGenerator>
-  CreateRTCCertificateGenerator() override;
-
   // May be called when |this| is registered as the active blink Platform
   // implementation. Overrides the result of IsThreadedAnimationEnabled() to
   // the provided value, and returns the value it was set to before the call.
diff --git a/device/vr/android/gvr/gvr_device.cc b/device/vr/android/gvr/gvr_device.cc
index 084f186..116982b 100644
--- a/device/vr/android/gvr/gvr_device.cc
+++ b/device/vr/android/gvr/gvr_device.cc
@@ -20,6 +20,7 @@
 #include "device/vr/android/gvr/gvr_device_provider.h"
 #include "device/vr/android/gvr/gvr_utils.h"
 #include "device/vr/jni_headers/NonPresentingGvrContext_jni.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr.h"
 #include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/transform.h"
@@ -141,9 +142,7 @@
 
 }  // namespace
 
-GvrDevice::GvrDevice()
-    : VRDeviceBase(mojom::XRDeviceId::GVR_DEVICE_ID),
-      exclusive_controller_binding_(this) {
+GvrDevice::GvrDevice() : VRDeviceBase(mojom::XRDeviceId::GVR_DEVICE_ID) {
   GvrDelegateProviderFactory::SetDevice(this);
 }
 
@@ -156,7 +155,8 @@
   }
 
   if (pending_request_session_callback_) {
-    std::move(pending_request_session_callback_).Run(nullptr, nullptr);
+    std::move(pending_request_session_callback_)
+        .Run(nullptr, mojo::NullRemote());
   }
 
   GvrDelegateProviderFactory::SetDevice(nullptr);
@@ -171,7 +171,7 @@
     mojom::XRRuntime::RequestSessionCallback callback) {
   // We can only process one request at a time.
   if (pending_request_session_callback_) {
-    std::move(callback).Run(nullptr, nullptr);
+    std::move(callback).Run(nullptr, mojo::NullRemote());
     return;
   }
   pending_request_session_callback_ = std::move(callback);
@@ -189,25 +189,26 @@
   DCHECK(pending_request_session_callback_);
 
   if (!session) {
-    std::move(pending_request_session_callback_).Run(nullptr, nullptr);
+    std::move(pending_request_session_callback_)
+        .Run(nullptr, mojo::NullRemote());
     return;
   }
 
   OnStartPresenting();
 
-  mojom::XRSessionControllerPtr session_controller;
   // Close the binding to ensure any previous sessions were closed.
   // TODO(billorr): Only do this in OnPresentingControllerMojoConnectionError.
-  exclusive_controller_binding_.Close();
-  exclusive_controller_binding_.Bind(mojo::MakeRequest(&session_controller));
+  exclusive_controller_receiver_.reset();
+
+  std::move(pending_request_session_callback_)
+      .Run(std::move(session),
+           exclusive_controller_receiver_.BindNewPipeAndPassRemote());
 
   // Unretained is safe because the error handler won't be called after the
   // binding has been destroyed.
-  exclusive_controller_binding_.set_connection_error_handler(
+  exclusive_controller_receiver_.set_disconnect_handler(
       base::BindOnce(&GvrDevice::OnPresentingControllerMojoConnectionError,
                      base::Unretained(this)));
-  std::move(pending_request_session_callback_)
-      .Run(std::move(session), std::move(session_controller));
 }
 
 // XRSessionController
@@ -225,7 +226,7 @@
   if (delegate_provider)
     delegate_provider->ExitWebVRPresent();
   OnExitPresent();
-  exclusive_controller_binding_.Close();
+  exclusive_controller_receiver_.reset();
 }
 
 void GvrDevice::OnListeningForActivate(bool listening) {
@@ -312,13 +313,15 @@
   DCHECK(pending_request_session_callback_);
 
   if (!success) {
-    std::move(pending_request_session_callback_).Run(nullptr, nullptr);
+    std::move(pending_request_session_callback_)
+        .Run(nullptr, mojo::NullRemote());
     return;
   }
 
   GvrDelegateProvider* delegate_provider = GetGvrDelegateProvider();
   if (!delegate_provider) {
-    std::move(pending_request_session_callback_).Run(nullptr, nullptr);
+    std::move(pending_request_session_callback_)
+        .Run(nullptr, mojo::NullRemote());
     return;
   }
 
diff --git a/device/vr/android/gvr/gvr_device.h b/device/vr/android/gvr/gvr_device.h
index 4c91a52..bf4c03fa 100644
--- a/device/vr/android/gvr/gvr_device.h
+++ b/device/vr/android/gvr/gvr_device.h
@@ -12,6 +12,7 @@
 #include "base/android/scoped_java_ref.h"
 #include "base/macros.h"
 #include "device/vr/vr_device_base.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 #include "third_party/gvr-android-sdk/src/libraries/headers/vr/gvr/capi/include/gvr_types.h"
 
 namespace device {
@@ -63,7 +64,8 @@
 
   bool paused_ = true;
 
-  mojo::Binding<mojom::XRSessionController> exclusive_controller_binding_;
+  mojo::Receiver<mojom::XRSessionController> exclusive_controller_receiver_{
+      this};
 
   mojom::XRRuntime::RequestSessionCallback pending_request_session_callback_;
 
diff --git a/device/vr/isolated_gamepad_data_fetcher.cc b/device/vr/isolated_gamepad_data_fetcher.cc
index 55ea0eb..d58d3189 100644
--- a/device/vr/isolated_gamepad_data_fetcher.cc
+++ b/device/vr/isolated_gamepad_data_fetcher.cc
@@ -70,7 +70,8 @@
 
 IsolatedGamepadDataFetcher::Factory::Factory(
     device::mojom::XRDeviceId display_id,
-    device::mojom::IsolatedXRGamepadProviderFactoryPtr factory)
+    mojo::PendingRemote<device::mojom::IsolatedXRGamepadProviderFactory>
+        factory)
     : display_id_(display_id), factory_(std::move(factory)) {}
 
 IsolatedGamepadDataFetcher::Factory::~Factory() {}
@@ -291,7 +292,8 @@
 
 void IsolatedGamepadDataFetcher::Factory::AddGamepad(
     device::mojom::XRDeviceId device_id,
-    device::mojom::IsolatedXRGamepadProviderFactoryPtr gamepad_factory) {
+    mojo::PendingRemote<device::mojom::IsolatedXRGamepadProviderFactory>
+        gamepad_factory) {
   if (!IsValidDeviceId(device_id))
     return;
 
diff --git a/device/vr/isolated_gamepad_data_fetcher.h b/device/vr/isolated_gamepad_data_fetcher.h
index 8402c21..cf5e1af 100644
--- a/device/vr/isolated_gamepad_data_fetcher.h
+++ b/device/vr/isolated_gamepad_data_fetcher.h
@@ -18,19 +18,21 @@
   class DEVICE_VR_EXPORT Factory : public GamepadDataFetcherFactory {
    public:
     Factory(device::mojom::XRDeviceId display_id,
-            device::mojom::IsolatedXRGamepadProviderFactoryPtr factory);
+            mojo::PendingRemote<device::mojom::IsolatedXRGamepadProviderFactory>
+                factory);
     ~Factory() override;
     std::unique_ptr<GamepadDataFetcher> CreateDataFetcher() override;
     GamepadSource source() override;
 
     static void AddGamepad(
         device::mojom::XRDeviceId device_id,
-        device::mojom::IsolatedXRGamepadProviderFactoryPtr gamepad_factory);
+        mojo::PendingRemote<device::mojom::IsolatedXRGamepadProviderFactory>
+            gamepad_factory);
     static void RemoveGamepad(device::mojom::XRDeviceId device_id);
 
    private:
     device::mojom::XRDeviceId display_id_;
-    device::mojom::IsolatedXRGamepadProviderFactoryPtr factory_;
+    mojo::Remote<device::mojom::IsolatedXRGamepadProviderFactory> factory_;
   };
 
   IsolatedGamepadDataFetcher(
diff --git a/device/vr/oculus/oculus_device.cc b/device/vr/oculus/oculus_device.cc
index 62c3ee48..cc3f0a5c 100644
--- a/device/vr/oculus/oculus_device.cc
+++ b/device/vr/oculus/oculus_device.cc
@@ -16,6 +16,7 @@
 #include "device/vr/oculus/oculus_render_loop.h"
 #include "device/vr/oculus/oculus_type_converters.h"
 #include "device/vr/util/transform_utils.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "third_party/libovr/src/Include/OVR_CAPI.h"
 #include "third_party/libovr/src/Include/OVR_CAPI_D3D.h"
 #include "ui/gfx/geometry/angle_conversions.h"
@@ -95,9 +96,6 @@
 OculusDevice::OculusDevice()
     : VRDeviceBase(mojom::XRDeviceId::OCULUS_DEVICE_ID),
       main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
-      exclusive_controller_binding_(this),
-      gamepad_provider_factory_binding_(this),
-      compositor_host_binding_(this),
       weak_ptr_factory_(this) {
   render_loop_ = std::make_unique<OculusRenderLoop>();
 }
@@ -112,16 +110,14 @@
   return result.IsOculusServiceRunning;
 }
 
-mojom::IsolatedXRGamepadProviderFactoryPtr OculusDevice::BindGamepadFactory() {
-  mojom::IsolatedXRGamepadProviderFactoryPtr ret;
-  gamepad_provider_factory_binding_.Bind(mojo::MakeRequest(&ret));
-  return ret;
+mojo::PendingRemote<mojom::IsolatedXRGamepadProviderFactory>
+OculusDevice::BindGamepadFactory() {
+  return gamepad_provider_factory_receiver_.BindNewPipeAndPassRemote();
 }
 
-mojom::XRCompositorHostPtr OculusDevice::BindCompositorHost() {
-  mojom::XRCompositorHostPtr ret;
-  compositor_host_binding_.Bind(mojo::MakeRequest(&ret));
-  return ret;
+mojo::PendingRemote<mojom::XRCompositorHost>
+OculusDevice::BindCompositorHost() {
+  return compositor_host_receiver_.BindNewPipeAndPassRemote();
 }
 
 OculusDevice::~OculusDevice() {
@@ -137,7 +133,7 @@
     mojom::XRRuntimeSessionOptionsPtr options,
     mojom::XRRuntime::RequestSessionCallback callback) {
   if (!EnsureValidDisplayInfo()) {
-    std::move(callback).Run(nullptr, nullptr);
+    std::move(callback).Run(nullptr, mojo::NullRemote());
     return;
   }
 
@@ -149,7 +145,7 @@
     render_loop_->Start();
 
     if (!render_loop_->IsRunning()) {
-      std::move(callback).Run(nullptr, nullptr);
+      std::move(callback).Run(nullptr, mojo::NullRemote());
       StartOvrSession();
       return;
     }
@@ -214,7 +210,7 @@
     mojom::XRSessionPtr session) {
   outstanding_session_requests_count_--;
   if (!result) {
-    std::move(callback).Run(nullptr, nullptr);
+    std::move(callback).Run(nullptr, mojo::NullRemote());
 
     // Start magic window again.
     if (outstanding_session_requests_count_ == 0)
@@ -224,18 +220,17 @@
 
   OnStartPresenting();
 
-  mojom::XRSessionControllerPtr session_controller;
-  exclusive_controller_binding_.Bind(mojo::MakeRequest(&session_controller));
+  session->display_info = display_info_.Clone();
+
+  std::move(callback).Run(
+      std::move(session),
+      exclusive_controller_receiver_.BindNewPipeAndPassRemote());
 
   // Unretained is safe because the error handler won't be called after the
   // binding has been destroyed.
-  exclusive_controller_binding_.set_connection_error_handler(
+  exclusive_controller_receiver_.set_disconnect_handler(
       base::BindOnce(&OculusDevice::OnPresentingControllerMojoConnectionError,
                      base::Unretained(this)));
-
-  session->display_info = display_info_.Clone();
-
-  std::move(callback).Run(std::move(session), std::move(session_controller));
 }
 
 bool OculusDevice::IsAvailable() {
@@ -254,7 +249,7 @@
       FROM_HERE, base::BindOnce(&XRCompositorCommon::ExitPresent,
                                 base::Unretained(render_loop_.get())));
   OnExitPresent();
-  exclusive_controller_binding_.Close();
+  exclusive_controller_receiver_.reset();
 }
 
 void OculusDevice::OnPresentationEnded() {
diff --git a/device/vr/oculus/oculus_device.h b/device/vr/oculus/oculus_device.h
index 3efe2d8..63670cf 100644
--- a/device/vr/oculus/oculus_device.h
+++ b/device/vr/oculus/oculus_device.h
@@ -11,8 +11,9 @@
 #include "base/single_thread_task_runner.h"
 #include "device/vr/public/mojom/vr_service.mojom.h"
 #include "device/vr/vr_device_base.h"
-#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 #include "third_party/libovr/src/Include/OVR_CAPI.h"
 
 namespace device {
@@ -42,8 +43,9 @@
 
   bool IsAvailable();
 
-  mojom::IsolatedXRGamepadProviderFactoryPtr BindGamepadFactory();
-  mojom::XRCompositorHostPtr BindCompositorHost();
+  mojo::PendingRemote<mojom::IsolatedXRGamepadProviderFactory>
+  BindGamepadFactory();
+  mojo::PendingRemote<mojom::XRCompositorHost> BindCompositorHost();
 
  private:
   // XRSessionController
@@ -71,12 +73,13 @@
   ovrSession session_ = nullptr;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
 
-  mojo::Binding<mojom::XRSessionController> exclusive_controller_binding_;
-  mojo::Binding<mojom::IsolatedXRGamepadProviderFactory>
-      gamepad_provider_factory_binding_;
+  mojo::Receiver<mojom::XRSessionController> exclusive_controller_receiver_{
+      this};
+  mojo::Receiver<mojom::IsolatedXRGamepadProviderFactory>
+      gamepad_provider_factory_receiver_{this};
   mojo::PendingReceiver<mojom::IsolatedXRGamepadProvider> provider_receiver_;
 
-  mojo::Binding<mojom::XRCompositorHost> compositor_host_binding_;
+  mojo::Receiver<mojom::XRCompositorHost> compositor_host_receiver_{this};
   mojo::PendingReceiver<mojom::ImmersiveOverlay> overlay_receiver_;
 
   base::WeakPtrFactory<OculusDevice> weak_ptr_factory_;
diff --git a/device/vr/openvr/openvr_device.cc b/device/vr/openvr/openvr_device.cc
index 42ed3976..98e630c7 100644
--- a/device/vr/openvr/openvr_device.cc
+++ b/device/vr/openvr/openvr_device.cc
@@ -16,6 +16,7 @@
 #include "build/build_config.h"
 #include "device/vr/openvr/openvr_render_loop.h"
 #include "device/vr/openvr/openvr_type_converters.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "third_party/openvr/src/headers/openvr.h"
 #include "ui/gfx/geometry/angle_conversions.h"
 
@@ -122,10 +123,7 @@
 
 OpenVRDevice::OpenVRDevice()
     : VRDeviceBase(device::mojom::XRDeviceId::OPENVR_DEVICE_ID),
-      main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()),
-      exclusive_controller_binding_(this),
-      gamepad_provider_factory_binding_(this),
-      compositor_host_binding_(this) {
+      main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
   render_loop_ = std::make_unique<OpenVRRenderLoop>();
 
   OnPollingEvents();
@@ -139,16 +137,14 @@
   return vr::VR_IsRuntimeInstalled();
 }
 
-mojom::IsolatedXRGamepadProviderFactoryPtr OpenVRDevice::BindGamepadFactory() {
-  mojom::IsolatedXRGamepadProviderFactoryPtr ret;
-  gamepad_provider_factory_binding_.Bind(mojo::MakeRequest(&ret));
-  return ret;
+mojo::PendingRemote<mojom::IsolatedXRGamepadProviderFactory>
+OpenVRDevice::BindGamepadFactory() {
+  return gamepad_provider_factory_receiver_.BindNewPipeAndPassRemote();
 }
 
-mojom::XRCompositorHostPtr OpenVRDevice::BindCompositorHost() {
-  mojom::XRCompositorHostPtr ret;
-  compositor_host_binding_.Bind(mojo::MakeRequest(&ret));
-  return ret;
+mojo::PendingRemote<mojom::XRCompositorHost>
+OpenVRDevice::BindCompositorHost() {
+  return compositor_host_receiver_.BindNewPipeAndPassRemote();
 }
 
 OpenVRDevice::~OpenVRDevice() {
@@ -167,7 +163,7 @@
     mojom::XRRuntimeSessionOptionsPtr options,
     mojom::XRRuntime::RequestSessionCallback callback) {
   if (!EnsureValidDisplayInfo()) {
-    std::move(callback).Run(nullptr, nullptr);
+    std::move(callback).Run(nullptr, mojo::NullRemote());
     return;
   }
 
@@ -177,7 +173,7 @@
     render_loop_->Start();
 
     if (!render_loop_->IsRunning()) {
-      std::move(callback).Run(nullptr, nullptr);
+      std::move(callback).Run(nullptr, mojo::NullRemote());
       return;
     }
 
@@ -255,24 +251,23 @@
   outstanding_session_requests_count_--;
   if (!result) {
     OnPresentationEnded();
-    std::move(callback).Run(nullptr, nullptr);
+    std::move(callback).Run(nullptr, mojo::NullRemote());
     return;
   }
 
   OnStartPresenting();
 
-  mojom::XRSessionControllerPtr session_controller;
-  exclusive_controller_binding_.Bind(mojo::MakeRequest(&session_controller));
+  session->display_info = display_info_.Clone();
+
+  std::move(callback).Run(
+      std::move(session),
+      exclusive_controller_receiver_.BindNewPipeAndPassRemote());
 
   // Use of Unretained is safe because the callback will only occur if the
   // binding is not destroyed.
-  exclusive_controller_binding_.set_connection_error_handler(
+  exclusive_controller_receiver_.set_disconnect_handler(
       base::BindOnce(&OpenVRDevice::OnPresentingControllerMojoConnectionError,
                      base::Unretained(this)));
-
-  session->display_info = display_info_.Clone();
-
-  std::move(callback).Run(std::move(session), std::move(session_controller));
 }
 
 bool OpenVRDevice::IsAvailable() {
@@ -318,7 +313,7 @@
   // TODO(https://crbug.com/875187): Alternatively, we could recreate the
   // provider on the next session, or look into why the callback gets lost.
   OnExitPresent();
-  exclusive_controller_binding_.Close();
+  exclusive_controller_receiver_.reset();
 }
 
 // Only deal with events that will cause displayInfo changes for now.
diff --git a/device/vr/openvr/openvr_device.h b/device/vr/openvr/openvr_device.h
index 8485f2c8..3d02da8e 100644
--- a/device/vr/openvr/openvr_device.h
+++ b/device/vr/openvr/openvr_device.h
@@ -12,8 +12,9 @@
 #include "device/vr/openvr/openvr_api_wrapper.h"
 #include "device/vr/public/mojom/vr_service.mojom.h"
 #include "device/vr/vr_device_base.h"
-#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 
 namespace device {
 
@@ -48,8 +49,9 @@
 
   bool IsAvailable();
 
-  mojom::IsolatedXRGamepadProviderFactoryPtr BindGamepadFactory();
-  mojom::XRCompositorHostPtr BindCompositorHost();
+  mojo::PendingRemote<mojom::IsolatedXRGamepadProviderFactory>
+  BindGamepadFactory();
+  mojo::PendingRemote<mojom::XRCompositorHost> BindCompositorHost();
 
  private:
   // XRSessionController
@@ -74,13 +76,14 @@
   std::unique_ptr<OpenVRWrapper> openvr_;
   scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
 
-  mojo::Binding<mojom::XRSessionController> exclusive_controller_binding_;
+  mojo::Receiver<mojom::XRSessionController> exclusive_controller_receiver_{
+      this};
 
-  mojo::Binding<mojom::IsolatedXRGamepadProviderFactory>
-      gamepad_provider_factory_binding_;
+  mojo::Receiver<mojom::IsolatedXRGamepadProviderFactory>
+      gamepad_provider_factory_receiver_{this};
   mojo::PendingReceiver<mojom::IsolatedXRGamepadProvider> provider_receiver_;
 
-  mojo::Binding<mojom::XRCompositorHost> compositor_host_binding_;
+  mojo::Receiver<mojom::XRCompositorHost> compositor_host_receiver_{this};
   mojo::PendingReceiver<mojom::ImmersiveOverlay> overlay_receiver_;
 
   base::WeakPtrFactory<OpenVRDevice> weak_ptr_factory_{this};
diff --git a/device/vr/openxr/openxr_device.cc b/device/vr/openxr/openxr_device.cc
index 2d2c95d..edfa4dc9 100644
--- a/device/vr/openxr/openxr_device.cc
+++ b/device/vr/openxr/openxr_device.cc
@@ -10,6 +10,7 @@
 #include "device/vr/openxr/openxr_api_wrapper.h"
 #include "device/vr/openxr/openxr_render_loop.h"
 #include "device/vr/util/transform_utils.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 
 namespace device {
 
@@ -85,9 +86,6 @@
 
 OpenXrDevice::OpenXrDevice()
     : VRDeviceBase(device::mojom::XRDeviceId::OPENXR_DEVICE_ID),
-      exclusive_controller_binding_(this),
-      gamepad_provider_factory_binding_(this),
-      compositor_host_binding_(this),
       weak_ptr_factory_(this) {
   SetVRDisplayInfo(CreateFakeVRDisplayInfo(GetId()));
 }
@@ -101,16 +99,14 @@
   }
 }
 
-mojom::IsolatedXRGamepadProviderFactoryPtr OpenXrDevice::BindGamepadFactory() {
-  mojom::IsolatedXRGamepadProviderFactoryPtr ret;
-  gamepad_provider_factory_binding_.Bind(mojo::MakeRequest(&ret));
-  return ret;
+mojo::PendingRemote<mojom::IsolatedXRGamepadProviderFactory>
+OpenXrDevice::BindGamepadFactory() {
+  return gamepad_provider_factory_receiver_.BindNewPipeAndPassRemote();
 }
 
-mojom::XRCompositorHostPtr OpenXrDevice::BindCompositorHost() {
-  mojom::XRCompositorHostPtr ret;
-  compositor_host_binding_.Bind(mojo::MakeRequest(&ret));
-  return ret;
+mojo::PendingRemote<mojom::XRCompositorHost>
+OpenXrDevice::BindCompositorHost() {
+  return compositor_host_receiver_.BindNewPipeAndPassRemote();
 }
 
 void OpenXrDevice::EnsureRenderLoop() {
@@ -132,7 +128,7 @@
     render_loop_->Start();
 
     if (!render_loop_->IsRunning()) {
-      std::move(callback).Run(nullptr, nullptr);
+      std::move(callback).Run(nullptr, mojo::NullRemote());
       return;
     }
 
@@ -173,21 +169,12 @@
     bool result,
     mojom::XRSessionPtr session) {
   if (!result) {
-    std::move(callback).Run(nullptr, nullptr);
+    std::move(callback).Run(nullptr, mojo::NullRemote());
     return;
   }
 
   OnStartPresenting();
 
-  mojom::XRSessionControllerPtr session_controller;
-  exclusive_controller_binding_.Bind(mojo::MakeRequest(&session_controller));
-
-  // Use of Unretained is safe because the callback will only occur if the
-  // binding is not destroyed.
-  exclusive_controller_binding_.set_connection_error_handler(
-      base::BindOnce(&OpenXrDevice::OnPresentingControllerMojoConnectionError,
-                     base::Unretained(this)));
-
   EnsureRenderLoop();
   gfx::Size view_size = render_loop_->GetViewSize();
   display_info_->left_eye->render_width = view_size.width();
@@ -196,7 +183,15 @@
   display_info_->right_eye->render_height = view_size.height();
   session->display_info = display_info_.Clone();
 
-  std::move(callback).Run(std::move(session), std::move(session_controller));
+  std::move(callback).Run(
+      std::move(session),
+      exclusive_controller_receiver_.BindNewPipeAndPassRemote());
+
+  // Use of Unretained is safe because the callback will only occur if the
+  // binding is not destroyed.
+  exclusive_controller_receiver_.set_disconnect_handler(
+      base::BindOnce(&OpenXrDevice::OnPresentingControllerMojoConnectionError,
+                     base::Unretained(this)));
 }
 
 void OpenXrDevice::OnPresentingControllerMojoConnectionError() {
@@ -208,7 +203,7 @@
                                   base::Unretained(render_loop_.get())));
   }
   OnExitPresent();
-  exclusive_controller_binding_.Close();
+  exclusive_controller_receiver_.reset();
 }
 
 void OpenXrDevice::SetFrameDataRestricted(bool restricted) {
diff --git a/device/vr/openxr/openxr_device.h b/device/vr/openxr/openxr_device.h
index e96afea..c9fa1dd 100644
--- a/device/vr/openxr/openxr_device.h
+++ b/device/vr/openxr/openxr_device.h
@@ -11,6 +11,8 @@
 #include "device/vr/public/mojom/vr_service.mojom.h"
 #include "device/vr/vr_device_base.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 
 namespace device {
 
@@ -33,8 +35,9 @@
       mojom::XRRuntimeSessionOptionsPtr options,
       mojom::XRRuntime::RequestSessionCallback callback) override;
 
-  mojom::IsolatedXRGamepadProviderFactoryPtr BindGamepadFactory();
-  mojom::XRCompositorHostPtr BindCompositorHost();
+  mojo::PendingRemote<mojom::IsolatedXRGamepadProviderFactory>
+  BindGamepadFactory();
+  mojo::PendingRemote<mojom::XRCompositorHost> BindCompositorHost();
 
  private:
   // XRSessionController
@@ -58,13 +61,14 @@
 
   std::unique_ptr<OpenXrRenderLoop> render_loop_;
 
-  mojo::Binding<mojom::XRSessionController> exclusive_controller_binding_;
+  mojo::Receiver<mojom::XRSessionController> exclusive_controller_receiver_{
+      this};
 
-  mojo::Binding<mojom::IsolatedXRGamepadProviderFactory>
-      gamepad_provider_factory_binding_;
+  mojo::Receiver<mojom::IsolatedXRGamepadProviderFactory>
+      gamepad_provider_factory_receiver_{this};
   mojo::PendingReceiver<mojom::IsolatedXRGamepadProvider> provider_receiver_;
 
-  mojo::Binding<mojom::XRCompositorHost> compositor_host_binding_;
+  mojo::Receiver<mojom::XRCompositorHost> compositor_host_receiver_{this};
   mojo::PendingReceiver<mojom::ImmersiveOverlay> overlay_receiver_;
 
   base::WeakPtrFactory<OpenXrDevice> weak_ptr_factory_;
diff --git a/device/vr/orientation/orientation_device.cc b/device/vr/orientation/orientation_device.cc
index adb343cc..fe4b2bd 100644
--- a/device/vr/orientation/orientation_device.cc
+++ b/device/vr/orientation/orientation_device.cc
@@ -138,10 +138,10 @@
   // available when RequestSession is called for non-immersive sessions.
 
   mojo::PendingRemote<mojom::XRFrameDataProvider> data_provider;
-  mojom::XRSessionControllerPtr controller;
+  mojo::PendingRemote<mojom::XRSessionController> controller;
   magic_window_sessions_.push_back(std::make_unique<VROrientationSession>(
       this, data_provider.InitWithNewPipeAndPassReceiver(),
-      mojo::MakeRequest(&controller)));
+      controller.InitWithNewPipeAndPassReceiver()));
 
   auto session = mojom::XRSession::New();
   session->data_provider = std::move(data_provider);
diff --git a/device/vr/orientation/orientation_device_unittest.cc b/device/vr/orientation/orientation_device_unittest.cc
index 0972195..9f8ce7a 100644
--- a/device/vr/orientation/orientation_device_unittest.cc
+++ b/device/vr/orientation/orientation_device_unittest.cc
@@ -164,10 +164,10 @@
 
   std::unique_ptr<VROrientationSession> MakeDisplay() {
     mojo::PendingRemote<mojom::XRFrameDataProvider> data_provider;
-    mojom::XRSessionControllerPtr controller;
+    mojo::PendingRemote<mojom::XRSessionController> controller;
     return std::make_unique<VROrientationSession>(
         device_.get(), data_provider.InitWithNewPipeAndPassReceiver(),
-        mojo::MakeRequest(&controller));
+        controller.InitWithNewPipeAndPassReceiver());
   }
 
   void TryGetFrameData(VROrientationSession* display, bool expect_null) {
diff --git a/device/vr/orientation/orientation_session.cc b/device/vr/orientation/orientation_session.cc
index 11c12869..05a7ade 100644
--- a/device/vr/orientation/orientation_session.cc
+++ b/device/vr/orientation/orientation_session.cc
@@ -14,13 +14,13 @@
 VROrientationSession::VROrientationSession(
     VROrientationDevice* device,
     mojo::PendingReceiver<mojom::XRFrameDataProvider> magic_window_receiver,
-    mojom::XRSessionControllerRequest session_request)
+    mojo::PendingReceiver<mojom::XRSessionController> session_receiver)
     : magic_window_receiver_(this, std::move(magic_window_receiver)),
-      session_controller_binding_(this, std::move(session_request)),
+      session_controller_receiver_(this, std::move(session_receiver)),
       device_(device) {
-  // Unretained is safe because the binding will close when we are destroyed,
+  // Unretained is safe because the receiver will close when we are destroyed,
   // so we won't receive any more callbacks after that.
-  session_controller_binding_.set_connection_error_handler(base::BindOnce(
+  session_controller_receiver_.set_disconnect_handler(base::BindOnce(
       &VROrientationSession::OnMojoConnectionError, base::Unretained(this)));
 }
 
@@ -63,7 +63,7 @@
 
 void VROrientationSession::OnMojoConnectionError() {
   magic_window_receiver_.reset();
-  session_controller_binding_.Close();
+  session_controller_receiver_.reset();
   device_->EndMagicWindowSession(this);  // This call will destroy us.
 }
 
diff --git a/device/vr/orientation/orientation_session.h b/device/vr/orientation/orientation_session.h
index 9be17c0..c5a822f 100644
--- a/device/vr/orientation/orientation_session.h
+++ b/device/vr/orientation/orientation_session.h
@@ -14,7 +14,6 @@
 #include "device/vr/vr_device.h"
 #include "device/vr/vr_export.h"
 #include "mojo/public/cpp/bindings/associated_binding.h"
-#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "ui/display/display.h"
@@ -33,7 +32,7 @@
  public:
   VROrientationSession(VROrientationDevice* device,
                        mojo::PendingReceiver<mojom::XRFrameDataProvider>,
-                       mojom::XRSessionControllerRequest);
+                       mojo::PendingReceiver<mojom::XRSessionController>);
   ~VROrientationSession() override;
 
   void GetEnvironmentIntegrationProvider(
@@ -54,7 +53,7 @@
   void OnMojoConnectionError();
 
   mojo::Receiver<mojom::XRFrameDataProvider> magic_window_receiver_;
-  mojo::Binding<mojom::XRSessionController> session_controller_binding_;
+  mojo::Receiver<mojom::XRSessionController> session_controller_receiver_;
   device::VROrientationDevice* device_;
   bool restrict_frame_data_ = true;
 };
diff --git a/device/vr/public/mojom/isolated_xr_service.mojom b/device/vr/public/mojom/isolated_xr_service.mojom
index bd5d9b7..76637db 100644
--- a/device/vr/public/mojom/isolated_xr_service.mojom
+++ b/device/vr/public/mojom/isolated_xr_service.mojom
@@ -73,7 +73,7 @@
   // the browser process.
   RequestSession(XRRuntimeSessionOptions options) => (
                      XRSession? session,
-                     XRSessionController? controller);
+                     pending_remote<XRSessionController>? controller);
 
   // The browser may register for changes to a device. Initial VRDisplayInfo
   // will immediately be returned to the listener to prevent races.
@@ -198,8 +198,8 @@
   // Called when runtimes are initially enumerated, or when devices are later
   // attached and become available.
   OnDeviceAdded(XRRuntime runtime,
-      IsolatedXRGamepadProviderFactory gamepad_factory,
-      XRCompositorHost compositor_host,
+      pending_remote<IsolatedXRGamepadProviderFactory> gamepad_factory,
+      pending_remote<XRCompositorHost> compositor_host,
       device.mojom.XRDeviceId device_id);
 
   // Called when runtimes become unavailable - for example if the hardware is
diff --git a/device/vr/test/fake_vr_device.cc b/device/vr/test/fake_vr_device.cc
index 9567c1c..bed7141 100644
--- a/device/vr/test/fake_vr_device.cc
+++ b/device/vr/test/fake_vr_device.cc
@@ -4,12 +4,12 @@
 
 #include "device/vr/test/fake_vr_device.h"
 
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "ui/gfx/transform_util.h"
 
 namespace device {
 
-FakeVRDevice::FakeVRDevice(mojom::XRDeviceId id)
-    : VRDeviceBase(id), controller_binding_(this) {
+FakeVRDevice::FakeVRDevice(mojom::XRDeviceId id) : VRDeviceBase(id) {
   SetVRDisplayInfo(InitBasicDevice());
 }
 
@@ -57,12 +57,11 @@
   OnStartPresenting();
   // The current tests never use the return values, so it's fine to return
   // invalid data here.
-  std::move(callback).Run(nullptr, nullptr);
+  std::move(callback).Run(nullptr, mojo::NullRemote());
 }
 
 void FakeVRDevice::OnPresentingControllerMojoConnectionError() {
   OnExitPresent();
-  controller_binding_.Close();
 }
 
 }  // namespace device
diff --git a/device/vr/test/fake_vr_device.h b/device/vr/test/fake_vr_device.h
index e519b8a..28aadbe2 100644
--- a/device/vr/test/fake_vr_device.h
+++ b/device/vr/test/fake_vr_device.h
@@ -39,8 +39,6 @@
 
   mojom::VRPosePtr pose_;
 
-  mojo::Binding<mojom::XRSessionController> controller_binding_;
-
   DISALLOW_COPY_AND_ASSIGN(FakeVRDevice);
 };
 
diff --git a/device/vr/windows_mixed_reality/mixed_reality_device.cc b/device/vr/windows_mixed_reality/mixed_reality_device.cc
index 14ec664..75a546d 100644
--- a/device/vr/windows_mixed_reality/mixed_reality_device.cc
+++ b/device/vr/windows_mixed_reality/mixed_reality_device.cc
@@ -15,6 +15,7 @@
 #include "build/build_config.h"
 #include "device/vr/util/transform_utils.h"
 #include "device/vr/windows_mixed_reality/mixed_reality_renderloop.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "ui/gfx/geometry/angle_conversions.h"
 
 namespace device {
@@ -61,10 +62,7 @@
 }  // namespace
 
 MixedRealityDevice::MixedRealityDevice()
-    : VRDeviceBase(device::mojom::XRDeviceId::WINDOWS_MIXED_REALITY_ID),
-      gamepad_provider_factory_binding_(this),
-      compositor_host_binding_(this),
-      exclusive_controller_binding_(this) {
+    : VRDeviceBase(device::mojom::XRDeviceId::WINDOWS_MIXED_REALITY_ID) {
   SetVRDisplayInfo(CreateFakeVRDisplayInfo(GetId()));
 }
 
@@ -72,17 +70,14 @@
   Shutdown();
 }
 
-mojom::IsolatedXRGamepadProviderFactoryPtr
+mojo::PendingRemote<mojom::IsolatedXRGamepadProviderFactory>
 MixedRealityDevice::BindGamepadFactory() {
-  mojom::IsolatedXRGamepadProviderFactoryPtr ret;
-  gamepad_provider_factory_binding_.Bind(mojo::MakeRequest(&ret));
-  return ret;
+  return gamepad_provider_factory_receiver_.BindNewPipeAndPassRemote();
 }
 
-mojom::XRCompositorHostPtr MixedRealityDevice::BindCompositorHost() {
-  mojom::XRCompositorHostPtr ret;
-  compositor_host_binding_.Bind(mojo::MakeRequest(&ret));
-  return ret;
+mojo::PendingRemote<mojom::XRCompositorHost>
+MixedRealityDevice::BindCompositorHost() {
+  return compositor_host_receiver_.BindNewPipeAndPassRemote();
 }
 
 void MixedRealityDevice::RequestSession(
@@ -104,7 +99,7 @@
     // memory exhaustion). If the thread fails to start, then we fail to create
     // a session.
     if (!render_loop_->IsRunning()) {
-      std::move(callback).Run(nullptr, nullptr);
+      std::move(callback).Run(nullptr, mojo::NullRemote());
       return;
     }
 
@@ -163,24 +158,22 @@
     mojom::XRSessionPtr session) {
   if (!result) {
     OnPresentationEnded();
-    std::move(callback).Run(nullptr, nullptr);
+    std::move(callback).Run(nullptr, mojo::NullRemote());
     return;
   }
 
   OnStartPresenting();
 
-  mojom::XRSessionControllerPtr session_controller;
-  exclusive_controller_binding_.Bind(mojo::MakeRequest(&session_controller));
+  session->display_info = display_info_.Clone();
+  std::move(callback).Run(
+      std::move(session),
+      exclusive_controller_receiver_.BindNewPipeAndPassRemote());
 
   // Use of Unretained is safe because the callback will only occur if the
   // binding is not destroyed.
-  exclusive_controller_binding_.set_connection_error_handler(base::BindOnce(
+  exclusive_controller_receiver_.set_disconnect_handler(base::BindOnce(
       &MixedRealityDevice::OnPresentingControllerMojoConnectionError,
       base::Unretained(this)));
-
-  session->display_info = display_info_.Clone();
-
-  std::move(callback).Run(std::move(session), std::move(session_controller));
 }
 
 void MixedRealityDevice::GetIsolatedXRGamepadProvider(
@@ -228,7 +221,7 @@
   // TODO(https://crbug.com/875187): Alternatively, we could recreate the
   // provider on the next session, or look into why the callback gets lost.
   OnExitPresent();
-  exclusive_controller_binding_.Close();
+  exclusive_controller_receiver_.reset();
 }
 
 }  // namespace device
diff --git a/device/vr/windows_mixed_reality/mixed_reality_device.h b/device/vr/windows_mixed_reality/mixed_reality_device.h
index fd9183a6..234dc24 100644
--- a/device/vr/windows_mixed_reality/mixed_reality_device.h
+++ b/device/vr/windows_mixed_reality/mixed_reality_device.h
@@ -13,8 +13,9 @@
 #include "device/vr/public/mojom/vr_service.mojom.h"
 #include "device/vr/vr_device_base.h"
 #include "device/vr/windows/compositor_base.h"
-#include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver.h"
 
 namespace device {
 
@@ -27,8 +28,9 @@
   MixedRealityDevice();
   ~MixedRealityDevice() override;
 
-  mojom::IsolatedXRGamepadProviderFactoryPtr BindGamepadFactory();
-  mojom::XRCompositorHostPtr BindCompositorHost();
+  mojo::PendingRemote<mojom::IsolatedXRGamepadProviderFactory>
+  BindGamepadFactory();
+  mojo::PendingRemote<mojom::XRCompositorHost> BindCompositorHost();
 
  private:
   // VRDeviceBase
@@ -58,14 +60,15 @@
 
   std::unique_ptr<XRCompositorCommon> render_loop_;
 
-  mojo::Binding<mojom::IsolatedXRGamepadProviderFactory>
-      gamepad_provider_factory_binding_;
+  mojo::Receiver<mojom::IsolatedXRGamepadProviderFactory>
+      gamepad_provider_factory_receiver_{this};
   mojo::PendingReceiver<mojom::IsolatedXRGamepadProvider> provider_receiver_;
 
-  mojo::Binding<mojom::XRCompositorHost> compositor_host_binding_;
+  mojo::Receiver<mojom::XRCompositorHost> compositor_host_receiver_{this};
   mojo::PendingReceiver<mojom::ImmersiveOverlay> overlay_receiver_;
 
-  mojo::Binding<mojom::XRSessionController> exclusive_controller_binding_;
+  mojo::Receiver<mojom::XRSessionController> exclusive_controller_receiver_{
+      this};
 
   base::WeakPtrFactory<MixedRealityDevice> weak_ptr_factory_{this};
 
diff --git a/docs/native_relocations.md b/docs/native_relocations.md
new file mode 100644
index 0000000..0910e6f9
--- /dev/null
+++ b/docs/native_relocations.md
@@ -0,0 +1,85 @@
+# Native Relocations
+
+*** note
+Information here is mostly Android & Linux-specific and may not be 100% accurate.
+***
+
+## What are they?
+ * For ELF files, they are sections of type REL, RELA, or RELR. They generally
+   have the name ".rel.dyn" and ".rel.plt".
+ * They tell the runtime linker a list of addresses to post-process after
+   loading the executable into memory.
+ * There are several types of relocations, but >99% of them are "relative"
+   relocations and are created any time a global variable or constant is
+   initialized with the address of something.
+   * This includes vtables, function pointers, and string literals, but not
+     `char[]`.
+ * Each relocation is stored as either 2 or 3 words, based on the architecture.
+   * On Android, they are compressed, which trades off runtime performance for
+     smaller file size.
+ * As of Oct 2019, Chrome on Android has about 390000 of them.
+   * Windows and Mac have them as well, but I don't know how they differ.
+
+## Why do they matter?
+ * **Binary Size:** Except on Android, relocations are stored very
+   inefficiently.
+   * Chrome on Linux has a `.rela.dyn` section of more than 14MiB!
+   * Android uses a [custom compression scheme][android_relro1] to shrink them
+     down to ~300kb.
+   * There is an even better [RELR][RELR] encoding available on Android P+, but
+     not widely available on Linux yet. It makes relocations ~60kb.
+ * **Memory Overhead:** Symbols with relocations cannot be loaded read-only
+   and result in "dirty" memory. 99% of these symbols live in `.data.rel.ro`,
+   which as of Oct 2019 is ~6.5MiB on Linux and ~2MiB on Android.
+   `.data.rel.ro` is data that *would* have been put into `.rodata` and mapped
+   read-only if not for the required relocations. It does not get written to
+   after it's relocated, so the linker makes it read-only once relocations are
+   applied (but by that point the damage is done and we have the dirty pages).
+   * On Linux, we share this overhead between processes via the [zygote].
+   * [On Android][android_relro2], we share this overhead between processes by
+     loading the shared library at the same address in all processes, and then
+     `mremap` onto shared memory to dedupe after-the-fact.
+ * **Start-up Time** The runtime linker applies relocations when loading the
+   executable. On low-end Android, it can take ~100ms (measured on a first-gen
+   Android Go devices with APS2 relocations). On Linux, it's
+   [closer to 20ms][zygote].
+
+[zygote]: linux_zygote.md
+[RELR]: https://reviews.llvm.org/D48247
+[android_relro1]: android_native_libraries.md#Packed-Relocations
+[android_relro2]: android_native_libraries.md#relro-sharing
+
+## How do I see them?
+
+```sh
+third_party/llvm-build/Release+Asserts/bin/llvm-readelf --relocs out/Release/libmonochrome.so
+```
+
+## Can I avoid them?
+It's not practical to avoid them altogether, but there are times when you can be
+smart about them.
+
+For Example:
+```c++
+// Wastes 2 bytes for each smaller string but creates no relocations.
+// Total size overhead: 4 * 5 = 20 bytes.
+const char kArr[][5] = {"as", "ab", "asdf", "fi"};
+
+// String data stored optimally, but uses 4 relocatable pointers.
+// Total size overhead:
+//   64-bit: 8 bytes per pointer + 24 bytes per relocation + 14 bytes of char = 142 bytes
+//   32-bit: 4 bytes per pointer + 8 bytes per relocation + 14 bytes of char = 62 bytes
+const char *kArr2[] = {"as", "ab", "asdf", "fi"};
+```
+
+Note:
+* String literals are de-duped with others in the binary, so it's possible that
+  the second example above might use 14 fewer bytes.
+* Not all string literals require relocations. Only those that are stored into
+  global variables require them.
+
+Another thing to look out for:
+ * Large data structures with relocations that you don't need random access to,
+   or which are seldom needed.
+   * For such cases, it might be better to store the data encoded and then
+     decode when required.
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
index 62f4e94..486fa90 100644
--- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
+++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.cc
@@ -861,7 +861,7 @@
     int render_process_id,
     scoped_refptr<WebRequestAPI::RequestIDGenerator> request_id_generator,
     std::unique_ptr<ExtensionNavigationUIData> navigation_ui_data,
-    network::mojom::URLLoaderFactoryRequest loader_request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
     network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
     mojo::PendingReceiver<network::mojom::TrustedURLLoaderHeaderClient>
         header_client_receiver,
@@ -886,8 +886,8 @@
   target_factory_.set_connection_error_handler(
       base::BindOnce(&WebRequestProxyingURLLoaderFactory::OnTargetFactoryError,
                      base::Unretained(this)));
-  proxy_bindings_.AddBinding(this, std::move(loader_request));
-  proxy_bindings_.set_connection_error_handler(base::BindRepeating(
+  proxy_receivers_.Add(this, std::move(loader_receiver));
+  proxy_receivers_.set_disconnect_handler(base::BindRepeating(
       &WebRequestProxyingURLLoaderFactory::OnProxyBindingError,
       base::Unretained(this)));
 
@@ -900,7 +900,7 @@
     int render_process_id,
     scoped_refptr<WebRequestAPI::RequestIDGenerator> request_id_generator,
     std::unique_ptr<ExtensionNavigationUIData> navigation_ui_data,
-    network::mojom::URLLoaderFactoryRequest loader_request,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
     network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
     mojo::PendingReceiver<network::mojom::TrustedURLLoaderHeaderClient>
         header_client_receiver,
@@ -910,7 +910,7 @@
 
   auto proxy = std::make_unique<WebRequestProxyingURLLoaderFactory>(
       browser_context, render_process_id, std::move(request_id_generator),
-      std::move(navigation_ui_data), std::move(loader_request),
+      std::move(navigation_ui_data), std::move(loader_receiver),
       std::move(target_factory_info), std::move(header_client_receiver),
       proxies, loader_factory_type);
 
@@ -957,9 +957,9 @@
 }
 
 void WebRequestProxyingURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest loader_request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  proxy_bindings_.AddBinding(this, std::move(loader_request));
+  proxy_receivers_.Add(this, std::move(loader_receiver));
 }
 
 void WebRequestProxyingURLLoaderFactory::OnLoaderCreated(
@@ -999,14 +999,14 @@
 void WebRequestProxyingURLLoaderFactory::OnTargetFactoryError() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   target_factory_.reset();
-  proxy_bindings_.CloseAllBindings();
+  proxy_receivers_.Clear();
 
   MaybeRemoveProxy();
 }
 
 void WebRequestProxyingURLLoaderFactory::OnProxyBindingError() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-  if (proxy_bindings_.empty())
+  if (proxy_receivers_.empty())
     target_factory_.reset();
 
   MaybeRemoveProxy();
diff --git a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
index 5c4593e..a2614d79 100644
--- a/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
+++ b/extensions/browser/api/web_request/web_request_proxying_url_loader_factory.h
@@ -18,8 +18,10 @@
 #include "content/public/browser/content_browser_client.h"
 #include "extensions/browser/api/web_request/web_request_api.h"
 #include "extensions/browser/api/web_request/web_request_info.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "net/base/completion_once_callback.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/cpp/resource_request.h"
@@ -188,7 +190,7 @@
       int render_process_id,
       scoped_refptr<WebRequestAPI::RequestIDGenerator> request_id_generator,
       std::unique_ptr<ExtensionNavigationUIData> navigation_ui_data,
-      network::mojom::URLLoaderFactoryRequest loader_request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
       network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
       mojo::PendingReceiver<network::mojom::TrustedURLLoaderHeaderClient>
           header_client_receiver,
@@ -202,7 +204,7 @@
       int render_process_id,
       scoped_refptr<WebRequestAPI::RequestIDGenerator> request_id_generator,
       std::unique_ptr<ExtensionNavigationUIData> navigation_ui_data,
-      network::mojom::URLLoaderFactoryRequest loader_request,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader_receiver,
       network::mojom::URLLoaderFactoryPtrInfo target_factory_info,
       mojo::PendingReceiver<network::mojom::TrustedURLLoaderHeaderClient>
           header_client_receiver,
@@ -218,7 +220,8 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest loader_request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+                 loader_receiver) override;
 
   // network::mojom::TrustedURLLoaderHeaderClient:
   void OnLoaderCreated(
@@ -251,7 +254,7 @@
   const int render_process_id_;
   scoped_refptr<WebRequestAPI::RequestIDGenerator> request_id_generator_;
   std::unique_ptr<ExtensionNavigationUIData> navigation_ui_data_;
-  mojo::BindingSet<network::mojom::URLLoaderFactory> proxy_bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> proxy_receivers_;
   network::mojom::URLLoaderFactoryPtr target_factory_;
   mojo::Receiver<network::mojom::TrustedURLLoaderHeaderClient>
       url_loader_header_client_receiver_{this};
diff --git a/extensions/browser/content_verifier.cc b/extensions/browser/content_verifier.cc
index 1f1ab63..536a623 100644
--- a/extensions/browser/content_verifier.cc
+++ b/extensions/browser/content_verifier.cc
@@ -614,7 +614,7 @@
   network::mojom::URLLoaderFactoryPtr url_loader_factory_ptr;
   base::PostTask(
       FROM_HERE, {content::BrowserThread::UI},
-      base::BindOnce(&ContentVerifier::BindURLLoaderFactoryRequestOnUIThread,
+      base::BindOnce(&ContentVerifier::BindURLLoaderFactoryReceiverOnUIThread,
                      this, mojo::MakeRequest(&url_loader_factory_ptr)));
   network::mojom::URLLoaderFactoryPtrInfo url_loader_factory_info =
       url_loader_factory_ptr.PassInterface();
@@ -633,15 +633,16 @@
   std::move(original_callback).Run(content_hash);
 }
 
-void ContentVerifier::BindURLLoaderFactoryRequestOnUIThread(
-    network::mojom::URLLoaderFactoryRequest url_loader_factory_request) {
+void ContentVerifier::BindURLLoaderFactoryReceiverOnUIThread(
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+        url_loader_factory_receiver) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   if (shutdown_on_ui_)
     return;
 
   content::BrowserContext::GetDefaultStoragePartition(context_)
       ->GetURLLoaderFactoryForBrowserProcess()
-      ->Clone(std::move(url_loader_factory_request));
+      ->Clone(std::move(url_loader_factory_receiver));
 }
 
 bool ContentVerifier::ShouldVerifyAnyPaths(
diff --git a/extensions/browser/content_verifier.h b/extensions/browser/content_verifier.h
index 368c2bb..bec90db01 100644
--- a/extensions/browser/content_verifier.h
+++ b/extensions/browser/content_verifier.h
@@ -21,6 +21,7 @@
 #include "extensions/browser/content_verify_job.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_registry_observer.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
 namespace base {
@@ -126,9 +127,10 @@
                          ContentHashCallback orig_callback,
                          scoped_refptr<const ContentHash> content_hash);
 
-  // Binds an URLLoaderFactoryRequest on the UI thread.
-  void BindURLLoaderFactoryRequestOnUIThread(
-      network::mojom::URLLoaderFactoryRequest url_loader_factory_request);
+  // Binds an URLLoaderFactoryReceiver on the UI thread.
+  void BindURLLoaderFactoryReceiverOnUIThread(
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory>
+          url_loader_factory_receiver);
 
   // Performs IO thread operations after extension load.
   void OnExtensionLoadedOnIO(
diff --git a/extensions/browser/extension_protocols.cc b/extensions/browser/extension_protocols.cc
index 3eab2376..a733b31 100644
--- a/extensions/browser/extension_protocols.cc
+++ b/extensions/browser/extension_protocols.cc
@@ -68,7 +68,8 @@
 #include "extensions/common/manifest_handlers/incognito_info.h"
 #include "extensions/common/manifest_handlers/shared_module_info.h"
 #include "extensions/common/manifest_handlers/web_accessible_resources_info.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "net/base/filename_util.h"
 #include "net/base/io_buffer.h"
 #include "net/base/mime_util.h"
@@ -433,8 +434,9 @@
                   std::move(directory_path));
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
-    bindings_.AddBinding(this, std::move(request));
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
+    receivers_.Add(this, std::move(receiver));
   }
 
  private:
@@ -603,7 +605,7 @@
   // the objects.
   const int render_process_id_;
   scoped_refptr<extensions::InfoMap> extension_info_map_;
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   DISALLOW_COPY_AND_ASSIGN(ExtensionURLLoaderFactory);
 };
diff --git a/fuchsia/engine/browser/content_directory_loader_factory.cc b/fuchsia/engine/browser/content_directory_loader_factory.cc
index 6a3511e..ea8fb0c 100644
--- a/fuchsia/engine/browser/content_directory_loader_factory.cc
+++ b/fuchsia/engine/browser/content_directory_loader_factory.cc
@@ -368,8 +368,8 @@
 }
 
 void ContentDirectoryLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest loader) {
-  bindings_.AddBinding(this, std::move(loader));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) {
+  receivers_.Add(this, std::move(loader));
 }
 
 void ContentDirectoryLoaderFactory::SetContentDirectoriesForTest(
diff --git a/fuchsia/engine/browser/content_directory_loader_factory.h b/fuchsia/engine/browser/content_directory_loader_factory.h
index c5257c2..378f000 100644
--- a/fuchsia/engine/browser/content_directory_loader_factory.h
+++ b/fuchsia/engine/browser/content_directory_loader_factory.h
@@ -13,7 +13,8 @@
 #include <vector>
 
 #include "fuchsia/engine/web_engine_export.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 
 // Creates a URLLoaderFactory which services requests for resources stored
@@ -38,7 +39,8 @@
       const network::ResourceRequest& request,
       network::mojom::URLLoaderClientPtr client,
       const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) final;
-  void Clone(network::mojom::URLLoaderFactoryRequest loader) final;
+  void Clone(
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> loader) final;
 
  private:
   net::Error OpenFileFromDirectory(
@@ -49,7 +51,7 @@
   // Used for executing blocking URLLoader routines.
   const scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   DISALLOW_COPY_AND_ASSIGN(ContentDirectoryLoaderFactory);
 };
diff --git a/gpu/command_buffer/common/skia_utils.cc b/gpu/command_buffer/common/skia_utils.cc
index 98b036f..e5cbb0b86f 100644
--- a/gpu/command_buffer/common/skia_utils.cc
+++ b/gpu/command_buffer/common/skia_utils.cc
@@ -134,7 +134,12 @@
     size_t* max_resource_cache_bytes,
     size_t* max_glyph_cache_texture_bytes) {
   // Default limits.
+#if defined(OS_FUCHSIA)
+  // Reduce protected budget on fuchsia due to https://fxb/36620.
+  constexpr size_t kMaxGaneshResourceCacheBytes = 24 * 1024 * 1024;
+#else
   constexpr size_t kMaxGaneshResourceCacheBytes = 96 * 1024 * 1024;
+#endif  // defined(OS_FUCHSIA)
   constexpr size_t kMaxDefaultGlyphCacheTextureBytes = 2048 * 1024 * 4;
 
   *max_resource_cache_bytes = kMaxGaneshResourceCacheBytes;
@@ -144,7 +149,12 @@
 #if !defined(OS_NACL)
   // The limit of the bytes allocated toward GPU resources in the GrContext's
   // GPU cache.
+#if defined(OS_FUCHSIA)
+  // Reduce protected budget on fuchsia due to https://fxb/36620.
+  constexpr size_t kMaxLowEndGaneshResourceCacheBytes = 24 * 1024 * 1024;
+#else
   constexpr size_t kMaxLowEndGaneshResourceCacheBytes = 48 * 1024 * 1024;
+#endif  // defined(OS_FUCHSIA)
   constexpr size_t kMaxHighEndGaneshResourceCacheBytes = 256 * 1024 * 1024;
   // Limits for glyph cache textures.
   constexpr size_t kMaxLowEndGlyphCacheTextureBytes = 1024 * 512 * 4;
diff --git a/headless/test/test_network_interceptor.cc b/headless/test/test_network_interceptor.cc
index 30f5df5..a045792 100644
--- a/headless/test/test_network_interceptor.cc
+++ b/headless/test/test_network_interceptor.cc
@@ -8,6 +8,7 @@
 #include "base/task/post_task.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
+#include "mojo/public/cpp/bindings/binding.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_util.h"
 #include "net/url_request/redirect_util.h"
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.h b/ios/chrome/browser/sync/ios_chrome_sync_client.h
index 1033746..9be5147c 100644
--- a/ios/chrome/browser/sync/ios_chrome_sync_client.h
+++ b/ios/chrome/browser/sync/ios_chrome_sync_client.h
@@ -49,6 +49,7 @@
   syncer::DataTypeController::TypeVector CreateDataTypeControllers(
       syncer::SyncService* sync_service) override;
   invalidation::InvalidationService* GetInvalidationService() override;
+  syncer::TrustedVaultClient* GetTrustedVaultClient() override;
   BookmarkUndoService* GetBookmarkUndoService() override;
   scoped_refptr<syncer::ExtensionsActivity> GetExtensionsActivity() override;
   base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType(
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.mm b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
index bac4d98..96cc4de 100644
--- a/ios/chrome/browser/sync/ios_chrome_sync_client.mm
+++ b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
@@ -190,6 +190,12 @@
   return nullptr;
 }
 
+syncer::TrustedVaultClient* IOSChromeSyncClient::GetTrustedVaultClient() {
+  // TODO(crbug.com/1012660): Instantiate a generic client for ios.
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
 scoped_refptr<syncer::ExtensionsActivity>
 IOSChromeSyncClient::GetExtensionsActivity() {
   return nullptr;
diff --git a/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc b/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc
index 76589dd..dd246bb 100644
--- a/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc
+++ b/ios/chrome/browser/sync/profile_sync_service_factory_unittest.cc
@@ -43,7 +43,7 @@
  protected:
   // Returns the collection of default datatypes.
   std::vector<syncer::ModelType> DefaultDatatypes() {
-    static_assert(42 == syncer::ModelType::NUM_ENTRIES,
+    static_assert(39 == syncer::ModelType::NUM_ENTRIES,
                   "When adding a new type, you probably want to add it here as "
                   "well (assuming it is already enabled).");
 
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/all_password_coordinator.mm b/ios/chrome/browser/ui/autofill/manual_fill/all_password_coordinator.mm
index 9498d9c..2b942bf4 100644
--- a/ios/chrome/browser/ui/autofill/manual_fill/all_password_coordinator.mm
+++ b/ios/chrome/browser/ui/autofill/manual_fill/all_password_coordinator.mm
@@ -75,8 +75,9 @@
 }
 
 - (void)stop {
-  [self.passwordViewController dismissViewControllerAnimated:YES
-                                                  completion:nil];
+  [self.passwordViewController.presentingViewController
+      dismissViewControllerAnimated:YES
+                         completion:nil];
   self.passwordViewController = nil;
   self.passwordMediator = nil;
   [super stop];
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm
index 5c54f98..4fbfc1bf 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm
@@ -304,8 +304,15 @@
 
   CGFloat percent =
       [self searchFieldProgressForOffset:offset safeAreaInsets:safeAreaInsets];
+
   if (!IsSplitToolbarMode(self)) {
-    self.alpha = 1 - percent;
+    // When Voiceover is running, if the header's alpha is set to 0, voiceover
+    // can't scroll back to it, and it will never come back into view. To
+    // prevent that, set the alpha to non-zero when the header is fully
+    // offscreen. It will still not be seen, but it will be accessible to
+    // Voiceover.
+    self.alpha = std::max(1 - percent, 0.01);
+
     widthConstraint.constant = searchFieldNormalWidth;
     self.fakeLocationBarHeightConstraint.constant = ToolbarHeight();
     self.fakeLocationBar.layer.cornerRadius =
diff --git a/ios/chrome/browser/ui/ui_feature_flags.cc b/ios/chrome/browser/ui/ui_feature_flags.cc
index edfba15..95275988 100644
--- a/ios/chrome/browser/ui/ui_feature_flags.cc
+++ b/ios/chrome/browser/ui/ui_feature_flags.cc
@@ -29,7 +29,7 @@
     "OmniboxUseDefaultSearchEngineFavicon", base::FEATURE_DISABLED_BY_DEFAULT};
 
 const base::Feature kLanguageSettings{"LanguageSettings",
-                                      base::FEATURE_DISABLED_BY_DEFAULT};
+                                      base::FEATURE_ENABLED_BY_DEFAULT};
 
 const base::Feature kOptionalArticleThumbnail{"OptionalArticleThumbnail",
                                               base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/webui/sync_internals/BUILD.gn b/ios/chrome/browser/ui/webui/sync_internals/BUILD.gn
index 1fb9f69..67b18a2 100644
--- a/ios/chrome/browser/ui/webui/sync_internals/BUILD.gn
+++ b/ios/chrome/browser/ui/webui/sync_internals/BUILD.gn
@@ -14,6 +14,7 @@
     "//components/browser_sync",
     "//components/resources",
     "//components/sync",
+    "//components/sync/driver:resources",
     "//ios/chrome/browser",
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/signin",
diff --git a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc
index 92afd10..1036f667 100644
--- a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc
+++ b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc
@@ -6,7 +6,7 @@
 
 #include <memory>
 
-#include "components/grit/components_resources.h"
+#include "components/grit/sync_driver_resources.h"
 #include "components/sync/driver/about_sync_util.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #include "ios/chrome/browser/chrome_url_constants.h"
diff --git a/ios/web_view/internal/sync/web_view_sync_client.h b/ios/web_view/internal/sync/web_view_sync_client.h
index f6a9b11..9fc0a37 100644
--- a/ios/web_view/internal/sync/web_view_sync_client.h
+++ b/ios/web_view/internal/sync/web_view_sync_client.h
@@ -52,6 +52,7 @@
   syncer::DataTypeController::TypeVector CreateDataTypeControllers(
       syncer::SyncService* sync_service) override;
   invalidation::InvalidationService* GetInvalidationService() override;
+  syncer::TrustedVaultClient* GetTrustedVaultClient() override;
   BookmarkUndoService* GetBookmarkUndoService() override;
   scoped_refptr<syncer::ExtensionsActivity> GetExtensionsActivity() override;
   base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType(
diff --git a/ios/web_view/internal/sync/web_view_sync_client.mm b/ios/web_view/internal/sync/web_view_sync_client.mm
index f16d60a..4aa731a 100644
--- a/ios/web_view/internal/sync/web_view_sync_client.mm
+++ b/ios/web_view/internal/sync/web_view_sync_client.mm
@@ -161,6 +161,10 @@
   return nullptr;
 }
 
+syncer::TrustedVaultClient* WebViewSyncClient::GetTrustedVaultClient() {
+  return nullptr;
+}
+
 scoped_refptr<syncer::ExtensionsActivity>
 WebViewSyncClient::GetExtensionsActivity() {
   return nullptr;
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index 8425327..3bda8541 100644
--- a/media/base/video_frame.cc
+++ b/media/base/video_frame.cc
@@ -43,8 +43,7 @@
 // Static constexpr class for generating unique identifiers for each VideoFrame.
 static base::AtomicSequenceNumber g_unique_id_generator;
 
-// static
-std::string VideoFrame::StorageTypeToString(
+static std::string StorageTypeToString(
     const VideoFrame::StorageType storage_type) {
   switch (storage_type) {
     case VideoFrame::STORAGE_UNKNOWN:
diff --git a/media/base/video_frame.h b/media/base/video_frame.h
index 9ea6ceb..eebca84 100644
--- a/media/base/video_frame.h
+++ b/media/base/video_frame.h
@@ -359,9 +359,6 @@
   // E.g. 2x2 for the U-plane in PIXEL_FORMAT_I420.
   static gfx::Size SampleSize(VideoPixelFormat format, size_t plane);
 
-  // Returns a human readable string of StorageType.
-  static std::string StorageTypeToString(VideoFrame::StorageType storage_type);
-
   // A video frame wrapping external data may be backed by an unsafe shared
   // memory region. These methods are used to appropriately transform a
   // VideoFrame created with WrapExternalData, WrapExternalYuvaData, etc. The
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn
index ba1b90e..827ff515 100644
--- a/media/gpu/BUILD.gn
+++ b/media/gpu/BUILD.gn
@@ -351,7 +351,6 @@
       ":common",
       "//base",
       "//media",
-      "//media/gpu/chromeos:fourcc",
       "//ui/gfx/geometry",
     ]
   }
@@ -658,7 +657,6 @@
       "test:render_helpers",
       "//base/test:test_support",
       "//media:test_support",
-      "//media/gpu/chromeos:fourcc",
       "//mojo/core/embedder",
       "//testing/gtest",
     ]
diff --git a/media/gpu/image_processor.cc b/media/gpu/image_processor.cc
index f0fffac..7908801 100644
--- a/media/gpu/image_processor.cc
+++ b/media/gpu/image_processor.cc
@@ -4,69 +4,40 @@
 
 #include "media/gpu/image_processor.h"
 
-#include <ostream>
-#include <sstream>
-
-#include "base/strings/stringprintf.h"
 #include "media/base/bind_to_current_loop.h"
-#include "media/base/video_frame.h"
 
 namespace media {
 
-namespace {
-
-std::ostream& operator<<(std::ostream& ostream,
-                         const VideoFrame::StorageType& storage_type) {
-  ostream << VideoFrame::StorageTypeToString(storage_type);
-  return ostream;
-}
-
-template <class T>
-std::string VectorToString(const std::vector<T>& vec) {
-  std::ostringstream result;
-  std::string delim;
-  result << "[";
-  for (const T& v : vec) {
-    result << delim << v;
-    if (delim.size() == 0)
-      delim = ", ";
-  }
-  result << "]";
-  return result.str();
-}
-
-}  // namespace
-
-ImageProcessor::PortConfig::PortConfig(const PortConfig&) = default;
-
 ImageProcessor::PortConfig::PortConfig(
-    Fourcc fourcc,
-    const gfx::Size& size,
-    const std::vector<ColorPlaneLayout>& planes,
+    const VideoFrameLayout& layout,
     const gfx::Size& visible_size,
     const std::vector<VideoFrame::StorageType>& preferred_storage_types)
-    : fourcc(fourcc),
-      size(size),
-      planes(planes),
+    : PortConfig(layout,
+                 kUnassignedFourCC,
+                 visible_size,
+                 preferred_storage_types) {}
+
+ImageProcessor::PortConfig::PortConfig(
+    const VideoFrameLayout& layout,
+    uint32_t fourcc,
+    const gfx::Size& visible_size,
+    const std::vector<VideoFrame::StorageType>& preferred_storage_types)
+    : layout(layout),
+      fourcc(fourcc),
       visible_size(visible_size),
       preferred_storage_types(preferred_storage_types) {}
 
-ImageProcessor::PortConfig::~PortConfig() = default;
+ImageProcessor::PortConfig::~PortConfig() {}
 
-std::string ImageProcessor::PortConfig::ToString() const {
-  return base::StringPrintf(
-      "PortConfig(format:%s, size:%s, planes: %s, visible_size:%s, "
-      "storage_types:%s)",
-      fourcc.ToString().c_str(), size.ToString().c_str(),
-      VectorToString(planes).c_str(), visible_size.ToString().c_str(),
-      VectorToString(preferred_storage_types).c_str());
-}
-
-ImageProcessor::ImageProcessor(const ImageProcessor::PortConfig& input_config,
-                               const ImageProcessor::PortConfig& output_config,
+ImageProcessor::ImageProcessor(const VideoFrameLayout& input_layout,
+                               VideoFrame::StorageType input_storage_type,
+                               const VideoFrameLayout& output_layout,
+                               VideoFrame::StorageType output_storage_type,
                                OutputMode output_mode)
-    : input_config_(input_config),
-      output_config_(output_config),
+    : input_layout_(input_layout),
+      input_storage_type_(input_storage_type),
+      output_layout_(output_layout),
+      output_storage_type_(output_storage_type),
       output_mode_(output_mode) {}
 
 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
diff --git a/media/gpu/image_processor.h b/media/gpu/image_processor.h
index b57991e..771652a 100644
--- a/media/gpu/image_processor.h
+++ b/media/gpu/image_processor.h
@@ -7,7 +7,6 @@
 
 #include <stdint.h>
 
-#include <string>
 #include <vector>
 
 #include "base/callback_forward.h"
@@ -15,9 +14,8 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "build/build_config.h"
-#include "media/base/color_plane_layout.h"
 #include "media/base/video_frame.h"
-#include "media/gpu/chromeos/fourcc.h"
+#include "media/base/video_frame_layout.h"
 #include "media/gpu/media_gpu_export.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -50,43 +48,27 @@
   };
 
   // Encapsulates ImageProcessor input / output configurations.
+  // Note that |fourcc| is used when format cannot be described in |layout|,
+  // e.g. platform specific format not listed in VideoPixelFormat. The default
+  // value of |fourcc| is kUnassignedFourCC.
   struct MEDIA_GPU_EXPORT PortConfig {
     PortConfig() = delete;
-    PortConfig(const PortConfig&);
     PortConfig(
-        Fourcc fourcc,
-        const gfx::Size& size,
-        const std::vector<ColorPlaneLayout>& planes,
+        const VideoFrameLayout& layout,
+        const gfx::Size& visible_size,
+        const std::vector<VideoFrame::StorageType>& preferred_storage_types);
+    PortConfig(
+        const VideoFrameLayout& layout,
+        uint32_t fourcc,
         const gfx::Size& visible_size,
         const std::vector<VideoFrame::StorageType>& preferred_storage_types);
     ~PortConfig();
 
-    // Get the first |preferred_storage_types|.
-    // If |preferred_storage_types| is empty, return STORAGE_UNKNOWN.
-    VideoFrame::StorageType storage_type() const {
-      return preferred_storage_types.empty() ? VideoFrame::STORAGE_UNKNOWN
-                                             : preferred_storage_types.front();
-    }
+    static const uint32_t kUnassignedFourCC = 0u;
 
-    // Output human readable string of PortConfig.
-    // Example:
-    // PortConfig(format::NV12, size:640x480, planes:[(640, 0, 307200),
-    // (640,0,153600)], visible_size:640x480, storage_types:[DMABUFS])
-    std::string ToString() const;
-
-    // Video frame format represented as fourcc type.
-    const Fourcc fourcc;
-
-    // Width and height of the video frame in pixels. This must include pixel
-    // data for the whole image; i.e. for YUV formats with subsampled chroma
-    // planes. If a visible portion of the image does not line up on a sample
-    // boundary, |size_| must be rounded up appropriately.
-    const gfx::Size size;
-
-    // Layout property (stride, offset, size of bytes) for each color plane.
-    const std::vector<ColorPlaneLayout> planes;
+    const VideoFrameLayout layout;
+    const uint32_t fourcc;
     const gfx::Size visible_size;
-    // List of preferred storage types.
     const std::vector<VideoFrame::StorageType> preferred_storage_types;
   };
 
@@ -113,8 +95,21 @@
 
   virtual ~ImageProcessor() = default;
 
-  const PortConfig& input_config() const { return input_config_; }
-  const PortConfig& output_config() const { return output_config_; }
+  // Returns input layout of the processor.
+  const VideoFrameLayout& input_layout() const { return input_layout_; }
+
+  // Returns output layout of the processor.
+  const VideoFrameLayout& output_layout() const { return output_layout_; }
+
+  // Returns input storage type.
+  VideoFrame::StorageType input_storage_type() const {
+    return input_storage_type_;
+  }
+
+  // Returns output storage type.
+  VideoFrame::StorageType output_storage_type() const {
+    return output_storage_type_;
+  }
 
   // Returns output mode.
   // TODO(crbug.com/907767): Remove it once ImageProcessor always works as
@@ -154,15 +149,21 @@
   virtual bool Reset() = 0;
 
  protected:
-  ImageProcessor(const PortConfig& input_config,
-                 const PortConfig& output_config,
+  ImageProcessor(const VideoFrameLayout& input_layout,
+                 VideoFrame::StorageType input_storage_type,
+                 const VideoFrameLayout& output_layout,
+                 VideoFrame::StorageType output_storage_type,
                  OutputMode output_mode);
 
-  const PortConfig input_config_;
-  const PortConfig output_config_;
+  // Stores input frame's layout and storage type.
+  const VideoFrameLayout input_layout_;
+  const VideoFrame::StorageType input_storage_type_;
 
+  // Stores output frame's layout, storage type and output mode.
   // TODO(crbug.com/907767): Remove |output_mode_| once ImageProcessor always
   // works as IMPORT mode for output.
+  const VideoFrameLayout output_layout_;
+  const VideoFrame::StorageType output_storage_type_;
   const OutputMode output_mode_;
 
  private:
diff --git a/media/gpu/image_processor_test.cc b/media/gpu/image_processor_test.cc
index d653e49b..8b0833de 100644
--- a/media/gpu/image_processor_test.cc
+++ b/media/gpu/image_processor_test.cc
@@ -15,7 +15,6 @@
 #include "media/base/video_frame.h"
 #include "media/base/video_frame_layout.h"
 #include "media/base/video_types.h"
-#include "media/gpu/chromeos/fourcc.h"
 #include "media/gpu/image_processor.h"
 #include "media/gpu/test/image.h"
 #include "media/gpu/test/image_processor/image_processor_client.h"
@@ -85,16 +84,18 @@
       const std::vector<VideoFrame::StorageType>& input_storage_types,
       const test::Image& output_image,
       const std::vector<VideoFrame::StorageType>& output_storage_types) {
-    Fourcc input_fourcc =
-        Fourcc::FromVideoPixelFormat(input_image.PixelFormat());
-    Fourcc output_fourcc =
-        Fourcc::FromVideoPixelFormat(output_image.PixelFormat());
-    ImageProcessor::PortConfig input_config(input_fourcc, input_image.Size(),
-                                            {}, input_image.Size(),
-                                            input_storage_types);
-    ImageProcessor::PortConfig output_config(output_fourcc, output_image.Size(),
-                                             {}, output_image.Size(),
-                                             output_storage_types);
+    const VideoPixelFormat input_format = input_image.PixelFormat();
+    const VideoPixelFormat output_format = output_image.PixelFormat();
+    auto input_config_layout =
+        test::CreateVideoFrameLayout(input_format, input_image.Size());
+    auto output_config_layout =
+        test::CreateVideoFrameLayout(output_format, output_image.Size());
+    LOG_ASSERT(input_config_layout);
+    LOG_ASSERT(output_config_layout);
+    ImageProcessor::PortConfig input_config(
+        *input_config_layout, input_image.Size(), input_storage_types);
+    ImageProcessor::PortConfig output_config(
+        *output_config_layout, output_image.Size(), output_storage_types);
     // TODO(crbug.com/917951): Select more appropriate number of buffers.
     constexpr size_t kNumBuffers = 1;
     LOG_ASSERT(output_image.IsMetadataLoaded());
@@ -103,8 +104,7 @@
     // TODO(crbug.com/917951): We should validate a scaled image with SSIM.
     // Validating processed frames is currently not supported when a format is
     // not YUV or when scaling images.
-    if (IsYuvPlanar(input_fourcc.ToVideoPixelFormat()) &&
-        IsYuvPlanar(output_fourcc.ToVideoPixelFormat()) &&
+    if (IsYuvPlanar(input_format) && IsYuvPlanar(output_format) &&
         input_image.Size() == output_image.Size()) {
       auto vf_validator = test::VideoFrameValidator::Create(
           {output_image.Checksum()}, output_image.PixelFormat());
@@ -116,7 +116,7 @@
           base::FilePath(base::FilePath::kCurrentDirectory)
               .Append(g_env->GetTestOutputFilePath());
       test::VideoFrameFileWriter::OutputFormat saved_file_format =
-          IsYuvPlanar(output_fourcc.ToVideoPixelFormat())
+          IsYuvPlanar(output_format)
               ? test::VideoFrameFileWriter::OutputFormat::kYUV
               : test::VideoFrameFileWriter::OutputFormat::kPNG;
       frame_processors.push_back(
diff --git a/media/gpu/libyuv_image_processor.cc b/media/gpu/libyuv_image_processor.cc
index 9bd914d..68d148ec 100644
--- a/media/gpu/libyuv_image_processor.cc
+++ b/media/gpu/libyuv_image_processor.cc
@@ -8,7 +8,6 @@
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
 #include "media/base/bind_to_current_loop.h"
-#include "media/gpu/chromeos/fourcc.h"
 #include "media/gpu/macros.h"
 #include "media/gpu/video_frame_mapper.h"
 #include "media/gpu/video_frame_mapper_factory.h"
@@ -26,21 +25,25 @@
   Unsupported,
 };
 
-SupportResult IsFormatSupported(Fourcc input_fourcc, Fourcc output_fourcc) {
-  static constexpr struct {
-    uint32_t input;
-    uint32_t output;
+SupportResult IsFormatSupported(VideoPixelFormat input_format,
+                                VideoPixelFormat output_format) {
+  constexpr struct {
+    VideoPixelFormat input;
+    VideoPixelFormat output;
     bool need_pivot;
   } kSupportFormatConversionArray[] = {
-      {Fourcc::AR24, Fourcc::NV12, false}, {Fourcc::YU12, Fourcc::NV12, false},
-      {Fourcc::YV12, Fourcc::NV12, false}, {Fourcc::AB24, Fourcc::NV12, true},
-      {Fourcc::XB24, Fourcc::NV12, true},
+      {PIXEL_FORMAT_ARGB, PIXEL_FORMAT_NV12, false},
+      {PIXEL_FORMAT_I420, PIXEL_FORMAT_NV12, false},
+      {PIXEL_FORMAT_YV12, PIXEL_FORMAT_NV12, false},
+      {PIXEL_FORMAT_ABGR, PIXEL_FORMAT_NV12, true},
+      {PIXEL_FORMAT_XBGR, PIXEL_FORMAT_NV12, true},
   };
 
-  for (const auto& conv : kSupportFormatConversionArray) {
-    if (conv.input == input_fourcc && conv.output == output_fourcc) {
-      return conv.need_pivot ? SupportResult::SupportedWithPivot
-                             : SupportResult::Supported;
+  for (auto* conv = std::cbegin(kSupportFormatConversionArray);
+       conv != std::cend(kSupportFormatConversionArray); conv++) {
+    if (conv->input == input_format && conv->output == output_format) {
+      return conv->need_pivot ? SupportResult::SupportedWithPivot
+                              : SupportResult::Supported;
     }
   }
 
@@ -50,11 +53,21 @@
 }  // namespace
 
 LibYUVImageProcessor::LibYUVImageProcessor(
-    const ImageProcessor::PortConfig& input_config,
-    const ImageProcessor::PortConfig& output_config,
+    const VideoFrameLayout& input_layout,
+    const gfx::Size& input_visible_size,
+    VideoFrame::StorageType input_storage_type,
+    const VideoFrameLayout& output_layout,
+    const gfx::Size& output_visible_size,
+    VideoFrame::StorageType output_storage_type,
     std::unique_ptr<VideoFrameMapper> video_frame_mapper,
     ErrorCB error_cb)
-    : ImageProcessor(input_config, output_config, OutputMode::IMPORT),
+    : ImageProcessor(input_layout,
+                     input_storage_type,
+                     output_layout,
+                     output_storage_type,
+                     OutputMode::IMPORT),
+      input_visible_rect_(input_visible_size),
+      output_visible_rect_(output_visible_size),
       video_frame_mapper_(std::move(video_frame_mapper)),
       error_cb_(error_cb),
       process_thread_("LibYUVImageProcessorThread") {}
@@ -70,7 +83,7 @@
 std::unique_ptr<LibYUVImageProcessor> LibYUVImageProcessor::Create(
     const ImageProcessor::PortConfig& input_config,
     const ImageProcessor::PortConfig& output_config,
-    ImageProcessor::OutputMode output_mode,
+    const ImageProcessor::OutputMode output_mode,
     ErrorCB error_cb) {
   VLOGF(2);
 
@@ -81,7 +94,7 @@
 #if defined(OS_LINUX)
     if (input_type == VideoFrame::STORAGE_DMABUFS) {
       video_frame_mapper = VideoFrameMapperFactory::CreateMapper(
-          input_config.fourcc.ToVideoPixelFormat(), true);
+          input_config.layout.format(), true);
       if (video_frame_mapper) {
         input_storage_type = input_type;
         break;
@@ -117,21 +130,17 @@
     return nullptr;
   }
 
-  SupportResult res =
-      IsFormatSupported(input_config.fourcc, output_config.fourcc);
+  SupportResult res = IsFormatSupported(input_config.layout.format(),
+                                        output_config.layout.format());
   if (res == SupportResult::Unsupported) {
-    VLOGF(2) << "Conversion from " << input_config.fourcc.ToString() << " to "
-             << output_config.fourcc.ToString() << " is not supported";
+    VLOGF(2) << "Conversion from " << input_config.layout.format() << " to "
+             << output_config.layout.format() << " is not supported";
     return nullptr;
   }
 
   auto processor = base::WrapUnique(new LibYUVImageProcessor(
-      ImageProcessor::PortConfig(input_config.fourcc, input_config.size, {},
-                                 input_config.visible_size,
-                                 {input_storage_type}),
-      ImageProcessor::PortConfig(output_config.fourcc, output_config.size, {},
-                                 output_config.visible_size,
-                                 {output_storage_type}),
+      input_config.layout, input_config.visible_size, input_storage_type,
+      output_config.layout, output_config.visible_size, output_storage_type,
       std::move(video_frame_mapper),
       media::BindToCurrentLoop(std::move(error_cb))));
   if (res == SupportResult::SupportedWithPivot) {
@@ -151,7 +160,7 @@
   }
 
   VLOGF(2) << "LibYUVImageProcessor created for converting from "
-           << input_config.ToString() << " to " << output_config.ToString();
+           << input_config.layout << " to " << output_config.layout;
   return processor;
 }
 
@@ -161,13 +170,11 @@
     FrameReadyCB cb) {
   DCHECK_CALLED_ON_VALID_THREAD(client_thread_checker_);
   DVLOGF(4);
-  DCHECK_EQ(input_frame->layout().format(),
-            input_config_.fourcc.ToVideoPixelFormat());
-  DCHECK(input_frame->layout().coded_size() == input_config_.size);
-  DCHECK_EQ(output_frame->layout().format(),
-            output_config_.fourcc.ToVideoPixelFormat());
-  DCHECK(output_frame->layout().coded_size() == output_config_.size);
-  DCHECK(input_config_.storage_type() == input_frame->storage_type() ||
+  DCHECK_EQ(input_frame->layout().format(), input_layout_.format());
+  DCHECK(input_frame->layout().coded_size() == input_layout_.coded_size());
+  DCHECK_EQ(output_frame->layout().format(), output_layout_.format());
+  DCHECK(output_frame->layout().coded_size() == output_layout_.coded_size());
+  DCHECK(input_storage_type_ == input_frame->storage_type() ||
          VideoFrame::IsStorageTypeMappable(input_frame->storage_type()));
   DCHECK(VideoFrame::IsStorageTypeMappable(output_frame->storage_type()));
 
diff --git a/media/gpu/libyuv_image_processor.h b/media/gpu/libyuv_image_processor.h
index 66e44f1..aaf5131 100644
--- a/media/gpu/libyuv_image_processor.h
+++ b/media/gpu/libyuv_image_processor.h
@@ -45,12 +45,16 @@
   static std::unique_ptr<LibYUVImageProcessor> Create(
       const ImageProcessor::PortConfig& input_config,
       const ImageProcessor::PortConfig& output_config,
-      ImageProcessor::OutputMode output_mode,
+      const ImageProcessor::OutputMode output_mode,
       ErrorCB error_cb);
 
  private:
-  LibYUVImageProcessor(const ImageProcessor::PortConfig& input_config,
-                       const ImageProcessor::PortConfig& output_config,
+  LibYUVImageProcessor(const VideoFrameLayout& input_layout,
+                       const gfx::Size& input_visible_size,
+                       VideoFrame::StorageType input_storage_type,
+                       const VideoFrameLayout& output_layout,
+                       const gfx::Size& output_visible_size,
+                       VideoFrame::StorageType output_storage_type,
                        std::unique_ptr<VideoFrameMapper> video_frame_mapper,
                        ErrorCB error_cb);
 
diff --git a/media/gpu/test/BUILD.gn b/media/gpu/test/BUILD.gn
index 514aa17..572693b 100644
--- a/media/gpu/test/BUILD.gn
+++ b/media/gpu/test/BUILD.gn
@@ -157,24 +157,21 @@
   ]
 }
 
-if (use_vaapi || use_v4l2_codec) {
-  static_library("image_processor") {
-    testonly = true
-    sources = [
-      "image_processor/image_processor_client.cc",
-      "image_processor/image_processor_client.h",
-    ]
-    deps = [
-      ":helpers",
-      ":render_helpers",
-      "//media:test_support",
-      "//media/gpu",
-      "//media/gpu/chromeos:fourcc",
-      "//testing/gtest",
-      "//third_party/libyuv",
-    ]
-    data = [
-      "//media/test/data/",
-    ]
-  }
+static_library("image_processor") {
+  testonly = true
+  sources = [
+    "image_processor/image_processor_client.cc",
+    "image_processor/image_processor_client.h",
+  ]
+  deps = [
+    ":helpers",
+    ":render_helpers",
+    "//media:test_support",
+    "//media/gpu",
+    "//testing/gtest",
+    "//third_party/libyuv",
+  ]
+  data = [
+    "//media/test/data/",
+  ]
 }
diff --git a/media/gpu/test/image_processor/image_processor_client.cc b/media/gpu/test/image_processor/image_processor_client.cc
index b4ca656..6de8fa2b 100644
--- a/media/gpu/test/image_processor/image_processor_client.cc
+++ b/media/gpu/test/image_processor/image_processor_client.cc
@@ -18,7 +18,6 @@
 #include "media/base/video_frame.h"
 #include "media/base/video_frame_layout.h"
 #include "media/gpu/buildflags.h"
-#include "media/gpu/chromeos/fourcc.h"
 #include "media/gpu/image_processor_factory.h"
 #include "media/gpu/test/image.h"
 #include "media/gpu/test/video_frame_helpers.h"
@@ -108,45 +107,22 @@
   done->Signal();
 }
 
-namespace {
-
-base::Optional<VideoFrameLayout> CreateLayout(
-    const ImageProcessor::PortConfig& config) {
-  // V4L2 specific format hack:
-  // If VDA's output format is V4L2_PIX_FMT_MT21C, which is a platform specific
-  // format and now is only used for MT8173 VDA output and its image processor
-  // input, we set VideoFrameLayout for image processor's input with format
-  // PIXEL_FORMAT_NV12 as NV12's layout is the same as MT21.
-  const VideoPixelFormat pixel_format = config.fourcc.ToVideoPixelFormat();
-  if (config.planes.size() <= 1) {
-    return VideoFrameLayout::Create(pixel_format, config.size);
-  }
-  return VideoFrameLayout::CreateMultiPlanar(pixel_format, config.size,
-                                             config.planes);
-}
-
-}  // namespace
-
 scoped_refptr<VideoFrame> ImageProcessorClient::CreateInputFrame(
     const Image& input_image) const {
   DCHECK_CALLED_ON_VALID_THREAD(test_main_thread_checker_);
   LOG_ASSERT(image_processor_);
   LOG_ASSERT(input_image.IsLoaded());
 
-  const ImageProcessor::PortConfig& input_config =
-      image_processor_->input_config();
-  const VideoFrame::StorageType input_storage_type =
-      input_config.storage_type();
-  base::Optional<VideoFrameLayout> input_layout = CreateLayout(input_config);
-  LOG_ASSERT(input_layout);
-
-  if (VideoFrame::IsStorageTypeMappable(input_storage_type)) {
+  const auto& input_layout = image_processor_->input_layout();
+  if (VideoFrame::IsStorageTypeMappable(
+          image_processor_->input_storage_type())) {
     return CloneVideoFrame(gpu_memory_buffer_factory_.get(),
                            CreateVideoFrameFromImage(input_image).get(),
-                           *input_layout, VideoFrame::STORAGE_OWNED_MEMORY);
+                           input_layout, VideoFrame::STORAGE_OWNED_MEMORY);
   } else {
 #if defined(OS_CHROMEOS)
-    LOG_ASSERT(input_storage_type == VideoFrame::STORAGE_DMABUFS);
+    LOG_ASSERT(image_processor_->input_storage_type() ==
+               VideoFrame::STORAGE_DMABUFS);
     // NV12 and YV12 are the only formats that can be allocated with
     // gfx::BufferUsage::SCANOUT_VEA_READ_CAMERA_AND_CPU_READ_WRITE. So
     // gfx::BufferUsage::GPU_READ_CPU_READ_WRITE is specified for RGB formats.
@@ -156,7 +132,7 @@
             : gfx::BufferUsage::GPU_READ_CPU_READ_WRITE;
     return CloneVideoFrame(gpu_memory_buffer_factory_.get(),
                            CreateVideoFrameFromImage(input_image).get(),
-                           *input_layout, VideoFrame::STORAGE_DMABUFS,
+                           input_layout, VideoFrame::STORAGE_DMABUFS,
                            dst_buffer_usage);
 #endif
     return nullptr;
@@ -169,22 +145,19 @@
   LOG_ASSERT(output_image.IsMetadataLoaded());
   LOG_ASSERT(image_processor_);
 
-  const ImageProcessor::PortConfig& output_config =
-      image_processor_->output_config();
-  const VideoFrame::StorageType output_storage_type =
-      output_config.storage_type();
-  base::Optional<VideoFrameLayout> output_layout = CreateLayout(output_config);
-  LOG_ASSERT(output_layout);
-  if (VideoFrame::IsStorageTypeMappable(output_storage_type)) {
+  const auto& output_layout = image_processor_->output_layout();
+  if (VideoFrame::IsStorageTypeMappable(
+          image_processor_->output_storage_type())) {
     return VideoFrame::CreateFrameWithLayout(
-        *output_layout, gfx::Rect(output_image.Size()), output_image.Size(),
+        output_layout, gfx::Rect(output_image.Size()), output_image.Size(),
         base::TimeDelta(), false /* zero_initialize_memory*/);
   } else {
 #if BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
-    LOG_ASSERT(output_storage_type == VideoFrame::STORAGE_DMABUFS);
+    LOG_ASSERT(image_processor_->output_storage_type() ==
+               VideoFrame::STORAGE_DMABUFS);
     return CreatePlatformVideoFrame(
-        gpu_memory_buffer_factory_.get(), output_layout->format(),
-        output_layout->coded_size(), gfx::Rect(output_image.Size()),
+        gpu_memory_buffer_factory_.get(), output_layout.format(),
+        output_layout.coded_size(), gfx::Rect(output_image.Size()),
         output_image.Size(), base::TimeDelta(),
         gfx::BufferUsage::GPU_READ_CPU_READ_WRITE);
 #endif  // BUILDFLAG(USE_CHROMEOS_MEDIA_ACCELERATION)
diff --git a/media/gpu/v4l2/v4l2_device.cc b/media/gpu/v4l2/v4l2_device.cc
index dbc406c..8189481 100644
--- a/media/gpu/v4l2/v4l2_device.cc
+++ b/media/gpu/v4l2/v4l2_device.cc
@@ -1153,6 +1153,14 @@
 }
 
 // static
+uint32_t V4L2Device::VideoFrameLayoutToV4L2PixFmt(
+    const VideoFrameLayout& layout) {
+  return Fourcc::FromVideoPixelFormat(layout.format(),
+                                      !layout.is_multi_planar())
+      .ToV4L2PixFmt();
+}
+
+// static
 uint32_t V4L2Device::VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile,
                                                    bool slice_based) {
   if (profile >= H264PROFILE_MIN && profile <= H264PROFILE_MAX) {
diff --git a/media/gpu/v4l2/v4l2_device.h b/media/gpu/v4l2/v4l2_device.h
index 862ed5f..0d06d93 100644
--- a/media/gpu/v4l2/v4l2_device.h
+++ b/media/gpu/v4l2/v4l2_device.h
@@ -381,6 +381,9 @@
     : public base::RefCountedThreadSafe<V4L2Device> {
  public:
   // Utility format conversion functions
+  // Returns v4l2 pixel format from |layout|. If there is no corresponding
+  // single- or multi-planar format or |layout| is invalid, returns 0.
+  static uint32_t VideoFrameLayoutToV4L2PixFmt(const VideoFrameLayout& layout);
   // If there is no corresponding single- or multi-planar format, returns 0.
   static uint32_t VideoCodecProfileToV4L2PixFmt(VideoCodecProfile profile,
                                                 bool slice_based);
diff --git a/media/gpu/v4l2/v4l2_image_processor.cc b/media/gpu/v4l2/v4l2_image_processor.cc
index 75c607ff..c0fb718 100644
--- a/media/gpu/v4l2/v4l2_image_processor.cc
+++ b/media/gpu/v4l2/v4l2_image_processor.cc
@@ -18,7 +18,6 @@
 #include "base/memory/ptr_util.h"
 #include "base/numerics/safe_conversions.h"
 #include "media/base/bind_to_current_loop.h"
-#include "media/base/color_plane_layout.h"
 #include "media/base/scopedfd_helper.h"
 #include "media/base/video_types.h"
 #include "media/gpu/chromeos/fourcc.h"
@@ -53,15 +52,25 @@
 
 V4L2ImageProcessor::V4L2ImageProcessor(
     scoped_refptr<V4L2Device> device,
-    const ImageProcessor::PortConfig& input_config,
-    const ImageProcessor::PortConfig& output_config,
+    VideoFrame::StorageType input_storage_type,
+    VideoFrame::StorageType output_storage_type,
     v4l2_memory input_memory_type,
     v4l2_memory output_memory_type,
     OutputMode output_mode,
+    const VideoFrameLayout& input_layout,
+    const VideoFrameLayout& output_layout,
+    gfx::Size input_visible_size,
+    gfx::Size output_visible_size,
     size_t num_buffers,
     ErrorCB error_cb)
-    : ImageProcessor(input_config, output_config, output_mode),
+    : ImageProcessor(input_layout,
+                     input_storage_type,
+                     output_layout,
+                     output_storage_type,
+                     output_mode),
+      input_visible_size_(input_visible_size),
       input_memory_type_(input_memory_type),
+      output_visible_size_(output_visible_size),
       output_memory_type_(output_memory_type),
       device_(device),
       device_thread_("V4L2ImageProcessorThread"),
@@ -163,10 +172,20 @@
     return nullptr;
   }
 
-  if (!device->Open(V4L2Device::Type::kImageProcessor,
-                    input_config.fourcc.ToV4L2PixFmt())) {
+  const VideoFrameLayout& input_layout = input_config.layout;
+
+  // Use input_config.fourcc as input format if it is specified, i.e. non-zero.
+  const uint32_t input_format_fourcc =
+      input_config.fourcc == ImageProcessor::PortConfig::kUnassignedFourCC
+          ? V4L2Device::VideoFrameLayoutToV4L2PixFmt(input_layout)
+          : input_config.fourcc;
+  if (!input_format_fourcc) {
+    VLOGF(1) << "Invalid VideoFrameLayout: " << input_layout;
+    return nullptr;
+  }
+  if (!device->Open(V4L2Device::Type::kImageProcessor, input_format_fourcc)) {
     VLOGF(1) << "Failed to open device with input fourcc: "
-             << input_config.fourcc.ToString();
+             << FourccToString(input_format_fourcc);
     return nullptr;
   }
 
@@ -174,78 +193,77 @@
   struct v4l2_format format;
   memset(&format, 0, sizeof(format));
   format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-  format.fmt.pix_mp.width = input_config.size.width();
-  format.fmt.pix_mp.height = input_config.size.height();
-  format.fmt.pix_mp.pixelformat = input_config.fourcc.ToV4L2PixFmt();
+  format.fmt.pix_mp.width = input_layout.coded_size().width();
+  format.fmt.pix_mp.height = input_layout.coded_size().height();
+  format.fmt.pix_mp.pixelformat = input_format_fourcc;
   if (device->Ioctl(VIDIOC_S_FMT, &format) != 0 ||
-      format.fmt.pix_mp.pixelformat != input_config.fourcc.ToV4L2PixFmt()) {
+      format.fmt.pix_mp.pixelformat != input_format_fourcc) {
     VLOGF(1) << "Failed to negotiate input format";
     return nullptr;
   }
 
-  const v4l2_pix_format_mplane& pix_mp = format.fmt.pix_mp;
-  const gfx::Size negotiated_input_size(pix_mp.width, pix_mp.height);
-  if (!gfx::Rect(negotiated_input_size)
+  base::Optional<VideoFrameLayout> negotiated_input_layout =
+      V4L2Device::V4L2FormatToVideoFrameLayout(format);
+  if (!negotiated_input_layout) {
+    VLOGF(1) << "Failed to negotiate input VideoFrameLayout";
+    return nullptr;
+  }
+
+  if (!gfx::Rect(negotiated_input_layout->coded_size())
            .Contains(gfx::Rect(input_config.visible_size))) {
     VLOGF(1) << "Negotiated input allocated size: "
-             << negotiated_input_size.ToString()
+             << negotiated_input_layout->coded_size().ToString()
              << " should contain visible size: "
              << input_config.visible_size.ToString();
     return nullptr;
   }
-  std::vector<ColorPlaneLayout> input_planes(pix_mp.num_planes);
-  for (size_t i = 0; i < pix_mp.num_planes; ++i) {
-    input_planes[i].stride = pix_mp.plane_fmt[i].bytesperline;
-    // offset will be specified for a buffer in each VIDIOC_QBUF.
-    input_planes[i].offset = 0;
-    input_planes[i].size = pix_mp.plane_fmt[i].sizeimage;
+
+  const VideoFrameLayout& output_layout = output_config.layout;
+  const uint32_t output_format_fourcc =
+      V4L2Device::VideoFrameLayoutToV4L2PixFmt(output_layout);
+  if (!output_format_fourcc) {
+    VLOGF(1) << "Invalid VideoFrameLayout: " << output_layout;
+    return nullptr;
   }
 
   // Try to set output format.
   memset(&format, 0, sizeof(format));
   format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
-  v4l2_pix_format_mplane& out_pix_mp = format.fmt.pix_mp;
-  out_pix_mp.width = output_config.size.width();
-  out_pix_mp.height = output_config.size.height();
-  out_pix_mp.pixelformat = output_config.fourcc.ToV4L2PixFmt();
-  out_pix_mp.num_planes = output_config.planes.size();
-  for (size_t i = 0; i < output_config.planes.size(); ++i) {
-    out_pix_mp.plane_fmt[i].sizeimage = output_config.planes[i].size;
-    out_pix_mp.plane_fmt[i].bytesperline = output_config.planes[i].stride;
+  format.fmt.pix_mp.width = output_layout.coded_size().width();
+  format.fmt.pix_mp.height = output_layout.coded_size().height();
+  format.fmt.pix_mp.pixelformat = output_format_fourcc;
+  format.fmt.pix_mp.num_planes =
+      V4L2Device::GetNumPlanesOfV4L2PixFmt(output_format_fourcc);
+  for (size_t i = 0; i < format.fmt.pix_mp.num_planes; ++i) {
+    format.fmt.pix_mp.plane_fmt[i].sizeimage = output_layout.planes()[i].size;
+    format.fmt.pix_mp.plane_fmt[i].bytesperline =
+        output_layout.planes()[i].stride;
   }
   if (device->Ioctl(VIDIOC_S_FMT, &format) != 0 ||
-      format.fmt.pix_mp.pixelformat != output_config.fourcc.ToV4L2PixFmt()) {
+      format.fmt.pix_mp.pixelformat != output_format_fourcc) {
     VLOGF(1) << "Failed to negotiate output format";
     return nullptr;
   }
-
-  out_pix_mp = format.fmt.pix_mp;
-  const gfx::Size negotiated_output_size(out_pix_mp.width, out_pix_mp.height);
-  if (!gfx::Rect(negotiated_output_size)
-           .Contains(gfx::Rect(output_config.size))) {
-    VLOGF(1) << "Negotiated output allocated size: "
-             << negotiated_output_size.ToString()
-             << " should contain original output allocated size: "
-             << output_config.size.ToString();
+  base::Optional<VideoFrameLayout> negotiated_output_layout =
+      V4L2Device::V4L2FormatToVideoFrameLayout(format);
+  if (!negotiated_output_layout) {
+    VLOGF(1) << "Failed to negotiate output VideoFrameLayout";
     return nullptr;
   }
-  std::vector<ColorPlaneLayout> output_planes(out_pix_mp.num_planes);
-  for (size_t i = 0; i < pix_mp.num_planes; ++i) {
-    output_planes[i].stride = pix_mp.plane_fmt[i].bytesperline;
-    // offset will be specified for a buffer in each VIDIOC_QBUF.
-    output_planes[i].offset = 0;
-    output_planes[i].size = pix_mp.plane_fmt[i].sizeimage;
+  if (!gfx::Rect(negotiated_output_layout->coded_size())
+           .Contains(gfx::Rect(output_layout.coded_size()))) {
+    VLOGF(1) << "Negotiated output allocated size: "
+             << negotiated_output_layout->coded_size().ToString()
+             << " should contain original output allocated size: "
+             << output_layout.coded_size().ToString();
+    return nullptr;
   }
 
   auto processor = base::WrapUnique(new V4L2ImageProcessor(
-      std::move(device),
-      ImageProcessor::PortConfig(input_config.fourcc, negotiated_input_size,
-                                 input_planes, input_config.visible_size,
-                                 {input_storage_type}),
-      ImageProcessor::PortConfig(output_config.fourcc, negotiated_output_size,
-                                 output_planes, output_config.visible_size,
-                                 {output_storage_type}),
-      input_memory_type, output_memory_type, output_mode, num_buffers,
+      std::move(device), input_storage_type, output_storage_type,
+      input_memory_type, output_memory_type, output_mode,
+      *negotiated_input_layout, *negotiated_output_layout,
+      input_config.visible_size, output_config.visible_size, num_buffers,
       media::BindToCurrentLoop(std::move(error_cb))));
   if (!processor->Initialize()) {
     VLOGF(1) << "Failed to initialize V4L2ImageProcessor";
@@ -288,8 +306,10 @@
                                 base::Unretained(this)));
 
   VLOGF(2) << "V4L2ImageProcessor initialized for "
-           << "input: " << input_config_.ToString()
-           << ", output: " << output_config_.ToString();
+           << "input_layout: " << input_layout_
+           << ", output_layout: " << output_layout_
+           << ", input_visible_size: " << input_visible_size_.ToString()
+           << ", output_visible_size: " << output_visible_size_.ToString();
 
   return true;
 }
@@ -494,10 +514,8 @@
   struct v4l2_rect visible_rect;
   visible_rect.left = 0;
   visible_rect.top = 0;
-  visible_rect.width =
-      base::checked_cast<__u32>(input_config_.visible_size.width());
-  visible_rect.height =
-      base::checked_cast<__u32>(input_config_.visible_size.height());
+  visible_rect.width = base::checked_cast<__u32>(input_visible_size_.width());
+  visible_rect.height = base::checked_cast<__u32>(input_visible_size_.height());
 
   struct v4l2_selection selection_arg;
   memset(&selection_arg, 0, sizeof(selection_arg));
@@ -538,10 +556,9 @@
   struct v4l2_rect visible_rect;
   visible_rect.left = 0;
   visible_rect.top = 0;
-  visible_rect.width =
-      base::checked_cast<__u32>(output_config_.visible_size.width());
+  visible_rect.width = base::checked_cast<__u32>(output_visible_size_.width());
   visible_rect.height =
-      base::checked_cast<__u32>(output_config_.visible_size.height());
+    base::checked_cast<__u32>(output_visible_size_.height());
 
   output_queue_ = device_->GetQueue(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
   if (!output_queue_)
@@ -779,11 +796,11 @@
   DCHECK(buffer.IsValid());
 
   std::vector<void*> user_ptrs;
-  const size_t num_planes =
-      V4L2Device::GetNumPlanesOfV4L2PixFmt(input_config_.fourcc.ToV4L2PixFmt());
+  size_t num_planes = V4L2Device::GetNumPlanesOfV4L2PixFmt(
+      V4L2Device::VideoFrameLayoutToV4L2PixFmt(input_layout_));
   for (size_t i = 0; i < num_planes; ++i) {
     int bytes_used = VideoFrame::PlaneSize(job_record->input_frame->format(), i,
-                                           input_config_.size)
+                                           input_layout_.coded_size())
                          .GetArea();
     buffer.SetPlaneBytesUsed(i, bytes_used);
     if (buffer.Memory() == V4L2_MEMORY_USERPTR)
diff --git a/media/gpu/v4l2/v4l2_image_processor.h b/media/gpu/v4l2/v4l2_image_processor.h
index 1d85f3b..cc1483fd 100644
--- a/media/gpu/v4l2/v4l2_image_processor.h
+++ b/media/gpu/v4l2/v4l2_image_processor.h
@@ -92,11 +92,15 @@
   };
 
   V4L2ImageProcessor(scoped_refptr<V4L2Device> device,
-                     const ImageProcessor::PortConfig& input_config,
-                     const ImageProcessor::PortConfig& output_config,
+                     VideoFrame::StorageType input_storage_type,
+                     VideoFrame::StorageType output_storage_type,
                      v4l2_memory input_memory_type,
                      v4l2_memory output_memory_type,
                      OutputMode output_mode,
+                     const VideoFrameLayout& input_layout,
+                     const VideoFrameLayout& output_layout,
+                     gfx::Size input_visible_size,
+                     gfx::Size output_visible_size,
                      size_t num_buffers,
                      ErrorCB error_cb);
 
@@ -139,7 +143,12 @@
   // callbacks will be invoked.
   void Destroy();
 
+  // Stores input frame's visible size and v4l2_memory type.
+  const gfx::Size input_visible_size_;
   const v4l2_memory input_memory_type_;
+
+  // Stores output frame's visible size and v4l2_memory type.
+  const gfx::Size output_visible_size_;
   const v4l2_memory output_memory_type_;
 
   // V4L2 device in use.
diff --git a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
index a013d21..f75ebb1 100644
--- a/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_slice_video_decode_accelerator.cc
@@ -585,7 +585,7 @@
     return false;
   }
 
-  DCHECK_EQ(gl_image_size_, image_processor_->output_config().size);
+  DCHECK_EQ(gl_image_size_, image_processor_->output_layout().coded_size());
 
   return true;
 }
diff --git a/media/gpu/v4l2/v4l2_vda_helpers.cc b/media/gpu/v4l2/v4l2_vda_helpers.cc
index f73d4e94..a01d9cf 100644
--- a/media/gpu/v4l2/v4l2_vda_helpers.cc
+++ b/media/gpu/v4l2/v4l2_vda_helpers.cc
@@ -13,6 +13,38 @@
 namespace media {
 namespace v4l2_vda_helpers {
 
+namespace {
+base::Optional<VideoFrameLayout> CreateLayout(uint32_t fourcc,
+                                              const gfx::Size& size) {
+  // V4L2 specific format hack:
+  // If VDA's output format is V4L2_PIX_FMT_MT21C, which is a platform specific
+  // format and now is only used for MT8173 VDA output and its image processor
+  // input, we set VideoFrameLayout for image processor's input with format
+  // PIXEL_FORMAT_NV12 as NV12's layout is the same as MT21.
+  size_t num_planes;
+  switch (fourcc) {
+    case V4L2_PIX_FMT_MT21C:
+    case V4L2_PIX_FMT_MM21:
+      num_planes = 2;
+      return VideoFrameLayout::CreateMultiPlanar(
+          PIXEL_FORMAT_NV12, size, std::vector<ColorPlaneLayout>(num_planes));
+
+    default:
+      VideoPixelFormat pixel_format =
+          Fourcc::FromV4L2PixFmt(fourcc).ToVideoPixelFormat();
+      if (pixel_format == PIXEL_FORMAT_UNKNOWN)
+        return base::nullopt;
+      num_planes = V4L2Device::GetNumPlanesOfV4L2PixFmt(fourcc);
+      if (num_planes == 1)
+        return VideoFrameLayout::Create(pixel_format, size);
+      else
+        return VideoFrameLayout::CreateMultiPlanar(
+            pixel_format, size, std::vector<ColorPlaneLayout>(num_planes));
+      break;
+  }
+}
+}  // namespace
+
 uint32_t FindImageProcessorInputFormat(V4L2Device* vda_device) {
   std::vector<uint32_t> processor_input_formats =
       V4L2ImageProcessor::GetSupportedInputFormats();
@@ -71,33 +103,45 @@
     scoped_refptr<V4L2Device> image_processor_device,
     ImageProcessor::OutputMode image_processor_output_mode,
     ImageProcessor::ErrorCB error_cb) {
+  base::Optional<VideoFrameLayout> input_layout =
+      CreateLayout(vda_output_format, vda_output_coded_size);
+  if (!input_layout) {
+    VLOGF(1) << "Invalid input layout";
+    return nullptr;
+  }
+
+  base::Optional<VideoFrameLayout> output_layout =
+      CreateLayout(ip_output_format, ip_output_coded_size);
+  if (!output_layout) {
+    VLOGF(1) << "Invalid output layout";
+    return nullptr;
+  }
+
   // TODO(crbug.com/917798): Use ImageProcessorFactory::Create() once we remove
   //     |image_processor_device_| from V4L2VideoDecodeAccelerator.
   auto image_processor = V4L2ImageProcessor::Create(
       image_processor_device,
-      ImageProcessor::PortConfig(Fourcc::FromV4L2PixFmt(vda_output_format),
-                                 vda_output_coded_size, {}, visible_size,
+      ImageProcessor::PortConfig(*input_layout, vda_output_format, visible_size,
                                  {VideoFrame::STORAGE_DMABUFS}),
-      ImageProcessor::PortConfig(Fourcc::FromV4L2PixFmt(ip_output_format),
-                                 ip_output_coded_size, {}, visible_size,
+      ImageProcessor::PortConfig(*output_layout, visible_size,
                                  {VideoFrame::STORAGE_DMABUFS}),
       image_processor_output_mode, nb_buffers, std::move(error_cb));
   if (!image_processor)
     return nullptr;
 
-  if (image_processor->output_config().size != ip_output_coded_size) {
+  if (image_processor->output_layout().coded_size() != ip_output_coded_size) {
     VLOGF(1) << "Image processor should be able to use the requested output "
              << "coded size " << ip_output_coded_size.ToString()
              << " without adjusting to "
-             << image_processor->output_config().size.ToString();
+             << image_processor->output_layout().coded_size().ToString();
     return nullptr;
   }
 
-  if (image_processor->input_config().size != vda_output_coded_size) {
+  if (image_processor->input_layout().coded_size() != vda_output_coded_size) {
     VLOGF(1) << "Image processor should be able to take the output coded "
              << "size of decoder " << vda_output_coded_size.ToString()
              << " without adjusting to "
-             << image_processor->input_config().size.ToString();
+             << image_processor->input_layout().coded_size().ToString();
     return nullptr;
   }
 
diff --git a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
index b3face6b..2197bec 100644
--- a/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
+++ b/media/gpu/v4l2/v4l2_video_encode_accelerator.cc
@@ -96,19 +96,6 @@
 
 namespace media {
 
-namespace {
-// Convert VideoFrameLayout to ImageProcessor::PortConfig.
-ImageProcessor::PortConfig VideoFrameLayoutToPortConfig(
-    const VideoFrameLayout& layout,
-    const gfx::Size& visible_size,
-    const std::vector<VideoFrame::StorageType>& preferred_storage_types) {
-  return ImageProcessor::PortConfig(
-      Fourcc::FromVideoPixelFormat(layout.format(), !layout.is_multi_planar()),
-      layout.coded_size(), layout.planes(), visible_size,
-      preferred_storage_types);
-}
-}  // namespace
-
 struct V4L2VideoEncodeAccelerator::BitstreamBufferRef {
   BitstreamBufferRef(int32_t id, std::unique_ptr<UnalignedSharedMemory> shm)
       : id(id), shm(std::move(shm)) {}
@@ -280,12 +267,12 @@
       config.initial_bitrate, config.initial_framerate.value_or(
                                   VideoEncodeAccelerator::kDefaultFramerate));
   child_task_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&Client::RequireBitstreamBuffers, client_,
-                                kInputBufferCount,
-                                image_processor_.get()
-                                    ? image_processor_->input_config().size
-                                    : input_allocated_size_,
-                                output_buffer_byte_size_));
+      FROM_HERE,
+      base::BindOnce(
+          &Client::RequireBitstreamBuffers, client_, kInputBufferCount,
+          image_processor_.get() ? image_processor_->input_layout().coded_size()
+                                 : input_allocated_size_,
+          output_buffer_byte_size_));
 
   // Finish initialization.
   *result = true;
@@ -307,9 +294,9 @@
   // for |input_storage_type| here, as long as VideoFrame on Process()'s data
   // can be accessed by VideoFrame::data().
   image_processor_ = ImageProcessorFactory::Create(
-      VideoFrameLayoutToPortConfig(input_layout, visible_size,
-                                   {VideoFrame::STORAGE_OWNED_MEMORY}),
-      VideoFrameLayoutToPortConfig(
+      ImageProcessor::PortConfig(input_layout, visible_size,
+                                 {VideoFrame::STORAGE_OWNED_MEMORY}),
+      ImageProcessor::PortConfig(
           output_layout, visible_size,
           {VideoFrame::STORAGE_DMABUFS, VideoFrame::STORAGE_OWNED_MEMORY}),
       // Try OutputMode::ALLOCATE first because we want v4l2IP chooses
@@ -332,7 +319,7 @@
   // Output coded height of processor can be larger but not smaller than the
   // input coded height of encoder. For example, suppose input size of encoder
   // is 320x193. It is OK if the output of processor is 320x208.
-  const auto& ip_output_size = image_processor_->output_config().size;
+  const auto& ip_output_size = image_processor_->output_layout().coded_size();
   if (ip_output_size.width() != output_layout.coded_size().width() ||
       ip_output_size.height() < output_layout.coded_size().height()) {
     VLOGF(1) << "Invalid image processor output coded size "
@@ -360,8 +347,7 @@
   }
 
   image_processor_output_buffers_.resize(count);
-  const auto output_storage_type =
-      image_processor_->output_config().storage_type();
+  const auto output_storage_type = image_processor_->output_storage_type();
   for (size_t i = 0; i < count; i++) {
     switch (output_storage_type) {
       case VideoFrame::STORAGE_OWNED_MEMORY:
@@ -386,7 +372,7 @@
 bool V4L2VideoEncodeAccelerator::InitInputMemoryType(const Config& config) {
   DCHECK(encoder_thread_.task_runner()->BelongsToCurrentThread());
   if (image_processor_) {
-    const auto storage_type = image_processor_->output_config().storage_type();
+    const auto storage_type = image_processor_->output_storage_type();
     if (storage_type == VideoFrame::STORAGE_DMABUFS) {
       input_memory_type_ = V4L2_MEMORY_DMABUF;
     } else if (VideoFrame::IsStorageTypeMappable(storage_type)) {
@@ -654,7 +640,7 @@
   // We should apply the frame size change to ImageProcessor if there is.
   if (image_processor_) {
     // Stride is the same. There is no need of executing S_FMT again.
-    if (image_processor_->input_config().size == new_frame_size) {
+    if (image_processor_->input_layout().coded_size() == new_frame_size) {
       return true;
     }
 
@@ -681,7 +667,7 @@
       NOTIFY_ERROR(kPlatformFailureError);
       return false;
     }
-    if (image_processor_->input_config().size.width() !=
+    if (image_processor_->input_layout().coded_size().width() !=
         new_frame_size.width()) {
       NOTIFY_ERROR(kPlatformFailureError);
       return false;
@@ -1082,9 +1068,7 @@
 
   DCHECK_EQ(device_input_layout_->format(), frame->format());
   size_t num_planes = V4L2Device::GetNumPlanesOfV4L2PixFmt(
-      Fourcc::FromVideoPixelFormat(device_input_layout_->format(),
-                                   device_input_layout_->is_multi_planar())
-          .ToV4L2PixFmt());
+      V4L2Device::VideoFrameLayoutToV4L2PixFmt(*device_input_layout_));
 
   // Create GpuMemoryBufferHandle for native_input_mode.
   gfx::GpuMemoryBufferHandle gmb_handle;
diff --git a/media/gpu/vaapi/vaapi_image_processor.cc b/media/gpu/vaapi/vaapi_image_processor.cc
index 885a0b8..52ee551b 100644
--- a/media/gpu/vaapi/vaapi_image_processor.cc
+++ b/media/gpu/vaapi/vaapi_image_processor.cc
@@ -4,8 +4,6 @@
 
 #include "media/gpu/vaapi/vaapi_image_processor.h"
 
-#include <stdint.h>
-
 #include <va/va.h>
 
 #include "base/bind.h"
@@ -37,19 +35,23 @@
   error_cb.Run();
 }
 
-bool IsSupported(uint32_t input_va_fourcc,
-                 uint32_t output_va_fourcc,
-                 const gfx::Size& input_size,
-                 const gfx::Size& output_size) {
+bool IsSupported(VideoPixelFormat input_format,
+                 VideoPixelFormat output_format,
+                 gfx::Size input_size,
+                 gfx::Size output_size) {
+  const uint32_t input_va_fourcc =
+      Fourcc::FromVideoPixelFormat(input_format).ToVAFourCC();
   if (!VaapiWrapper::IsVppFormatSupported(input_va_fourcc)) {
-    VLOGF(2) << "Unsupported input format: VA_FOURCC_"
-             << FourccToString(input_va_fourcc);
+    VLOGF(2) << "Unsupported input format: " << input_format << " (VA_FOURCC_"
+             << FourccToString(input_va_fourcc) << ")";
     return false;
   }
 
+  const uint32_t output_va_fourcc =
+      Fourcc::FromVideoPixelFormat(output_format).ToVAFourCC();
   if (!VaapiWrapper::IsVppFormatSupported(output_va_fourcc)) {
-    VLOGF(2) << "Unsupported output format: VA_FOURCC_"
-             << FourccToString(output_va_fourcc);
+    VLOGF(2) << "Unsupported output format: " << output_format << " (VA_FOURCC_"
+             << FourccToString(output_va_fourcc) << ")";
     return false;
   }
 
@@ -99,9 +101,11 @@
   return nullptr;
 #endif
 
-  if (!IsSupported(input_config.fourcc.ToVAFourCC(),
-                   output_config.fourcc.ToVAFourCC(), input_config.size,
-                   output_config.size)) {
+  const VideoFrameLayout& input_layout = input_config.layout;
+  const VideoFrameLayout& output_layout = output_config.layout;
+  if (!IsSupported(input_layout.format(), output_layout.format(),
+                   input_config.layout.coded_size(),
+                   output_config.layout.coded_size())) {
     return nullptr;
   }
 
@@ -127,23 +131,27 @@
     return nullptr;
   }
 
-  // We should restrict the acceptable PortConfig for input and output both to
-  // the one returned by GetPlatformVideoFrameLayout(). However,
+  // We should restrict the acceptable VideoFrameLayout for input and output
+  // both to the one returned by GetPlatformVideoFrameLayout(). However,
   // ImageProcessorFactory interface doesn't provide information about what
   // ImageProcessor will be used for. (e.g. format conversion after decoding and
   // scaling before encoding). Thus we cannot execute
   // GetPlatformVideoFrameLayout() with a proper gfx::BufferUsage.
   // TODO(crbug.com/898423): Adjust layout once ImageProcessor provide the use
   // scenario.
-  return base::WrapUnique(new VaapiImageProcessor(input_config, output_config,
+  return base::WrapUnique(new VaapiImageProcessor(input_layout, output_layout,
                                                   std::move(vaapi_wrapper)));
 }
 
 VaapiImageProcessor::VaapiImageProcessor(
-    const ImageProcessor::PortConfig& input_config,
-    const ImageProcessor::PortConfig& output_config,
+    const VideoFrameLayout& input_layout,
+    const VideoFrameLayout& output_layout,
     scoped_refptr<VaapiWrapper> vaapi_wrapper)
-    : ImageProcessor(input_config, output_config, OutputMode::IMPORT),
+    : ImageProcessor(input_layout,
+                     VideoFrame::STORAGE_DMABUFS,
+                     output_layout,
+                     VideoFrame::STORAGE_DMABUFS,
+                     OutputMode::IMPORT),
       processor_task_runner_(base::CreateSequencedTaskRunner(
           base::TaskTraits{base::ThreadPool()})),
       vaapi_wrapper_(std::move(vaapi_wrapper)) {}
@@ -161,46 +169,32 @@
   DCHECK(input_frame);
   DCHECK(output_frame);
 
-  const Fourcc input_frame_fourcc =
-      Fourcc::FromVideoPixelFormat(input_frame->layout().format());
-  if (input_frame_fourcc != input_config_.fourcc) {
-    VLOGF(1) << "Invalid input_frame format=" << input_frame_fourcc.ToString()
-             << ", expected=" << input_config_.fourcc.ToString();
+  const VideoFrameLayout& input_frame_layout = input_frame->layout();
+  if (input_frame_layout.format() != input_layout_.format() ||
+      input_frame_layout.coded_size() != input_layout_.coded_size()) {
+    VLOGF(1) << "Invalid input_frame->layout=" << input_frame->layout()
+             << ", input_layout_=" << input_layout_;
     return false;
   }
 
-  if (input_frame->layout().coded_size() != input_config_.size) {
-    VLOGF(1) << "Invalid input_frame size="
-             << input_frame->layout().coded_size().ToString()
-             << ", expected=" << input_config_.size.ToString();
+  const VideoFrameLayout& output_frame_layout = output_frame->layout();
+  if (output_frame_layout.format() != output_layout_.format() ||
+      output_frame_layout.coded_size() != output_layout_.coded_size()) {
+    VLOGF(1) << "Invalid output_frame->layout=" << output_frame->layout()
+             << ", output_layout_=" << output_layout_;
     return false;
   }
 
-  const Fourcc output_frame_fourcc =
-      Fourcc::FromVideoPixelFormat(output_frame->layout().format());
-  if (output_frame_fourcc != output_config_.fourcc) {
-    VLOGF(1) << "Invalid output_frame format=" << output_frame_fourcc.ToString()
-             << ", expected=" << output_config_.fourcc.ToString();
-    return false;
-  }
-
-  if (output_frame->layout().coded_size() != output_config_.size) {
-    VLOGF(1) << "Invalid output_frame size="
-             << output_frame->layout().coded_size().ToString()
-             << ", expected=" << output_config_.size.ToString();
-    return false;
-  }
-
-  if (input_frame->storage_type() != input_config_.storage_type()) {
+  if (input_frame->storage_type() != input_storage_type()) {
     VLOGF(1) << "Invalid input_frame->storage_type="
              << input_frame->storage_type()
-             << ", input_storage_type=" << input_config_.storage_type();
+             << ", input_storage_type=" << input_storage_type();
     return false;
   }
-  if (output_frame->storage_type() != output_config_.storage_type()) {
+  if (output_frame->storage_type() != output_storage_type()) {
     VLOGF(1) << "Invalid output_frame->storage_type="
              << output_frame->storage_type()
-             << ", expected=" << output_config_.storage_type();
+             << ", output_storage_type=" << output_storage_type();
     return false;
   }
 
diff --git a/media/gpu/vaapi/vaapi_image_processor.h b/media/gpu/vaapi/vaapi_image_processor.h
index 699be4c2..69a0082b 100644
--- a/media/gpu/vaapi/vaapi_image_processor.h
+++ b/media/gpu/vaapi/vaapi_image_processor.h
@@ -39,8 +39,8 @@
   bool Reset() override;
 
  private:
-  VaapiImageProcessor(const ImageProcessor::PortConfig& input_config,
-                      const ImageProcessor::PortConfig& output_config,
+  VaapiImageProcessor(const VideoFrameLayout& input_layout,
+                      const VideoFrameLayout& output_layout,
                       scoped_refptr<VaapiWrapper> vaapi_wrapper);
 
   // ImageProcessor implementation.
diff --git a/net/BUILD.gn b/net/BUILD.gn
index f32b0c05..a879882b 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -5855,7 +5855,10 @@
       "quic/platform/impl/quic_socket_utils_test.cc",
       "third_party/quiche/src/epoll_server/simple_epoll_server_test.cc",
       "third_party/quiche/src/quic/core/chlo_extractor_test.cc",
-      "third_party/quiche/src/quic/core/http/end_to_end_test.cc",
+
+      # EndToEndTestServerPush.ServerPushOverLimitNonBlocking is flaky.
+      # See https://crbug.com/1010206
+      # "third_party/quiche/src/quic/core/http/end_to_end_test.cc",
       "third_party/quiche/src/quic/core/http/quic_spdy_client_session_test.cc",
       "third_party/quiche/src/quic/core/http/quic_spdy_client_stream_test.cc",
       "third_party/quiche/src/quic/core/http/quic_spdy_server_stream_base_test.cc",
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc
index ca45366e..bda3d27c 100644
--- a/services/network/cors/cors_url_loader_factory.cc
+++ b/services/network/cors/cors_url_loader_factory.cc
@@ -34,7 +34,7 @@
     NetworkContext* context,
     mojom::URLLoaderFactoryParamsPtr params,
     scoped_refptr<ResourceSchedulerClient> resource_scheduler_client,
-    mojom::URLLoaderFactoryRequest request,
+    mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
     const OriginAccessList* origin_access_list,
     std::unique_ptr<mojom::URLLoaderFactory> network_loader_factory_for_testing)
     : context_(context),
@@ -60,8 +60,8 @@
                 context, std::move(params),
                 std::move(resource_scheduler_client), this);
 
-  bindings_.AddBinding(this, std::move(request));
-  bindings_.set_connection_error_handler(base::BindRepeating(
+  receivers_.Add(this, std::move(receiver));
+  receivers_.set_disconnect_handler(base::BindRepeating(
       &CorsURLLoaderFactory::DeleteIfNeeded, base::Unretained(this)));
 }
 
@@ -116,19 +116,20 @@
   }
 }
 
-void CorsURLLoaderFactory::Clone(mojom::URLLoaderFactoryRequest request) {
+void CorsURLLoaderFactory::Clone(
+    mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) {
   // The cloned factories stop working when this factory is destructed.
-  bindings_.AddBinding(this, std::move(request));
+  receivers_.Add(this, std::move(receiver));
 }
 
 void CorsURLLoaderFactory::ClearBindings() {
-  bindings_.CloseAllBindings();
+  receivers_.Clear();
 }
 
 void CorsURLLoaderFactory::DeleteIfNeeded() {
   if (!context_)
     return;
-  if (bindings_.empty() && loaders_.empty())
+  if (receivers_.empty() && loaders_.empty())
     context_->DestroyURLLoaderFactory(this);
 }
 
diff --git a/services/network/cors/cors_url_loader_factory.h b/services/network/cors/cors_url_loader_factory.h
index 4ad1e408..d4bc5a4 100644
--- a/services/network/cors/cors_url_loader_factory.h
+++ b/services/network/cors/cors_url_loader_factory.h
@@ -11,6 +11,8 @@
 #include "base/callback_forward.h"
 #include "base/containers/unique_ptr_adapters.h"
 #include "base/macros.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "mojo/public/cpp/bindings/strong_binding_set.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/cpp/cors/origin_access_list.h"
@@ -41,7 +43,7 @@
       NetworkContext* context,
       mojom::URLLoaderFactoryParamsPtr params,
       scoped_refptr<ResourceSchedulerClient> resource_scheduler_client,
-      mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
       const OriginAccessList* origin_access_list,
       std::unique_ptr<mojom::URLLoaderFactory>
           network_loader_factory_for_testing);
@@ -64,13 +66,13 @@
                             mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) override;
 
   void DeleteIfNeeded();
 
   bool IsSane(const NetworkContext* context, const ResourceRequest& request);
 
-  mojo::BindingSet<mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<mojom::URLLoaderFactory> receivers_;
 
   // Used when constructed by NetworkContext.
   // The NetworkContext owns |this|.
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc
index 21b70e24..b792321 100644
--- a/services/network/cors/cors_url_loader_unittest.cc
+++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -22,6 +22,7 @@
 #include "base/test/task_environment.h"
 #include "mojo/core/embedder/embedder.h"
 #include "mojo/public/cpp/bindings/message.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "net/base/load_flags.h"
 #include "net/http/http_request_headers.h"
@@ -123,7 +124,9 @@
       on_create_loader_and_start_.Run();
   }
 
-  void Clone(mojom::URLLoaderFactoryRequest request) override { NOTREACHED(); }
+  void Clone(mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) override {
+    NOTREACHED();
+  }
 
   mojom::URLLoaderClientPtr client_ptr_;
 
diff --git a/services/network/network_context.cc b/services/network/network_context.cc
index 7e154991..2c853cf 100644
--- a/services/network/network_context.cc
+++ b/services/network/network_context.cc
@@ -461,12 +461,12 @@
 }
 
 void NetworkContext::CreateURLLoaderFactory(
-    mojom::URLLoaderFactoryRequest request,
+    mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
     mojom::URLLoaderFactoryParamsPtr params,
     scoped_refptr<ResourceSchedulerClient> resource_scheduler_client) {
   url_loader_factories_.emplace(std::make_unique<cors::CorsURLLoaderFactory>(
       this, std::move(params), std::move(resource_scheduler_client),
-      std::move(request), &cors_origin_access_list_, nullptr));
+      std::move(receiver), &cors_origin_access_list_, nullptr));
 }
 
 void NetworkContext::SetClient(
@@ -476,14 +476,14 @@
 }
 
 void NetworkContext::CreateURLLoaderFactory(
-    mojom::URLLoaderFactoryRequest request,
+    mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
     mojom::URLLoaderFactoryParamsPtr params) {
   scoped_refptr<ResourceSchedulerClient> resource_scheduler_client;
   resource_scheduler_client = base::MakeRefCounted<ResourceSchedulerClient>(
       params->process_id, ++current_resource_scheduler_client_id_,
       resource_scheduler_.get(),
       url_request_context_->network_quality_estimator());
-  CreateURLLoaderFactory(std::move(request), std::move(params),
+  CreateURLLoaderFactory(std::move(receiver), std::move(params),
                          std::move(resource_scheduler_client));
 }
 
diff --git a/services/network/network_context.h b/services/network/network_context.h
index 29d9c39..65ccceb 100644
--- a/services/network/network_context.h
+++ b/services/network/network_context.h
@@ -164,15 +164,16 @@
   // is used to reuse the existing ResourceSchedulerClient for cloned
   // URLLoaderFactory.
   void CreateURLLoaderFactory(
-      mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
       mojom::URLLoaderFactoryParamsPtr params,
       scoped_refptr<ResourceSchedulerClient> resource_scheduler_client);
 
   // mojom::NetworkContext implementation:
   void SetClient(
       mojo::PendingRemote<mojom::NetworkContextClient> client) override;
-  void CreateURLLoaderFactory(mojom::URLLoaderFactoryRequest request,
-                              mojom::URLLoaderFactoryParamsPtr params) override;
+  void CreateURLLoaderFactory(
+      mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
+      mojom::URLLoaderFactoryParamsPtr params) override;
   void ResetURLLoaderFactories() override;
   void GetCookieManager(
       mojo::PendingReceiver<mojom::CookieManager> receiver) override;
diff --git a/services/network/public/cpp/cross_thread_shared_url_loader_factory_info.cc b/services/network/public/cpp/cross_thread_shared_url_loader_factory_info.cc
index 0da8c691..cba963f 100644
--- a/services/network/public/cpp/cross_thread_shared_url_loader_factory_info.cc
+++ b/services/network/public/cpp/cross_thread_shared_url_loader_factory_info.cc
@@ -10,6 +10,7 @@
 #include "base/callback.h"
 #include "base/sequenced_task_runner.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
@@ -43,7 +44,7 @@
       mojom::URLLoaderClientPtrInfo client,
       const net::MutableNetworkTrafficAnnotationTag& traffic_annotation);
 
-  void Clone(mojom::URLLoaderFactoryRequest request);
+  void Clone(mojo::PendingReceiver<mojom::URLLoaderFactory> receiver);
 
   // Sequence |base_factory()| and |this| run on.
   base::SequencedTaskRunner* task_runner() const { return task_runner_.get(); }
@@ -86,7 +87,7 @@
                             mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) override;
 
   // SharedURLLoaderFactory implementation:
   std::unique_ptr<SharedURLLoaderFactoryInfo> Clone() override;
@@ -134,14 +135,14 @@
 }
 
 void CrossThreadSharedURLLoaderFactory::Clone(
-    mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   base::SequencedTaskRunner* runner = state_->task_runner();
   if (runner->RunsTasksInCurrentSequence()) {
-    state_->base_factory()->Clone(std::move(request));
+    state_->base_factory()->Clone(std::move(receiver));
   } else {
     state_->task_runner()->PostTask(
-        FROM_HERE, base::BindOnce(&State::Clone, state_, std::move(request)));
+        FROM_HERE, base::BindOnce(&State::Clone, state_, std::move(receiver)));
   }
 }
 
@@ -200,9 +201,9 @@
 }
 
 void CrossThreadSharedURLLoaderFactoryInfo::State::Clone(
-    mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  base_factory_->Clone(std::move(request));
+  base_factory_->Clone(std::move(receiver));
 }
 
 }  // namespace network
diff --git a/services/network/public/cpp/cross_thread_shared_url_loader_factory_info_unittest.cc b/services/network/public/cpp/cross_thread_shared_url_loader_factory_info_unittest.cc
index eb37b95..c520180c 100644
--- a/services/network/public/cpp/cross_thread_shared_url_loader_factory_info_unittest.cc
+++ b/services/network/public/cpp/cross_thread_shared_url_loader_factory_info_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/test/bind_test_util.h"
 #include "base/test/task_environment.h"
 #include "base/threading/sequenced_task_runner_handle.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/cpp/resource_response.h"
@@ -38,7 +39,7 @@
       scoped_refptr<base::SequencedTaskRunner> owning_thread)
       : owning_thread_(owning_thread) {}
 
-  void Clone(mojom::URLLoaderFactoryRequest request) override {
+  void Clone(mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) override {
     EXPECT_TRUE(owning_thread_->RunsTasksInCurrentSequence());
   }
 
diff --git a/services/network/public/cpp/shared_url_loader_factory.h b/services/network/public/cpp/shared_url_loader_factory.h
index 66c5b0f..8b1572e8 100644
--- a/services/network/public/cpp/shared_url_loader_factory.h
+++ b/services/network/public/cpp/shared_url_loader_factory.h
@@ -10,6 +10,7 @@
 #include "base/component_export.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
@@ -33,7 +34,8 @@
       std::unique_ptr<SharedURLLoaderFactoryInfo> info);
 
   // From mojom::URLLoaderFactory:
-  void Clone(mojom::URLLoaderFactoryRequest request) override = 0;
+  void Clone(mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) override =
+      0;
 
   // If implemented, creates a SharedURLLoaderFactoryInfo that can be used on
   // any thread to create a SharedURLLoaderFactory that works there.
diff --git a/services/network/public/cpp/simple_url_loader_unittest.cc b/services/network/public/cpp/simple_url_loader_unittest.cc
index bae914b..4159a774 100644
--- a/services/network/public/cpp/simple_url_loader_unittest.cc
+++ b/services/network/public/cpp/simple_url_loader_unittest.cc
@@ -2020,10 +2020,11 @@
     url_loader_queue_.push_back(url_loaders_.back().get());
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
-    mojo::BindingId id = binding_set_.AddBinding(this, std::move(request));
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
+    mojo::ReceiverId id = receiver_set_.Add(this, std::move(receiver));
     if (close_new_binding_on_clone_)
-      binding_set_.RemoveBinding(id);
+      receiver_set_.Remove(id);
   }
 
   // Makes clone fail close the newly created binding after bining the request,
@@ -2044,8 +2045,8 @@
   // Runs all events for all created URLLoaders, in order.
   void RunTest(SimpleLoaderTestHelper* test_helper,
                bool wait_for_completion = true) {
-    network::mojom::URLLoaderFactoryPtr factory;
-    binding_set_.AddBinding(this, mojo::MakeRequest(&factory));
+    mojo::Remote<network::mojom::URLLoaderFactory> factory;
+    receiver_set_.Add(this, factory.BindNewPipeAndPassReceiver());
 
     test_helper->StartSimpleLoader(factory.get());
 
@@ -2080,7 +2081,7 @@
 
   std::list<GURL> requested_urls_;
 
-  mojo::BindingSet<network::mojom::URLLoaderFactory> binding_set_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receiver_set_;
 
   DISALLOW_COPY_AND_ASSIGN(MockURLLoaderFactory);
 };
diff --git a/services/network/public/cpp/weak_wrapper_shared_url_loader_factory.cc b/services/network/public/cpp/weak_wrapper_shared_url_loader_factory.cc
index d124154..dbc97fc 100644
--- a/services/network/public/cpp/weak_wrapper_shared_url_loader_factory.cc
+++ b/services/network/public/cpp/weak_wrapper_shared_url_loader_factory.cc
@@ -38,10 +38,10 @@
 }
 
 void WeakWrapperSharedURLLoaderFactory::Clone(
-    mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) {
   if (!factory())
     return;
-  factory()->Clone(std::move(request));
+  factory()->Clone(std::move(receiver));
 }
 
 std::unique_ptr<network::SharedURLLoaderFactoryInfo>
diff --git a/services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h b/services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h
index 57089a6..98ba151 100644
--- a/services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h
+++ b/services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h
@@ -7,6 +7,7 @@
 
 #include "base/callback.h"
 #include "base/component_export.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
 
@@ -39,7 +40,7 @@
                             mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) override;
   std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override;
 
  private:
diff --git a/services/network/public/cpp/wrapper_shared_url_loader_factory.h b/services/network/public/cpp/wrapper_shared_url_loader_factory.h
index e0969c4..cc96471 100644
--- a/services/network/public/cpp/wrapper_shared_url_loader_factory.h
+++ b/services/network/public/cpp/wrapper_shared_url_loader_factory.h
@@ -6,6 +6,7 @@
 #define SERVICES_NETWORK_PUBLIC_CPP_WRAPPER_SHARED_URL_LOADER_FACTORY_H_
 
 #include "base/component_export.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
@@ -62,10 +63,11 @@
                                        std::move(client), traffic_annotation);
   }
 
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override {
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override {
     if (!factory_ptr_)
       return;
-    factory_ptr_->Clone(std::move(request));
+    factory_ptr_->Clone(std::move(receiver));
   }
 
   std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override {
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
index 20b2a70..ca9fef6 100644
--- a/services/network/public/mojom/network_context.mojom
+++ b/services/network/public/mojom/network_context.mojom
@@ -741,7 +741,7 @@
   SetClient(pending_remote<NetworkContextClient> client);
 
   // Creates a new URLLoaderFactory with the given |params|.
-  CreateURLLoaderFactory(URLLoaderFactory& url_loader_factory,
+  CreateURLLoaderFactory(pending_receiver<URLLoaderFactory> url_loader_factory,
                          URLLoaderFactoryParams params);
 
   // Destroys all URLLoaderFactory bindings, which should then be regenerated.
diff --git a/services/network/public/mojom/url_loader_factory.mojom b/services/network/public/mojom/url_loader_factory.mojom
index 19db323..93b06594e 100644
--- a/services/network/public/mojom/url_loader_factory.mojom
+++ b/services/network/public/mojom/url_loader_factory.mojom
@@ -44,5 +44,5 @@
                        MutableNetworkTrafficAnnotationTag traffic_annotation);
 
   // Connects a new pipe to this instance of the URLLoaderFactory interface.
-  Clone(URLLoaderFactory& factory);
+  Clone(pending_receiver<URLLoaderFactory> factory);
 };
diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h
index 978d40f7..97de3f2 100644
--- a/services/network/test/test_network_context.h
+++ b/services/network/test/test_network_context.h
@@ -45,7 +45,7 @@
   void SetClient(
       mojo::PendingRemote<mojom::NetworkContextClient> client) override {}
   void CreateURLLoaderFactory(
-      mojom::URLLoaderFactoryRequest request,
+      mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
       mojom::URLLoaderFactoryParamsPtr params) override {}
   void GetCookieManager(
       mojo::PendingReceiver<mojom::CookieManager> cookie_manager) override {}
diff --git a/services/network/test/test_shared_url_loader_factory.cc b/services/network/test/test_shared_url_loader_factory.cc
index 4fd1cd0..e20b42f 100644
--- a/services/network/test/test_shared_url_loader_factory.cc
+++ b/services/network/test/test_shared_url_loader_factory.cc
@@ -42,7 +42,8 @@
       std::move(client), traffic_annotation);
 }
 
-void TestSharedURLLoaderFactory::Clone(mojom::URLLoaderFactoryRequest request) {
+void TestSharedURLLoaderFactory::Clone(
+    mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) {
   NOTIMPLEMENTED();
 }
 
diff --git a/services/network/test/test_shared_url_loader_factory.h b/services/network/test/test_shared_url_loader_factory.h
index 8750e83..baa25f55 100644
--- a/services/network/test/test_shared_url_loader_factory.h
+++ b/services/network/test/test_shared_url_loader_factory.h
@@ -6,6 +6,7 @@
 #define SERVICES_NETWORK_TEST_TEST_SHARED_URL_LOADER_FACTORY_H_
 
 #include "base/macros.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
 namespace net {
@@ -36,7 +37,7 @@
                             mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) override;
 
   // SharedURLLoaderFactoryInfo implementation
   std::unique_ptr<SharedURLLoaderFactoryInfo> Clone() override;
diff --git a/services/network/test/test_url_loader_factory.cc b/services/network/test/test_url_loader_factory.cc
index 1187ca1e..4b8a426 100644
--- a/services/network/test/test_url_loader_factory.cc
+++ b/services/network/test/test_url_loader_factory.cc
@@ -135,8 +135,9 @@
   pending_requests_.push_back(std::move(pending_request));
 }
 
-void TestURLLoaderFactory::Clone(mojom::URLLoaderFactoryRequest request) {
-  bindings_.AddBinding(this, std::move(request));
+void TestURLLoaderFactory::Clone(
+    mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) {
+  receivers_.Add(this, std::move(receiver));
 }
 
 scoped_refptr<network::WeakWrapperSharedURLLoaderFactory>
diff --git a/services/network/test/test_url_loader_factory.h b/services/network/test/test_url_loader_factory.h
index bab4f6e..06da0bc 100644
--- a/services/network/test/test_url_loader_factory.h
+++ b/services/network/test/test_url_loader_factory.h
@@ -11,7 +11,8 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "net/http/http_status_code.h"
 #include "services/network/public/cpp/resource_request.h"
 #include "services/network/public/mojom/url_loader.mojom.h"
@@ -149,7 +150,7 @@
                             mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) override;
 
   // Returns a 'safe' ref-counted weak wrapper around this TestURLLoaderFactory
   // instance.
@@ -194,7 +195,7 @@
   scoped_refptr<network::WeakWrapperSharedURLLoaderFactory> weak_wrapper_;
 
   Interceptor interceptor_;
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   DISALLOW_COPY_AND_ASSIGN(TestURLLoaderFactory);
 };
diff --git a/services/network/url_loader_factory.cc b/services/network/url_loader_factory.cc
index e01d555..d8b8b8d7 100644
--- a/services/network/url_loader_factory.cc
+++ b/services/network/url_loader_factory.cc
@@ -151,7 +151,8 @@
   cors_url_loader_factory_->OnLoaderCreated(std::move(loader));
 }
 
-void URLLoaderFactory::Clone(mojom::URLLoaderFactoryRequest request) {
+void URLLoaderFactory::Clone(
+    mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) {
   NOTREACHED();
 }
 
diff --git a/services/network/url_loader_factory.h b/services/network/url_loader_factory.h
index 30bdfafd..d78f5af 100644
--- a/services/network/url_loader_factory.h
+++ b/services/network/url_loader_factory.h
@@ -10,6 +10,7 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "net/traffic_annotation/network_traffic_annotation.h"
 #include "services/network/public/mojom/network_context.mojom.h"
@@ -58,7 +59,7 @@
                             mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<mojom::URLLoaderFactory> receiver) override;
 
   static constexpr int kMaxKeepaliveConnections = 256;
   static constexpr int kMaxKeepaliveConnectionsPerProcess = 20;
diff --git a/services/shape_detection/barcode_detection_impl_mac_unittest.mm b/services/shape_detection/barcode_detection_impl_mac_unittest.mm
index e44a037..368fe04 100644
--- a/services/shape_detection/barcode_detection_impl_mac_unittest.mm
+++ b/services/shape_detection/barcode_detection_impl_mac_unittest.mm
@@ -178,9 +178,8 @@
   ASSERT_TRUE(SkCreateBitmapFromCGImage(&bitmap, cg_image));
 
   base::RunLoop run_loop;
-  base::Closure quit_closure = run_loop.QuitClosure();
   // Send the image Detect() and expect the response in callback.
-  EXPECT_CALL(*this, Detection()).WillOnce(RunClosure(quit_closure));
+  EXPECT_CALL(*this, Detection()).WillOnce(RunClosure(run_loop.QuitClosure()));
   // TODO(crbug.com/938663): expect detected symbology.
   impl_->Detect(bitmap,
                 base::BindOnce(&BarcodeDetectionImplMacTest::DetectCallback,
diff --git a/services/shape_detection/face_detection_impl_mac_unittest.mm b/services/shape_detection/face_detection_impl_mac_unittest.mm
index c9a00bb..e5d909de 100644
--- a/services/shape_detection/face_detection_impl_mac_unittest.mm
+++ b/services/shape_detection/face_detection_impl_mac_unittest.mm
@@ -52,7 +52,7 @@
 }
 
 using FaceDetectorFactory =
-    base::Callback<std::unique_ptr<mojom::FaceDetection>(
+    base::RepeatingCallback<std::unique_ptr<mojom::FaceDetection>(
         shape_detection::mojom::FaceDetectorOptionsPtr)>;
 
 struct TestParams {
@@ -70,32 +70,32 @@
   if (@available(macOS 10.14, *)) {
     return {
         {false, 120, 120, "services/test/data/mona_lisa.jpg", 1, 3, 1,
-         base::Bind(&CreateFaceDetectorImplMac)},
+         base::BindRepeating(&CreateFaceDetectorImplMac)},
         {true, 120, 120, "services/test/data/mona_lisa.jpg", 1, 3, 1,
-         base::Bind(&CreateFaceDetectorImplMac)},
+         base::BindRepeating(&CreateFaceDetectorImplMac)},
         {false, 120, 120, "services/test/data/mona_lisa.jpg", 1, 4, 10,
-         base::Bind(&CreateFaceDetectorImplMacVision)},
+         base::BindRepeating(&CreateFaceDetectorImplMacVision)},
         {false, 240, 240, "services/test/data/the_beatles.jpg", 4, 3, 1,
-         base::Bind(&CreateFaceDetectorImplMac)},
+         base::BindRepeating(&CreateFaceDetectorImplMac)},
         {true, 240, 240, "services/test/data/the_beatles.jpg", 4, 3, 1,
-         base::Bind(&CreateFaceDetectorImplMac)},
+         base::BindRepeating(&CreateFaceDetectorImplMac)},
         {false, 240, 240, "services/test/data/the_beatles.jpg", 4, 4, 10,
-         base::Bind(&CreateFaceDetectorImplMacVision)},
+         base::BindRepeating(&CreateFaceDetectorImplMacVision)},
     };
   } else {
     return {
         {false, 120, 120, "services/test/data/mona_lisa.jpg", 1, 3, 1,
-         base::Bind(&CreateFaceDetectorImplMac)},
+         base::BindRepeating(&CreateFaceDetectorImplMac)},
         {true, 120, 120, "services/test/data/mona_lisa.jpg", 1, 3, 1,
-         base::Bind(&CreateFaceDetectorImplMac)},
+         base::BindRepeating(&CreateFaceDetectorImplMac)},
         {false, 120, 120, "services/test/data/mona_lisa.jpg", 1, 4, 10,
-         base::Bind(&CreateFaceDetectorImplMacVision)},
+         base::BindRepeating(&CreateFaceDetectorImplMacVision)},
         {false, 240, 240, "services/test/data/the_beatles.jpg", 3, 3, 1,
-         base::Bind(&CreateFaceDetectorImplMac)},
+         base::BindRepeating(&CreateFaceDetectorImplMac)},
         {true, 240, 240, "services/test/data/the_beatles.jpg", 3, 3, 1,
-         base::Bind(&CreateFaceDetectorImplMac)},
+         base::BindRepeating(&CreateFaceDetectorImplMac)},
         {false, 240, 240, "services/test/data/the_beatles.jpg", 4, 4, 10,
-         base::Bind(&CreateFaceDetectorImplMacVision)},
+         base::BindRepeating(&CreateFaceDetectorImplMacVision)},
     };
   }
 }
@@ -186,9 +186,8 @@
   ASSERT_EQ(num_bytes, image->computeByteSize());
 
   base::RunLoop run_loop;
-  base::Closure quit_closure = run_loop.QuitClosure();
   // Send the image to Detect() and expect the response in callback.
-  EXPECT_CALL(*this, Detection()).WillOnce(RunClosure(quit_closure));
+  EXPECT_CALL(*this, Detection()).WillOnce(RunClosure(run_loop.QuitClosure()));
   impl_->Detect(
       *image,
       base::BindOnce(&FaceDetectionImplMacTest::DetectCallback,
diff --git a/services/shape_detection/face_detection_impl_win_unittest.cc b/services/shape_detection/face_detection_impl_win_unittest.cc
index 7489e64..4f279d6c1 100644
--- a/services/shape_detection/face_detection_impl_win_unittest.cc
+++ b/services/shape_detection/face_detection_impl_win_unittest.cc
@@ -24,11 +24,11 @@
 namespace shape_detection {
 
 namespace {
-void DetectCallback(base::Closure quit_closure,
+void DetectCallback(base::OnceClosure quit_closure,
                     uint32_t* num_faces,
                     std::vector<mojom::FaceDetectionResultPtr> results) {
   *num_faces = results.size();
-  quit_closure.Run();
+  std::move(quit_closure).Run();
 }
 }  // namespace
 
diff --git a/services/shape_detection/text_detection_impl_mac_unittest.mm b/services/shape_detection/text_detection_impl_mac_unittest.mm
index e6f9508..e476ddcb 100644
--- a/services/shape_detection/text_detection_impl_mac_unittest.mm
+++ b/services/shape_detection/text_detection_impl_mac_unittest.mm
@@ -90,11 +90,12 @@
     ASSERT_TRUE(SkCreateBitmapFromCGImage(&bitmap, cg_image));
 
     base::RunLoop run_loop;
-    base::Closure quit_closure = run_loop.QuitClosure();
     // Send the image to Detect() and expect the response in callback.
-    EXPECT_CALL(*this, Detection(1)).WillOnce(RunClosure(quit_closure));
-    impl_->Detect(bitmap, base::Bind(&TextDetectionImplMacTest::DetectCallback,
-                                     base::Unretained(this)));
+    EXPECT_CALL(*this, Detection(1))
+        .WillOnce(RunClosure(run_loop.QuitClosure()));
+    impl_->Detect(bitmap,
+                  base::BindOnce(&TextDetectionImplMacTest::DetectCallback,
+                                 base::Unretained(this)));
 
     run_loop.Run();
   }
diff --git a/services/shape_detection/text_detection_impl_win_unittest.cc b/services/shape_detection/text_detection_impl_win_unittest.cc
index 1b5522b9..b89f0de8 100644
--- a/services/shape_detection/text_detection_impl_win_unittest.cc
+++ b/services/shape_detection/text_detection_impl_win_unittest.cc
@@ -25,11 +25,11 @@
 
 namespace {
 
-void DetectTextCallback(base::Closure quit_closure,
+void DetectTextCallback(base::OnceClosure quit_closure,
                         std::vector<mojom::TextDetectionResultPtr>* results_out,
                         std::vector<mojom::TextDetectionResultPtr> results_in) {
   *results_out = std::move(results_in);
-  quit_closure.Run();
+  std::move(quit_closure).Run();
 }
 
 }  // namespace
diff --git a/storage/browser/blob/blob_url_loader_factory.cc b/storage/browser/blob/blob_url_loader_factory.cc
index 4c34edc3..85058b4 100644
--- a/storage/browser/blob/blob_url_loader_factory.cc
+++ b/storage/browser/blob/blob_url_loader_factory.cc
@@ -18,16 +18,17 @@
 // The mojo::Remote<BlobURLToken> parameter is passed in to make sure the
 // connection stays alive until this method is called, it is not otherwise used
 // by this method.
-void CreateFactoryForToken(mojo::Remote<blink::mojom::BlobURLToken>,
-                           const base::WeakPtr<BlobStorageContext>& context,
-                           network::mojom::URLLoaderFactoryRequest request,
-                           const base::UnguessableToken& token) {
+void CreateFactoryForToken(
+    mojo::Remote<blink::mojom::BlobURLToken>,
+    const base::WeakPtr<BlobStorageContext>& context,
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
+    const base::UnguessableToken& token) {
   mojo::PendingRemote<blink::mojom::Blob> blob;
   GURL blob_url;
   if (context)
     context->registry().GetTokenMapping(token, &blob_url, &blob);
   BlobURLLoaderFactory::Create(std::move(blob), blob_url, context,
-                               std::move(request));
+                               std::move(receiver));
 }
 
 }  // namespace
@@ -37,13 +38,13 @@
     mojo::PendingRemote<blink::mojom::Blob> pending_blob,
     const GURL& blob_url,
     base::WeakPtr<BlobStorageContext> context,
-    network::mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   if (!pending_blob) {
-    new BlobURLLoaderFactory(nullptr, blob_url, std::move(request));
+    new BlobURLLoaderFactory(nullptr, blob_url, std::move(receiver));
     return;
   }
   // Not every URLLoaderFactory user deals with the URLLoaderFactory simply
-  // disconnecting very well, so make sure we always at least bind the request
+  // disconnecting very well, so make sure we always at least bind the receiver
   // to some factory that can then fail with a network error. Hence the callback
   // is wrapped in WrapCallbackWithDefaultInvokeIfNotRun.
   mojo::Remote<blink::mojom::Blob> blob(std::move(pending_blob));
@@ -52,15 +53,15 @@
       base::BindOnce(
           [](mojo::Remote<blink::mojom::Blob>,
              base::WeakPtr<BlobStorageContext> context, const GURL& blob_url,
-             network::mojom::URLLoaderFactoryRequest request,
+             mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
              const std::string& uuid) {
             std::unique_ptr<BlobDataHandle> blob;
             if (context)
               blob = context->GetBlobDataFromUUID(uuid);
             new BlobURLLoaderFactory(std::move(blob), blob_url,
-                                     std::move(request));
+                                     std::move(receiver));
           },
-          std::move(blob), std::move(context), blob_url, std::move(request)),
+          std::move(blob), std::move(context), blob_url, std::move(receiver)),
       ""));
 }
 
@@ -68,16 +69,16 @@
 void BlobURLLoaderFactory::Create(
     mojo::PendingRemote<blink::mojom::BlobURLToken> token,
     base::WeakPtr<BlobStorageContext> context,
-    network::mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   // Not every URLLoaderFactory user deals with the URLLoaderFactory simply
-  // disconnecting very well, so make sure we always at least bind the request
+  // disconnecting very well, so make sure we always at least bind the receiver
   // to some factory that can then fail with a network error. Hence the callback
   // is wrapped in WrapCallbackWithDefaultInvokeIfNotRun.
   mojo::Remote<blink::mojom::BlobURLToken> token_remote(std::move(token));
   auto* raw_token = token_remote.get();
   raw_token->GetToken(mojo::WrapCallbackWithDefaultInvokeIfNotRun(
       base::BindOnce(&CreateFactoryForToken, std::move(token_remote),
-                     std::move(context), std::move(request)),
+                     std::move(context), std::move(receiver)),
       base::UnguessableToken()));
 }
 
@@ -90,7 +91,7 @@
     network::mojom::URLLoaderClientPtr client,
     const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
   if (url_.is_valid() && request.url != url_) {
-    bindings_.ReportBadMessage("Invalid URL when attempting to fetch Blob");
+    receivers_.ReportBadMessage("Invalid URL when attempting to fetch Blob");
     client->OnComplete(
         network::URLLoaderCompletionStatus(net::ERR_INVALID_URL));
     return;
@@ -101,24 +102,24 @@
 }
 
 void BlobURLLoaderFactory::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
-  bindings_.AddBinding(this, std::move(request));
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
+  receivers_.Add(this, std::move(receiver));
 }
 
 BlobURLLoaderFactory::BlobURLLoaderFactory(
     std::unique_ptr<BlobDataHandle> handle,
     const GURL& blob_url,
-    network::mojom::URLLoaderFactoryRequest request)
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
     : handle_(std::move(handle)), url_(blob_url) {
-  bindings_.AddBinding(this, std::move(request));
-  bindings_.set_connection_error_handler(base::BindRepeating(
+  receivers_.Add(this, std::move(receiver));
+  receivers_.set_disconnect_handler(base::BindRepeating(
       &BlobURLLoaderFactory::OnConnectionError, base::Unretained(this)));
 }
 
 BlobURLLoaderFactory::~BlobURLLoaderFactory() = default;
 
 void BlobURLLoaderFactory::OnConnectionError() {
-  if (!bindings_.empty())
+  if (!receivers_.empty())
     return;
   delete this;
 }
diff --git a/storage/browser/blob/blob_url_loader_factory.h b/storage/browser/blob/blob_url_loader_factory.h
index e8600ba..c4ac5c2d 100644
--- a/storage/browser/blob/blob_url_loader_factory.h
+++ b/storage/browser/blob/blob_url_loader_factory.h
@@ -6,7 +6,8 @@
 #define STORAGE_BROWSER_BLOB_BLOB_URL_LOADER_FACTORY_H_
 
 #include "base/component_export.h"
-#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
 #include "third_party/blink/public/mojom/blob/blob_url_store.mojom.h"
 
@@ -21,17 +22,19 @@
 class COMPONENT_EXPORT(STORAGE_BROWSER) BlobURLLoaderFactory
     : public network::mojom::URLLoaderFactory {
  public:
-  static void Create(mojo::PendingRemote<blink::mojom::Blob> blob,
-                     const GURL& blob_url,
-                     base::WeakPtr<BlobStorageContext> context,
-                     network::mojom::URLLoaderFactoryRequest request);
+  static void Create(
+      mojo::PendingRemote<blink::mojom::Blob> blob,
+      const GURL& blob_url,
+      base::WeakPtr<BlobStorageContext> context,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver);
 
   // Creates a factory for a BlobURLToken. The token is used to look up the blob
   // and blob URL in the (browser side) BlobStorageRegistry, to ensure you can't
   // use a blob URL to load the contents of an unrelated blob.
-  static void Create(mojo::PendingRemote<blink::mojom::BlobURLToken> token,
-                     base::WeakPtr<BlobStorageContext> context,
-                     network::mojom::URLLoaderFactoryRequest request);
+  static void Create(
+      mojo::PendingRemote<blink::mojom::BlobURLToken> token,
+      base::WeakPtr<BlobStorageContext> context,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver);
 
   // URLLoaderFactory:
   void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader,
@@ -42,19 +45,21 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
 
  private:
-  BlobURLLoaderFactory(std::unique_ptr<BlobDataHandle> handle,
-                       const GURL& blob_url,
-                       network::mojom::URLLoaderFactoryRequest request);
+  BlobURLLoaderFactory(
+      std::unique_ptr<BlobDataHandle> handle,
+      const GURL& blob_url,
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver);
   ~BlobURLLoaderFactory() override;
   void OnConnectionError();
 
   std::unique_ptr<BlobDataHandle> handle_;
   GURL url_;
 
-  mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_;
+  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
 
   DISALLOW_COPY_AND_ASSIGN(BlobURLLoaderFactory);
 };
diff --git a/storage/browser/blob/blob_url_store_impl.cc b/storage/browser/blob/blob_url_store_impl.cc
index 3bbff15..a79f0b0 100644
--- a/storage/browser/blob/blob_url_store_impl.cc
+++ b/storage/browser/blob/blob_url_store_impl.cc
@@ -5,7 +5,6 @@
 #include "storage/browser/blob/blob_url_store_impl.h"
 
 #include "base/bind.h"
-#include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver_set.h"
 #include "storage/browser/blob/blob_impl.h"
 #include "storage/browser/blob/blob_storage_context.h"
@@ -140,10 +139,10 @@
 
 void BlobURLStoreImpl::ResolveAsURLLoaderFactory(
     const GURL& url,
-    network::mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   BlobURLLoaderFactory::Create(
       context_ ? context_->GetBlobFromPublicURL(url) : mojo::NullRemote(), url,
-      context_, std::move(request));
+      context_, std::move(receiver));
 }
 
 void BlobURLStoreImpl::ResolveForNavigation(
diff --git a/storage/browser/blob/blob_url_store_impl.h b/storage/browser/blob/blob_url_store_impl.h
index 9565d76..90223c75 100644
--- a/storage/browser/blob/blob_url_store_impl.h
+++ b/storage/browser/blob/blob_url_store_impl.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/component_export.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "storage/browser/blob/blob_registry_impl.h"
@@ -31,7 +32,8 @@
   void Resolve(const GURL& url, ResolveCallback callback) override;
   void ResolveAsURLLoaderFactory(
       const GURL& url,
-      network::mojom::URLLoaderFactoryRequest request) override;
+      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
   void ResolveForNavigation(
       const GURL& url,
       mojo::PendingReceiver<blink::mojom::BlobURLToken> token) override;
diff --git a/testing/buildbot/filters/bfcache.chrome_public_test_apk.filter b/testing/buildbot/filters/bfcache.chrome_public_test_apk.filter
index 891db3e..4946795 100644
--- a/testing/buildbot/filters/bfcache.chrome_public_test_apk.filter
+++ b/testing/buildbot/filters/bfcache.chrome_public_test_apk.filter
@@ -31,4 +31,4 @@
 
 # Autofill / password manager.
 # https://crbug.com/1011799
--org.chromium.chrome.browser.password_manager.OnboardingDialogIntegrationTest.testOnboardingDismissedPressedBack
+-org.chromium.chrome.browser.password_manager.OnboardingDialogIntegrationTest.*
diff --git a/third_party/axe-core/README.chromium b/third_party/axe-core/README.chromium
index 7697284..54f5507 100644
--- a/third_party/axe-core/README.chromium
+++ b/third_party/axe-core/README.chromium
@@ -1,9 +1,9 @@
 Name: AXE-CORE Accessibility Audit
 Short Name: axe-core
 URL: https://github.com/dequelabs/axe-core/
-Version: 0
-Date: Mon Jul 24 12:17:05 2017
-Revision: d02dba3223fefe525438330e40b5da5de81eeeb5
+Version: 3.3.2
+Date: Thur Aug 22 12:45:00 2019
+Revision: 281653df3794f429b71327fe3afa37ca0fadb1c7
 License: MPL 2.0
 License File: LICENSE
 Security Critical: no
diff --git a/third_party/axe-core/axe.d.ts b/third_party/axe-core/axe.d.ts
index 258cf3dc..b68b2c6 100644
--- a/third_party/axe-core/axe.d.ts
+++ b/third_party/axe-core/axe.d.ts
@@ -1,169 +1,224 @@
-// Type definitions for axe-core 2.3.1
+// Type definitions for axe-core
 // Project: https://github.com/dequelabs/axe-core
 // Definitions by: Marcy Sutton <https://github.com/marcysutton>
 
-declare module axe {
+declare namespace axe {
+	type ImpactValue = 'minor' | 'moderate' | 'serious' | 'critical';
 
-	type ImpactValue = "minor" | "moderate" | "serious" | "critical";
+	type TagValue = 'wcag2a' | 'wcag2aa' | 'section508' | 'best-practice';
 
-	type TagValue = "wcag2a" | "wcag2aa" | "section508" | "best-practice";
+	type ReporterVersion = 'v1' | 'v2' | 'raw' | 'raw-env' | 'no-passes';
 
-	type ReporterVersion = "v1" | "v2";
+	type RunOnlyType = 'rule' | 'rules' | 'tag' | 'tags';
 
-	type RunOnlyType = "rule" | "rules" | "tag" | "tags";
+	type resultGroups = 'inapplicable' | 'passes' | 'incomplete' | 'violations';
 
-	interface ElementContext {
-		node?: Object,
-		selector?: string,
-		include?: any[],
-		exclude?: any[]
+	type RunOnlyObject = {
+		include?: string[] | string[][];
+		exclude?: string[] | string[][];
+	};
+
+	type RunCallback = (error: Error, results: AxeResults) => void;
+
+	type ElementContext = Node | string | RunOnlyObject;
+
+	interface TestEngine {
+		name: string;
+		version: string;
+	}
+	interface TestRunner {
+		name: string;
+	}
+	interface TestEnvironment {
+		userAgent: string;
+		windowWidth: number;
+		windowHeight: number;
+		orientationAngle?: number;
+		orientationType?: string;
 	}
 	interface RunOnly {
-		type: RunOnlyType,
-		value?: {
-			include?: string[],
-			exclude?: string[]
-		}
-		values?: TagValue[]
+		type: RunOnlyType;
+		values?: TagValue[] | string[] | RunOnlyObject;
+	}
+	interface RunOptions {
+		runOnly?: RunOnly;
+		rules?: Object;
+		iframes?: boolean;
+		elementRef?: boolean;
+		selectors?: boolean;
+		resultTypes?: resultGroups[];
+		reporter?: ReporterVersion;
+		xpath?: boolean;
+		absolutePaths?: boolean;
+		restoreScroll?: boolean;
+		frameWaitTime?: number;
+		preload?: boolean;
+		performanceTimer?: boolean;
 	}
 	interface AxeResults {
-		url: string,
-		timestamp: string,
-		passes: Result[],
-		violations: Result[],
-		incomplete: Result[],
-		inapplicable: Result[]
+		toolOptions: RunOptions;
+		testEngine: TestEngine;
+		testRunner: TestRunner;
+		testEnvironment: TestEnvironment;
+		url: string;
+		timestamp: string;
+		passes: Result[];
+		violations: Result[];
+		incomplete: Result[];
+		inapplicable: Result[];
 	}
 	interface Result {
-		description: string,
-		help: string,
-		helpUrl: string,
-		id: string,
-		impact: ImpactValue,
-		tags: TagValue[],
-		nodes: NodeResult[]
+		description: string;
+		help: string;
+		helpUrl: string;
+		id: string;
+		impact?: ImpactValue;
+		tags: TagValue[];
+		nodes: NodeResult[];
 	}
 	interface NodeResult {
-		html: string,
-		impact: ImpactValue,
-		target: string[],
-		any: CheckResult[],
-		all: CheckResult[],
-		none: CheckResult[],
-		failureSummary?: string
+		html: string;
+		impact?: ImpactValue;
+		target: string[];
+		xpath?: string[];
+		any: CheckResult[];
+		all: CheckResult[];
+		none: CheckResult[];
+		failureSummary?: string;
 	}
 	interface CheckResult {
-		id: string,
-		impact: string,
-		message: string,
-		data: any,
-		relatedNodes?: RelatedNode[]
+		id: string;
+		impact: string;
+		message: string;
+		data: any;
+		relatedNodes?: RelatedNode[];
 	}
 	interface RelatedNode {
-		target: string[],
-		html: string
+		target: string[];
+		html: string;
+	}
+	interface RuleLocale {
+		[key: string]: {
+			description: string;
+			help: string;
+		};
+	}
+	interface CheckLocale {
+		[key: string]: {
+			pass: string;
+			fail: string;
+			incomplete: string | { [key: string]: string };
+		};
+	}
+	interface Locale {
+		lang?: string;
+		rules?: RuleLocale;
+		checks?: CheckLocale;
 	}
 	interface Spec {
 		branding?: {
-			brand: string,
-			application: string
-		},
-		reporter?: ReporterVersion,
-		checks?: Check[],
-		rules?: Rule[]
+			brand?: string;
+			application?: string;
+		};
+		reporter?: ReporterVersion;
+		checks?: Check[];
+		rules?: Rule[];
+		locale?: Locale;
 	}
 	interface Check {
-		id: string,
-		evaluate: Function,
-		after?: Function,
-		options?: any,
-		matches?: string,
-		enabled?: boolean
+		id: string;
+		evaluate: Function | string;
+		after?: Function | string;
+		options?: any;
+		matches?: string;
+		enabled?: boolean;
 	}
 	interface Rule {
-		id: string,
-		selector?: string,
-		excludeHidden?: boolean,
-		enabled?: boolean,
-		pageLevel?: boolean,
-		any?: string[],
-		all?: string[],
-		none?: string[],
-		tags?: string[],
-		matches?: string
+		id: string;
+		selector?: string;
+		excludeHidden?: boolean;
+		enabled?: boolean;
+		pageLevel?: boolean;
+		any?: string[];
+		all?: string[];
+		none?: string[];
+		tags?: string[];
+		matches?: string;
 	}
 	interface AxePlugin {
-		id: string,
-		run(...args:any[]): any,
+		id: string;
+		run(...args: any[]): any;
 		commands: {
-			id: string,
-			callback(...args:any[]): void
-		}[],
-		cleanup?(callback:Function): void
+			id: string;
+			callback(...args: any[]): void;
+		}[];
+		cleanup?(callback: Function): void;
 	}
 
-	let plugins: any
+	let plugins: any;
 
 	/**
 	 * Source string to use as an injected script in Selenium
 	 */
-	let source: string
+	let source: string;
 
 	/**
-	 * Object for aXe Results
+	 * Object for axe Results
 	 */
-	var AxeResults: AxeResults
+	var AxeResults: AxeResults;
 
 	/**
 	 * Runs a number of rules against the provided HTML page and returns the resulting issue list
 	 *
-	 * @param  {Object}   context  Optional The `Context` specification object @see Context
-	 * @param  {Array}    options  Optional Options passed into rules or checks, temporarily modifying them.
-	 * @param  {Function} callback Optional The function to invoke when analysis is complete.
-	 * @returns {any}  	  results  If the callback was not defined, aXe will return a Promise instead.
+	 * @param   {ElementContext} context  Optional The `Context` specification object @see Context
+	 * @param   {RunOptions}     options  Optional Options passed into rules or checks, temporarily modifying them.
+	 * @param   {RunCallback}    callback Optional The function to invoke when analysis is complete.
+	 * @returns {Promise<AxeResults>|void} If the callback was not defined, axe will return a Promise.
 	 */
-	function run(context?: ElementContext, options?: {runOnly?: RunOnly, rules?: Object, iframes?: Boolean, elementRef?: Boolean, selectors?: Boolean}, callback?: (error: Error, results:AxeResults) => void): any
+	function run(context?: ElementContext): Promise<AxeResults>;
+	function run(options: RunOptions): Promise<AxeResults>;
+	function run(callback: (error: Error, results: AxeResults) => void): void;
+	function run(context: ElementContext, callback: RunCallback): void;
+	function run(options: RunOptions, callback: RunCallback): void;
+	function run(
+		context: ElementContext,
+		options: RunOptions
+	): Promise<AxeResults>;
+	function run(
+		context: ElementContext,
+		options: RunOptions,
+		callback: RunCallback
+	): void;
 
 	/**
-	 * Starts analysis on the current document and its subframes
-	 *
-	 * @param  {Object}   context  The `Context` specification object @see Context
-	 * @param  {Array}    options  Options passed into rules or checks, temporarily modifyint them.
-	 * @param  {Function} callback The function to invoke when analysis is complete.
-	 * @returns {Object}  results  The aXe results object
-	 */
-	function a11yCheck(context: ElementContext, options: {runOnly?: RunOnly, rules?: Object, iframes?: Boolean, elementRef?: Boolean, selectors?: Boolean}, callback: (results:AxeResults) => void): AxeResults
-
-	/**
-	 * Method for configuring the data format used by aXe. Helpful for adding new
+	 * Method for configuring the data format used by axe. Helpful for adding new
 	 * rules, which must be registered with the library to execute.
 	 * @param  {Spec}       Spec Object with valid `branding`, `reporter`, `checks` and `rules` data
 	 */
-	function configure(spec: Spec): void
+	function configure(spec: Spec): void;
 
 	/**
 	 * Searches and returns rules that contain a tag in the list of tags.
 	 * @param  {Array}  tags  Optional array of tags
 	 * @return {Array}  Array of rules
 	 */
-	function getRules(tags?: string[]): Object[]
+	function getRules(tags?: string[]): Object[];
 
 	/**
 	 * Restores the default axe configuration
 	 */
-	function reset(): void
+	function reset(): void;
 
 	/**
 	 * Function to register a plugin configuration in document and its subframes
 	 * @param  {Object}    plugin    A plugin configuration object
 	 */
-	function registerPlugin(plugin: AxePlugin): void
+	function registerPlugin(plugin: AxePlugin): void;
 
 	/**
 	 * Function to clean up plugin configuration in document and its subframes
 	 */
-	function cleanup(): void
-
+	function cleanup(): void;
 }
 
 export = axe;
diff --git a/third_party/axe-core/axe.js b/third_party/axe-core/axe.js
index 2e2c746b..3b7cfe6 100644
--- a/third_party/axe-core/axe.js
+++ b/third_party/axe-core/axe.js
@@ -1,5 +1,5 @@
-/*! aXe v3.0.0-alpha-1
- * Copyright (c) 2017 Deque Systems, Inc.
+/*! axe v3.3.2
+ * Copyright (c) 2019 Deque Systems, Inc.
  *
  * Your use of this Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -13,15 +13,22 @@
   var global = window;
   var document = window.document;
   'use strict';
-  var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-    return typeof obj;
-  } : function(obj) {
-    return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-  };
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
   var axe = axe || {};
-  axe.version = '3.0.0-alpha-1';
+  axe.version = '3.3.2';
   if (typeof define === 'function' && define.amd) {
-    define([], function() {
+    define('axe-core', [], function() {
       'use strict';
       return axe;
     });
@@ -37,25 +44,2496 @@
   function SupportError(error) {
     this.name = 'SupportError';
     this.cause = error.cause;
-    this.message = '`' + error.cause + '` - feature unsupported in your environment.';
+    this.message = '`'.concat(error.cause, '` - feature unsupported in your environment.');
     if (error.ruleId) {
       this.ruleId = error.ruleId;
-      this.message += ' Skipping ' + this.ruleId + ' rule.';
+      this.message += ' Skipping '.concat(this.ruleId, ' rule.');
     }
     this.stack = new Error().stack;
   }
   SupportError.prototype = Object.create(Error.prototype);
   SupportError.prototype.constructor = SupportError;
+  (function() {
+    function r(e, n, t) {
+      function o(i, f) {
+        if (!n[i]) {
+          if (!e[i]) {
+            var c = 'function' == typeof require && require;
+            if (!f && c) {
+              return c(i, !0);
+            }
+            if (u) {
+              return u(i, !0);
+            }
+            var a = new Error('Cannot find module \'' + i + '\'');
+            throw a.code = 'MODULE_NOT_FOUND', a;
+          }
+          var p = n[i] = {
+            exports: {}
+          };
+          e[i][0].call(p.exports, function(r) {
+            var n = e[i][1][r];
+            return o(n || r);
+          }, p, p.exports, r, e, n, t);
+        }
+        return n[i].exports;
+      }
+      for (var u = 'function' == typeof require && require, i = 0; i < t.length; i++) {
+        o(t[i]);
+      }
+      return o;
+    }
+    return r;
+  })()({
+    1: [ function(_dereq_, module, exports) {
+      if (!('Promise' in window)) {
+        _dereq_('es6-promise').polyfill();
+      }
+      _dereq_('weakmap-polyfill');
+      axe.imports = {
+        axios: _dereq_('axios'),
+        CssSelectorParser: _dereq_('css-selector-parser').CssSelectorParser,
+        doT: _dereq_('@deque/dot'),
+        emojiRegexText: _dereq_('emoji-regex')
+      };
+    }, {
+      '@deque/dot': 2,
+      axios: 3,
+      'css-selector-parser': 29,
+      'emoji-regex': 31,
+      'es6-promise': 32,
+      'weakmap-polyfill': 34
+    } ],
+    2: [ function(_dereq_, module, exports) {
+      (function() {
+        'use strict';
+        var doT = {
+          name: 'doT',
+          version: '1.1.1',
+          templateSettings: {
+            evaluate: /\{\{([\s\S]+?(\}?)+)\}\}/g,
+            interpolate: /\{\{=([\s\S]+?)\}\}/g,
+            encode: /\{\{!([\s\S]+?)\}\}/g,
+            use: /\{\{#([\s\S]+?)\}\}/g,
+            useParams: /(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,
+            define: /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,
+            defineParams: /^\s*([\w$]+):([\s\S]+)/,
+            conditional: /\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,
+            iterate: /\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,
+            varname: 'it',
+            strip: true,
+            append: true,
+            selfcontained: false,
+            doNotSkipEncoded: false
+          },
+          template: undefined,
+          compile: undefined,
+          log: true
+        };
+        (function() {
+          if (typeof globalThis === 'object') {
+            return;
+          }
+          Object.defineProperty(Object.prototype, '__magic__', {
+            get: function() {
+              return this;
+            },
+            configurable: true
+          });
+          __magic__.globalThis = __magic__;
+          delete Object.prototype.__magic__;
+        })();
+        doT.encodeHTMLSource = function(doNotSkipEncoded) {
+          var encodeHTMLRules = {
+            '&': '&#38;',
+            '<': '&#60;',
+            '>': '&#62;',
+            '"': '&#34;',
+            '\'': '&#39;',
+            '/': '&#47;'
+          }, matchHTML = doNotSkipEncoded ? /[&<>"'\/]/g : /&(?!#?\w+;)|<|>|"|'|\//g;
+          return function(code) {
+            return code ? code.toString().replace(matchHTML, function(m) {
+              return encodeHTMLRules[m] || m;
+            }) : '';
+          };
+        };
+        if (typeof module !== 'undefined' && module.exports) {
+          module.exports = doT;
+        } else if (typeof define === 'function' && define.amd) {
+          define(function() {
+            return doT;
+          });
+        } else {
+          globalThis.doT = doT;
+        }
+        var startend = {
+          append: {
+            start: '\'+(',
+            end: ')+\'',
+            startencode: '\'+encodeHTML('
+          },
+          split: {
+            start: '\';out+=(',
+            end: ');out+=\'',
+            startencode: '\';out+=encodeHTML('
+          }
+        }, skip = /$^/;
+        function resolveDefs(c, block, def) {
+          return (typeof block === 'string' ? block : block.toString()).replace(c.define || skip, function(m, code, assign, value) {
+            if (code.indexOf('def.') === 0) {
+              code = code.substring(4);
+            }
+            if (!(code in def)) {
+              if (assign === ':') {
+                if (c.defineParams) {
+                  value.replace(c.defineParams, function(m, param, v) {
+                    def[code] = {
+                      arg: param,
+                      text: v
+                    };
+                  });
+                }
+                if (!(code in def)) {
+                  def[code] = value;
+                }
+              } else {
+                new Function('def', 'def[\'' + code + '\']=' + value)(def);
+              }
+            }
+            return '';
+          }).replace(c.use || skip, function(m, code) {
+            if (c.useParams) {
+              code = code.replace(c.useParams, function(m, s, d, param) {
+                if (def[d] && def[d].arg && param) {
+                  var rw = (d + ':' + param).replace(/'|\\/g, '_');
+                  def.__exp = def.__exp || {};
+                  def.__exp[rw] = def[d].text.replace(new RegExp('(^|[^\\w$])' + def[d].arg + '([^\\w$])', 'g'), '$1' + param + '$2');
+                  return s + 'def.__exp[\'' + rw + '\']';
+                }
+              });
+            }
+            var v = new Function('def', 'return ' + code)(def);
+            return v ? resolveDefs(c, v, def) : v;
+          });
+        }
+        function unescape(code) {
+          return code.replace(/\\('|\\)/g, '$1').replace(/[\r\t\n]/g, ' ');
+        }
+        doT.template = function(tmpl, c, def) {
+          c = c || doT.templateSettings;
+          var cse = c.append ? startend.append : startend.split, needhtmlencode, sid = 0, indv, str = c.use || c.define ? resolveDefs(c, tmpl, def || {}) : tmpl;
+          str = ('var out=\'' + (c.strip ? str.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g, ' ').replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g, '') : str).replace(/'|\\/g, '\\$&').replace(c.interpolate || skip, function(m, code) {
+            return cse.start + unescape(code) + cse.end;
+          }).replace(c.encode || skip, function(m, code) {
+            needhtmlencode = true;
+            return cse.startencode + unescape(code) + cse.end;
+          }).replace(c.conditional || skip, function(m, elsecase, code) {
+            return elsecase ? code ? '\';}else if(' + unescape(code) + '){out+=\'' : '\';}else{out+=\'' : code ? '\';if(' + unescape(code) + '){out+=\'' : '\';}out+=\'';
+          }).replace(c.iterate || skip, function(m, iterate, vname, iname) {
+            if (!iterate) {
+              return '\';} } out+=\'';
+            }
+            sid += 1;
+            indv = iname || 'i' + sid;
+            iterate = unescape(iterate);
+            return '\';var arr' + sid + '=' + iterate + ';if(arr' + sid + '){var ' + vname + ',' + indv + '=-1,l' + sid + '=arr' + sid + '.length-1;while(' + indv + '<l' + sid + '){' + vname + '=arr' + sid + '[' + indv + '+=1];out+=\'';
+          }).replace(c.evaluate || skip, function(m, code) {
+            return '\';' + unescape(code) + 'out+=\'';
+          }) + '\';return out;').replace(/\n/g, '\\n').replace(/\t/g, '\\t').replace(/\r/g, '\\r').replace(/(\s|;|\}|^|\{)out\+='';/g, '$1').replace(/\+''/g, '');
+          if (needhtmlencode) {
+            if (!c.selfcontained && globalThis && !globalThis._encodeHTML) {
+              globalThis._encodeHTML = doT.encodeHTMLSource(c.doNotSkipEncoded);
+            }
+            str = 'var encodeHTML = typeof _encodeHTML !== \'undefined\' ? _encodeHTML : (' + doT.encodeHTMLSource.toString() + '(' + (c.doNotSkipEncoded || '') + '));' + str;
+          }
+          try {
+            return new Function(c.varname, str);
+          } catch (e) {
+            if (typeof console !== 'undefined') {
+              console.log('Could not create a template function: ' + str);
+            }
+            throw e;
+          }
+        };
+        doT.compile = function(tmpl, def) {
+          return doT.template(tmpl, null, def);
+        };
+      })();
+    }, {} ],
+    3: [ function(_dereq_, module, exports) {
+      module.exports = _dereq_('./lib/axios');
+    }, {
+      './lib/axios': 5
+    } ],
+    4: [ function(_dereq_, module, exports) {
+      'use strict';
+      var utils = _dereq_('./../utils');
+      var settle = _dereq_('./../core/settle');
+      var buildURL = _dereq_('./../helpers/buildURL');
+      var parseHeaders = _dereq_('./../helpers/parseHeaders');
+      var isURLSameOrigin = _dereq_('./../helpers/isURLSameOrigin');
+      var createError = _dereq_('../core/createError');
+      module.exports = function xhrAdapter(config) {
+        return new Promise(function dispatchXhrRequest(resolve, reject) {
+          var requestData = config.data;
+          var requestHeaders = config.headers;
+          if (utils.isFormData(requestData)) {
+            delete requestHeaders['Content-Type'];
+          }
+          var request = new XMLHttpRequest();
+          if (config.auth) {
+            var username = config.auth.username || '';
+            var password = config.auth.password || '';
+            requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);
+          }
+          request.open(config.method.toUpperCase(), buildURL(config.url, config.params, config.paramsSerializer), true);
+          request.timeout = config.timeout;
+          request.onreadystatechange = function handleLoad() {
+            if (!request || request.readyState !== 4) {
+              return;
+            }
+            if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {
+              return;
+            }
+            var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;
+            var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response;
+            var response = {
+              data: responseData,
+              status: request.status,
+              statusText: request.statusText,
+              headers: responseHeaders,
+              config: config,
+              request: request
+            };
+            settle(resolve, reject, response);
+            request = null;
+          };
+          request.onabort = function handleAbort() {
+            if (!request) {
+              return;
+            }
+            reject(createError('Request aborted', config, 'ECONNABORTED', request));
+            request = null;
+          };
+          request.onerror = function handleError() {
+            reject(createError('Network Error', config, null, request));
+            request = null;
+          };
+          request.ontimeout = function handleTimeout() {
+            reject(createError('timeout of ' + config.timeout + 'ms exceeded', config, 'ECONNABORTED', request));
+            request = null;
+          };
+          if (utils.isStandardBrowserEnv()) {
+            var cookies = _dereq_('./../helpers/cookies');
+            var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ? cookies.read(config.xsrfCookieName) : undefined;
+            if (xsrfValue) {
+              requestHeaders[config.xsrfHeaderName] = xsrfValue;
+            }
+          }
+          if ('setRequestHeader' in request) {
+            utils.forEach(requestHeaders, function setRequestHeader(val, key) {
+              if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
+                delete requestHeaders[key];
+              } else {
+                request.setRequestHeader(key, val);
+              }
+            });
+          }
+          if (config.withCredentials) {
+            request.withCredentials = true;
+          }
+          if (config.responseType) {
+            try {
+              request.responseType = config.responseType;
+            } catch (e) {
+              if (config.responseType !== 'json') {
+                throw e;
+              }
+            }
+          }
+          if (typeof config.onDownloadProgress === 'function') {
+            request.addEventListener('progress', config.onDownloadProgress);
+          }
+          if (typeof config.onUploadProgress === 'function' && request.upload) {
+            request.upload.addEventListener('progress', config.onUploadProgress);
+          }
+          if (config.cancelToken) {
+            config.cancelToken.promise.then(function onCanceled(cancel) {
+              if (!request) {
+                return;
+              }
+              request.abort();
+              reject(cancel);
+              request = null;
+            });
+          }
+          if (requestData === undefined) {
+            requestData = null;
+          }
+          request.send(requestData);
+        });
+      };
+    }, {
+      '../core/createError': 11,
+      './../core/settle': 15,
+      './../helpers/buildURL': 19,
+      './../helpers/cookies': 21,
+      './../helpers/isURLSameOrigin': 23,
+      './../helpers/parseHeaders': 25,
+      './../utils': 27
+    } ],
+    5: [ function(_dereq_, module, exports) {
+      'use strict';
+      var utils = _dereq_('./utils');
+      var bind = _dereq_('./helpers/bind');
+      var Axios = _dereq_('./core/Axios');
+      var mergeConfig = _dereq_('./core/mergeConfig');
+      var defaults = _dereq_('./defaults');
+      function createInstance(defaultConfig) {
+        var context = new Axios(defaultConfig);
+        var instance = bind(Axios.prototype.request, context);
+        utils.extend(instance, Axios.prototype, context);
+        utils.extend(instance, context);
+        return instance;
+      }
+      var axios = createInstance(defaults);
+      axios.Axios = Axios;
+      axios.create = function create(instanceConfig) {
+        return createInstance(mergeConfig(axios.defaults, instanceConfig));
+      };
+      axios.Cancel = _dereq_('./cancel/Cancel');
+      axios.CancelToken = _dereq_('./cancel/CancelToken');
+      axios.isCancel = _dereq_('./cancel/isCancel');
+      axios.all = function all(promises) {
+        return Promise.all(promises);
+      };
+      axios.spread = _dereq_('./helpers/spread');
+      module.exports = axios;
+      module.exports.default = axios;
+    }, {
+      './cancel/Cancel': 6,
+      './cancel/CancelToken': 7,
+      './cancel/isCancel': 8,
+      './core/Axios': 9,
+      './core/mergeConfig': 14,
+      './defaults': 17,
+      './helpers/bind': 18,
+      './helpers/spread': 26,
+      './utils': 27
+    } ],
+    6: [ function(_dereq_, module, exports) {
+      'use strict';
+      function Cancel(message) {
+        this.message = message;
+      }
+      Cancel.prototype.toString = function toString() {
+        return 'Cancel' + (this.message ? ': ' + this.message : '');
+      };
+      Cancel.prototype.__CANCEL__ = true;
+      module.exports = Cancel;
+    }, {} ],
+    7: [ function(_dereq_, module, exports) {
+      'use strict';
+      var Cancel = _dereq_('./Cancel');
+      function CancelToken(executor) {
+        if (typeof executor !== 'function') {
+          throw new TypeError('executor must be a function.');
+        }
+        var resolvePromise;
+        this.promise = new Promise(function promiseExecutor(resolve) {
+          resolvePromise = resolve;
+        });
+        var token = this;
+        executor(function cancel(message) {
+          if (token.reason) {
+            return;
+          }
+          token.reason = new Cancel(message);
+          resolvePromise(token.reason);
+        });
+      }
+      CancelToken.prototype.throwIfRequested = function throwIfRequested() {
+        if (this.reason) {
+          throw this.reason;
+        }
+      };
+      CancelToken.source = function source() {
+        var cancel;
+        var token = new CancelToken(function executor(c) {
+          cancel = c;
+        });
+        return {
+          token: token,
+          cancel: cancel
+        };
+      };
+      module.exports = CancelToken;
+    }, {
+      './Cancel': 6
+    } ],
+    8: [ function(_dereq_, module, exports) {
+      'use strict';
+      module.exports = function isCancel(value) {
+        return !!(value && value.__CANCEL__);
+      };
+    }, {} ],
+    9: [ function(_dereq_, module, exports) {
+      'use strict';
+      var utils = _dereq_('./../utils');
+      var buildURL = _dereq_('../helpers/buildURL');
+      var InterceptorManager = _dereq_('./InterceptorManager');
+      var dispatchRequest = _dereq_('./dispatchRequest');
+      var mergeConfig = _dereq_('./mergeConfig');
+      function Axios(instanceConfig) {
+        this.defaults = instanceConfig;
+        this.interceptors = {
+          request: new InterceptorManager(),
+          response: new InterceptorManager()
+        };
+      }
+      Axios.prototype.request = function request(config) {
+        if (typeof config === 'string') {
+          config = arguments[1] || {};
+          config.url = arguments[0];
+        } else {
+          config = config || {};
+        }
+        config = mergeConfig(this.defaults, config);
+        config.method = config.method ? config.method.toLowerCase() : 'get';
+        var chain = [ dispatchRequest, undefined ];
+        var promise = Promise.resolve(config);
+        this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
+          chain.unshift(interceptor.fulfilled, interceptor.rejected);
+        });
+        this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
+          chain.push(interceptor.fulfilled, interceptor.rejected);
+        });
+        while (chain.length) {
+          promise = promise.then(chain.shift(), chain.shift());
+        }
+        return promise;
+      };
+      Axios.prototype.getUri = function getUri(config) {
+        config = mergeConfig(this.defaults, config);
+        return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, '');
+      };
+      utils.forEach([ 'delete', 'get', 'head', 'options' ], function forEachMethodNoData(method) {
+        Axios.prototype[method] = function(url, config) {
+          return this.request(utils.merge(config || {}, {
+            method: method,
+            url: url
+          }));
+        };
+      });
+      utils.forEach([ 'post', 'put', 'patch' ], function forEachMethodWithData(method) {
+        Axios.prototype[method] = function(url, data, config) {
+          return this.request(utils.merge(config || {}, {
+            method: method,
+            url: url,
+            data: data
+          }));
+        };
+      });
+      module.exports = Axios;
+    }, {
+      '../helpers/buildURL': 19,
+      './../utils': 27,
+      './InterceptorManager': 10,
+      './dispatchRequest': 12,
+      './mergeConfig': 14
+    } ],
+    10: [ function(_dereq_, module, exports) {
+      'use strict';
+      var utils = _dereq_('./../utils');
+      function InterceptorManager() {
+        this.handlers = [];
+      }
+      InterceptorManager.prototype.use = function use(fulfilled, rejected) {
+        this.handlers.push({
+          fulfilled: fulfilled,
+          rejected: rejected
+        });
+        return this.handlers.length - 1;
+      };
+      InterceptorManager.prototype.eject = function eject(id) {
+        if (this.handlers[id]) {
+          this.handlers[id] = null;
+        }
+      };
+      InterceptorManager.prototype.forEach = function forEach(fn) {
+        utils.forEach(this.handlers, function forEachHandler(h) {
+          if (h !== null) {
+            fn(h);
+          }
+        });
+      };
+      module.exports = InterceptorManager;
+    }, {
+      './../utils': 27
+    } ],
+    11: [ function(_dereq_, module, exports) {
+      'use strict';
+      var enhanceError = _dereq_('./enhanceError');
+      module.exports = function createError(message, config, code, request, response) {
+        var error = new Error(message);
+        return enhanceError(error, config, code, request, response);
+      };
+    }, {
+      './enhanceError': 13
+    } ],
+    12: [ function(_dereq_, module, exports) {
+      'use strict';
+      var utils = _dereq_('./../utils');
+      var transformData = _dereq_('./transformData');
+      var isCancel = _dereq_('../cancel/isCancel');
+      var defaults = _dereq_('../defaults');
+      var isAbsoluteURL = _dereq_('./../helpers/isAbsoluteURL');
+      var combineURLs = _dereq_('./../helpers/combineURLs');
+      function throwIfCancellationRequested(config) {
+        if (config.cancelToken) {
+          config.cancelToken.throwIfRequested();
+        }
+      }
+      module.exports = function dispatchRequest(config) {
+        throwIfCancellationRequested(config);
+        if (config.baseURL && !isAbsoluteURL(config.url)) {
+          config.url = combineURLs(config.baseURL, config.url);
+        }
+        config.headers = config.headers || {};
+        config.data = transformData(config.data, config.headers, config.transformRequest);
+        config.headers = utils.merge(config.headers.common || {}, config.headers[config.method] || {}, config.headers || {});
+        utils.forEach([ 'delete', 'get', 'head', 'post', 'put', 'patch', 'common' ], function cleanHeaderConfig(method) {
+          delete config.headers[method];
+        });
+        var adapter = config.adapter || defaults.adapter;
+        return adapter(config).then(function onAdapterResolution(response) {
+          throwIfCancellationRequested(config);
+          response.data = transformData(response.data, response.headers, config.transformResponse);
+          return response;
+        }, function onAdapterRejection(reason) {
+          if (!isCancel(reason)) {
+            throwIfCancellationRequested(config);
+            if (reason && reason.response) {
+              reason.response.data = transformData(reason.response.data, reason.response.headers, config.transformResponse);
+            }
+          }
+          return Promise.reject(reason);
+        });
+      };
+    }, {
+      '../cancel/isCancel': 8,
+      '../defaults': 17,
+      './../helpers/combineURLs': 20,
+      './../helpers/isAbsoluteURL': 22,
+      './../utils': 27,
+      './transformData': 16
+    } ],
+    13: [ function(_dereq_, module, exports) {
+      'use strict';
+      module.exports = function enhanceError(error, config, code, request, response) {
+        error.config = config;
+        if (code) {
+          error.code = code;
+        }
+        error.request = request;
+        error.response = response;
+        error.isAxiosError = true;
+        error.toJSON = function() {
+          return {
+            message: this.message,
+            name: this.name,
+            description: this.description,
+            number: this.number,
+            fileName: this.fileName,
+            lineNumber: this.lineNumber,
+            columnNumber: this.columnNumber,
+            stack: this.stack,
+            config: this.config,
+            code: this.code
+          };
+        };
+        return error;
+      };
+    }, {} ],
+    14: [ function(_dereq_, module, exports) {
+      'use strict';
+      var utils = _dereq_('../utils');
+      module.exports = function mergeConfig(config1, config2) {
+        config2 = config2 || {};
+        var config = {};
+        utils.forEach([ 'url', 'method', 'params', 'data' ], function valueFromConfig2(prop) {
+          if (typeof config2[prop] !== 'undefined') {
+            config[prop] = config2[prop];
+          }
+        });
+        utils.forEach([ 'headers', 'auth', 'proxy' ], function mergeDeepProperties(prop) {
+          if (utils.isObject(config2[prop])) {
+            config[prop] = utils.deepMerge(config1[prop], config2[prop]);
+          } else if (typeof config2[prop] !== 'undefined') {
+            config[prop] = config2[prop];
+          } else if (utils.isObject(config1[prop])) {
+            config[prop] = utils.deepMerge(config1[prop]);
+          } else if (typeof config1[prop] !== 'undefined') {
+            config[prop] = config1[prop];
+          }
+        });
+        utils.forEach([ 'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer', 'timeout', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName', 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'maxContentLength', 'validateStatus', 'maxRedirects', 'httpAgent', 'httpsAgent', 'cancelToken', 'socketPath' ], function defaultToConfig2(prop) {
+          if (typeof config2[prop] !== 'undefined') {
+            config[prop] = config2[prop];
+          } else if (typeof config1[prop] !== 'undefined') {
+            config[prop] = config1[prop];
+          }
+        });
+        return config;
+      };
+    }, {
+      '../utils': 27
+    } ],
+    15: [ function(_dereq_, module, exports) {
+      'use strict';
+      var createError = _dereq_('./createError');
+      module.exports = function settle(resolve, reject, response) {
+        var validateStatus = response.config.validateStatus;
+        if (!validateStatus || validateStatus(response.status)) {
+          resolve(response);
+        } else {
+          reject(createError('Request failed with status code ' + response.status, response.config, null, response.request, response));
+        }
+      };
+    }, {
+      './createError': 11
+    } ],
+    16: [ function(_dereq_, module, exports) {
+      'use strict';
+      var utils = _dereq_('./../utils');
+      module.exports = function transformData(data, headers, fns) {
+        utils.forEach(fns, function transform(fn) {
+          data = fn(data, headers);
+        });
+        return data;
+      };
+    }, {
+      './../utils': 27
+    } ],
+    17: [ function(_dereq_, module, exports) {
+      (function(process) {
+        'use strict';
+        var utils = _dereq_('./utils');
+        var normalizeHeaderName = _dereq_('./helpers/normalizeHeaderName');
+        var DEFAULT_CONTENT_TYPE = {
+          'Content-Type': 'application/x-www-form-urlencoded'
+        };
+        function setContentTypeIfUnset(headers, value) {
+          if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {
+            headers['Content-Type'] = value;
+          }
+        }
+        function getDefaultAdapter() {
+          var adapter;
+          if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
+            adapter = _dereq_('./adapters/http');
+          } else if (typeof XMLHttpRequest !== 'undefined') {
+            adapter = _dereq_('./adapters/xhr');
+          }
+          return adapter;
+        }
+        var defaults = {
+          adapter: getDefaultAdapter(),
+          transformRequest: [ function transformRequest(data, headers) {
+            normalizeHeaderName(headers, 'Accept');
+            normalizeHeaderName(headers, 'Content-Type');
+            if (utils.isFormData(data) || utils.isArrayBuffer(data) || utils.isBuffer(data) || utils.isStream(data) || utils.isFile(data) || utils.isBlob(data)) {
+              return data;
+            }
+            if (utils.isArrayBufferView(data)) {
+              return data.buffer;
+            }
+            if (utils.isURLSearchParams(data)) {
+              setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
+              return data.toString();
+            }
+            if (utils.isObject(data)) {
+              setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
+              return JSON.stringify(data);
+            }
+            return data;
+          } ],
+          transformResponse: [ function transformResponse(data) {
+            if (typeof data === 'string') {
+              try {
+                data = JSON.parse(data);
+              } catch (e) {}
+            }
+            return data;
+          } ],
+          timeout: 0,
+          xsrfCookieName: 'XSRF-TOKEN',
+          xsrfHeaderName: 'X-XSRF-TOKEN',
+          maxContentLength: -1,
+          validateStatus: function validateStatus(status) {
+            return status >= 200 && status < 300;
+          }
+        };
+        defaults.headers = {
+          common: {
+            Accept: 'application/json, text/plain, */*'
+          }
+        };
+        utils.forEach([ 'delete', 'get', 'head' ], function forEachMethodNoData(method) {
+          defaults.headers[method] = {};
+        });
+        utils.forEach([ 'post', 'put', 'patch' ], function forEachMethodWithData(method) {
+          defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
+        });
+        module.exports = defaults;
+      }).call(this, _dereq_('_process'));
+    }, {
+      './adapters/http': 4,
+      './adapters/xhr': 4,
+      './helpers/normalizeHeaderName': 24,
+      './utils': 27,
+      _process: 33
+    } ],
+    18: [ function(_dereq_, module, exports) {
+      'use strict';
+      module.exports = function bind(fn, thisArg) {
+        return function wrap() {
+          var args = new Array(arguments.length);
+          for (var i = 0; i < args.length; i++) {
+            args[i] = arguments[i];
+          }
+          return fn.apply(thisArg, args);
+        };
+      };
+    }, {} ],
+    19: [ function(_dereq_, module, exports) {
+      'use strict';
+      var utils = _dereq_('./../utils');
+      function encode(val) {
+        return encodeURIComponent(val).replace(/%40/gi, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',').replace(/%20/g, '+').replace(/%5B/gi, '[').replace(/%5D/gi, ']');
+      }
+      module.exports = function buildURL(url, params, paramsSerializer) {
+        if (!params) {
+          return url;
+        }
+        var serializedParams;
+        if (paramsSerializer) {
+          serializedParams = paramsSerializer(params);
+        } else if (utils.isURLSearchParams(params)) {
+          serializedParams = params.toString();
+        } else {
+          var parts = [];
+          utils.forEach(params, function serialize(val, key) {
+            if (val === null || typeof val === 'undefined') {
+              return;
+            }
+            if (utils.isArray(val)) {
+              key = key + '[]';
+            } else {
+              val = [ val ];
+            }
+            utils.forEach(val, function parseValue(v) {
+              if (utils.isDate(v)) {
+                v = v.toISOString();
+              } else if (utils.isObject(v)) {
+                v = JSON.stringify(v);
+              }
+              parts.push(encode(key) + '=' + encode(v));
+            });
+          });
+          serializedParams = parts.join('&');
+        }
+        if (serializedParams) {
+          var hashmarkIndex = url.indexOf('#');
+          if (hashmarkIndex !== -1) {
+            url = url.slice(0, hashmarkIndex);
+          }
+          url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
+        }
+        return url;
+      };
+    }, {
+      './../utils': 27
+    } ],
+    20: [ function(_dereq_, module, exports) {
+      'use strict';
+      module.exports = function combineURLs(baseURL, relativeURL) {
+        return relativeURL ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') : baseURL;
+      };
+    }, {} ],
+    21: [ function(_dereq_, module, exports) {
+      'use strict';
+      var utils = _dereq_('./../utils');
+      module.exports = utils.isStandardBrowserEnv() ? function standardBrowserEnv() {
+        return {
+          write: function write(name, value, expires, path, domain, secure) {
+            var cookie = [];
+            cookie.push(name + '=' + encodeURIComponent(value));
+            if (utils.isNumber(expires)) {
+              cookie.push('expires=' + new Date(expires).toGMTString());
+            }
+            if (utils.isString(path)) {
+              cookie.push('path=' + path);
+            }
+            if (utils.isString(domain)) {
+              cookie.push('domain=' + domain);
+            }
+            if (secure === true) {
+              cookie.push('secure');
+            }
+            document.cookie = cookie.join('; ');
+          },
+          read: function read(name) {
+            var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)'));
+            return match ? decodeURIComponent(match[3]) : null;
+          },
+          remove: function remove(name) {
+            this.write(name, '', Date.now() - 864e5);
+          }
+        };
+      }() : function nonStandardBrowserEnv() {
+        return {
+          write: function write() {},
+          read: function read() {
+            return null;
+          },
+          remove: function remove() {}
+        };
+      }();
+    }, {
+      './../utils': 27
+    } ],
+    22: [ function(_dereq_, module, exports) {
+      'use strict';
+      module.exports = function isAbsoluteURL(url) {
+        return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
+      };
+    }, {} ],
+    23: [ function(_dereq_, module, exports) {
+      'use strict';
+      var utils = _dereq_('./../utils');
+      module.exports = utils.isStandardBrowserEnv() ? function standardBrowserEnv() {
+        var msie = /(msie|trident)/i.test(navigator.userAgent);
+        var urlParsingNode = document.createElement('a');
+        var originURL;
+        function resolveURL(url) {
+          var href = url;
+          if (msie) {
+            urlParsingNode.setAttribute('href', href);
+            href = urlParsingNode.href;
+          }
+          urlParsingNode.setAttribute('href', href);
+          return {
+            href: urlParsingNode.href,
+            protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',
+            host: urlParsingNode.host,
+            search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '',
+            hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',
+            hostname: urlParsingNode.hostname,
+            port: urlParsingNode.port,
+            pathname: urlParsingNode.pathname.charAt(0) === '/' ? urlParsingNode.pathname : '/' + urlParsingNode.pathname
+          };
+        }
+        originURL = resolveURL(window.location.href);
+        return function isURLSameOrigin(requestURL) {
+          var parsed = utils.isString(requestURL) ? resolveURL(requestURL) : requestURL;
+          return parsed.protocol === originURL.protocol && parsed.host === originURL.host;
+        };
+      }() : function nonStandardBrowserEnv() {
+        return function isURLSameOrigin() {
+          return true;
+        };
+      }();
+    }, {
+      './../utils': 27
+    } ],
+    24: [ function(_dereq_, module, exports) {
+      'use strict';
+      var utils = _dereq_('../utils');
+      module.exports = function normalizeHeaderName(headers, normalizedName) {
+        utils.forEach(headers, function processHeader(value, name) {
+          if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {
+            headers[normalizedName] = value;
+            delete headers[name];
+          }
+        });
+      };
+    }, {
+      '../utils': 27
+    } ],
+    25: [ function(_dereq_, module, exports) {
+      'use strict';
+      var utils = _dereq_('./../utils');
+      var ignoreDuplicateOf = [ 'age', 'authorization', 'content-length', 'content-type', 'etag', 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', 'last-modified', 'location', 'max-forwards', 'proxy-authorization', 'referer', 'retry-after', 'user-agent' ];
+      module.exports = function parseHeaders(headers) {
+        var parsed = {};
+        var key;
+        var val;
+        var i;
+        if (!headers) {
+          return parsed;
+        }
+        utils.forEach(headers.split('\n'), function parser(line) {
+          i = line.indexOf(':');
+          key = utils.trim(line.substr(0, i)).toLowerCase();
+          val = utils.trim(line.substr(i + 1));
+          if (key) {
+            if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {
+              return;
+            }
+            if (key === 'set-cookie') {
+              parsed[key] = (parsed[key] ? parsed[key] : []).concat([ val ]);
+            } else {
+              parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
+            }
+          }
+        });
+        return parsed;
+      };
+    }, {
+      './../utils': 27
+    } ],
+    26: [ function(_dereq_, module, exports) {
+      'use strict';
+      module.exports = function spread(callback) {
+        return function wrap(arr) {
+          return callback.apply(null, arr);
+        };
+      };
+    }, {} ],
+    27: [ function(_dereq_, module, exports) {
+      'use strict';
+      var bind = _dereq_('./helpers/bind');
+      var isBuffer = _dereq_('is-buffer');
+      var toString = Object.prototype.toString;
+      function isArray(val) {
+        return toString.call(val) === '[object Array]';
+      }
+      function isArrayBuffer(val) {
+        return toString.call(val) === '[object ArrayBuffer]';
+      }
+      function isFormData(val) {
+        return typeof FormData !== 'undefined' && val instanceof FormData;
+      }
+      function isArrayBufferView(val) {
+        var result;
+        if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView) {
+          result = ArrayBuffer.isView(val);
+        } else {
+          result = val && val.buffer && val.buffer instanceof ArrayBuffer;
+        }
+        return result;
+      }
+      function isString(val) {
+        return typeof val === 'string';
+      }
+      function isNumber(val) {
+        return typeof val === 'number';
+      }
+      function isUndefined(val) {
+        return typeof val === 'undefined';
+      }
+      function isObject(val) {
+        return val !== null && typeof val === 'object';
+      }
+      function isDate(val) {
+        return toString.call(val) === '[object Date]';
+      }
+      function isFile(val) {
+        return toString.call(val) === '[object File]';
+      }
+      function isBlob(val) {
+        return toString.call(val) === '[object Blob]';
+      }
+      function isFunction(val) {
+        return toString.call(val) === '[object Function]';
+      }
+      function isStream(val) {
+        return isObject(val) && isFunction(val.pipe);
+      }
+      function isURLSearchParams(val) {
+        return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
+      }
+      function trim(str) {
+        return str.replace(/^\s*/, '').replace(/\s*$/, '');
+      }
+      function isStandardBrowserEnv() {
+        if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' || navigator.product === 'NativeScript' || navigator.product === 'NS')) {
+          return false;
+        }
+        return typeof window !== 'undefined' && typeof document !== 'undefined';
+      }
+      function forEach(obj, fn) {
+        if (obj === null || typeof obj === 'undefined') {
+          return;
+        }
+        if (typeof obj !== 'object') {
+          obj = [ obj ];
+        }
+        if (isArray(obj)) {
+          for (var i = 0, l = obj.length; i < l; i++) {
+            fn.call(null, obj[i], i, obj);
+          }
+        } else {
+          for (var key in obj) {
+            if (Object.prototype.hasOwnProperty.call(obj, key)) {
+              fn.call(null, obj[key], key, obj);
+            }
+          }
+        }
+      }
+      function merge() {
+        var result = {};
+        function assignValue(val, key) {
+          if (typeof result[key] === 'object' && typeof val === 'object') {
+            result[key] = merge(result[key], val);
+          } else {
+            result[key] = val;
+          }
+        }
+        for (var i = 0, l = arguments.length; i < l; i++) {
+          forEach(arguments[i], assignValue);
+        }
+        return result;
+      }
+      function deepMerge() {
+        var result = {};
+        function assignValue(val, key) {
+          if (typeof result[key] === 'object' && typeof val === 'object') {
+            result[key] = deepMerge(result[key], val);
+          } else if (typeof val === 'object') {
+            result[key] = deepMerge({}, val);
+          } else {
+            result[key] = val;
+          }
+        }
+        for (var i = 0, l = arguments.length; i < l; i++) {
+          forEach(arguments[i], assignValue);
+        }
+        return result;
+      }
+      function extend(a, b, thisArg) {
+        forEach(b, function assignValue(val, key) {
+          if (thisArg && typeof val === 'function') {
+            a[key] = bind(val, thisArg);
+          } else {
+            a[key] = val;
+          }
+        });
+        return a;
+      }
+      module.exports = {
+        isArray: isArray,
+        isArrayBuffer: isArrayBuffer,
+        isBuffer: isBuffer,
+        isFormData: isFormData,
+        isArrayBufferView: isArrayBufferView,
+        isString: isString,
+        isNumber: isNumber,
+        isObject: isObject,
+        isUndefined: isUndefined,
+        isDate: isDate,
+        isFile: isFile,
+        isBlob: isBlob,
+        isFunction: isFunction,
+        isStream: isStream,
+        isURLSearchParams: isURLSearchParams,
+        isStandardBrowserEnv: isStandardBrowserEnv,
+        forEach: forEach,
+        merge: merge,
+        deepMerge: deepMerge,
+        extend: extend,
+        trim: trim
+      };
+    }, {
+      './helpers/bind': 18,
+      'is-buffer': 28
+    } ],
+    28: [ function(_dereq_, module, exports) {
+      module.exports = function isBuffer(obj) {
+        return obj != null && obj.constructor != null && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj);
+      };
+    }, {} ],
+    29: [ function(_dereq_, module, exports) {
+      module.exports = {
+        CssSelectorParser: _dereq_('./lib/css-selector-parser.js').CssSelectorParser
+      };
+    }, {
+      './lib/css-selector-parser.js': 30
+    } ],
+    30: [ function(_dereq_, module, exports) {
+      function CssSelectorParser() {
+        this.pseudos = {};
+        this.attrEqualityMods = {};
+        this.ruleNestingOperators = {};
+        this.substitutesEnabled = false;
+      }
+      CssSelectorParser.prototype.registerSelectorPseudos = function(name) {
+        for (var j = 0, len = arguments.length; j < len; j++) {
+          name = arguments[j];
+          this.pseudos[name] = 'selector';
+        }
+        return this;
+      };
+      CssSelectorParser.prototype.unregisterSelectorPseudos = function(name) {
+        for (var j = 0, len = arguments.length; j < len; j++) {
+          name = arguments[j];
+          delete this.pseudos[name];
+        }
+        return this;
+      };
+      CssSelectorParser.prototype.registerNumericPseudos = function(name) {
+        for (var j = 0, len = arguments.length; j < len; j++) {
+          name = arguments[j];
+          this.pseudos[name] = 'numeric';
+        }
+        return this;
+      };
+      CssSelectorParser.prototype.unregisterNumericPseudos = function(name) {
+        for (var j = 0, len = arguments.length; j < len; j++) {
+          name = arguments[j];
+          delete this.pseudos[name];
+        }
+        return this;
+      };
+      CssSelectorParser.prototype.registerNestingOperators = function(operator) {
+        for (var j = 0, len = arguments.length; j < len; j++) {
+          operator = arguments[j];
+          this.ruleNestingOperators[operator] = true;
+        }
+        return this;
+      };
+      CssSelectorParser.prototype.unregisterNestingOperators = function(operator) {
+        for (var j = 0, len = arguments.length; j < len; j++) {
+          operator = arguments[j];
+          delete this.ruleNestingOperators[operator];
+        }
+        return this;
+      };
+      CssSelectorParser.prototype.registerAttrEqualityMods = function(mod) {
+        for (var j = 0, len = arguments.length; j < len; j++) {
+          mod = arguments[j];
+          this.attrEqualityMods[mod] = true;
+        }
+        return this;
+      };
+      CssSelectorParser.prototype.unregisterAttrEqualityMods = function(mod) {
+        for (var j = 0, len = arguments.length; j < len; j++) {
+          mod = arguments[j];
+          delete this.attrEqualityMods[mod];
+        }
+        return this;
+      };
+      CssSelectorParser.prototype.enableSubstitutes = function() {
+        this.substitutesEnabled = true;
+        return this;
+      };
+      CssSelectorParser.prototype.disableSubstitutes = function() {
+        this.substitutesEnabled = false;
+        return this;
+      };
+      function isIdentStart(c) {
+        return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c === '-' || c === '_';
+      }
+      function isIdent(c) {
+        return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c === '-' || c === '_';
+      }
+      function isHex(c) {
+        return c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F' || c >= '0' && c <= '9';
+      }
+      function isDecimal(c) {
+        return c >= '0' && c <= '9';
+      }
+      function isAttrMatchOperator(chr) {
+        return chr === '=' || chr === '^' || chr === '$' || chr === '*' || chr === '~';
+      }
+      var identSpecialChars = {
+        '!': true,
+        '"': true,
+        '#': true,
+        $: true,
+        '%': true,
+        '&': true,
+        '\'': true,
+        '(': true,
+        ')': true,
+        '*': true,
+        '+': true,
+        ',': true,
+        '.': true,
+        '/': true,
+        ';': true,
+        '<': true,
+        '=': true,
+        '>': true,
+        '?': true,
+        '@': true,
+        '[': true,
+        '\\': true,
+        ']': true,
+        '^': true,
+        '`': true,
+        '{': true,
+        '|': true,
+        '}': true,
+        '~': true
+      };
+      var strReplacementsRev = {
+        '\n': '\\n',
+        '\r': '\\r',
+        '\t': '\\t',
+        '\f': '\\f',
+        '\v': '\\v'
+      };
+      var singleQuoteEscapeChars = {
+        n: '\n',
+        r: '\r',
+        t: '\t',
+        f: '\f',
+        '\\': '\\',
+        '\'': '\''
+      };
+      var doubleQuotesEscapeChars = {
+        n: '\n',
+        r: '\r',
+        t: '\t',
+        f: '\f',
+        '\\': '\\',
+        '"': '"'
+      };
+      function ParseContext(str, pos, pseudos, attrEqualityMods, ruleNestingOperators, substitutesEnabled) {
+        var chr, getIdent, getStr, l, skipWhitespace;
+        l = str.length;
+        chr = null;
+        getStr = function(quote, escapeTable) {
+          var esc, hex, result;
+          result = '';
+          pos++;
+          chr = str.charAt(pos);
+          while (pos < l) {
+            if (chr === quote) {
+              pos++;
+              return result;
+            } else if (chr === '\\') {
+              pos++;
+              chr = str.charAt(pos);
+              if (chr === quote) {
+                result += quote;
+              } else if (esc = escapeTable[chr]) {
+                result += esc;
+              } else if (isHex(chr)) {
+                hex = chr;
+                pos++;
+                chr = str.charAt(pos);
+                while (isHex(chr)) {
+                  hex += chr;
+                  pos++;
+                  chr = str.charAt(pos);
+                }
+                if (chr === ' ') {
+                  pos++;
+                  chr = str.charAt(pos);
+                }
+                result += String.fromCharCode(parseInt(hex, 16));
+                continue;
+              } else {
+                result += chr;
+              }
+            } else {
+              result += chr;
+            }
+            pos++;
+            chr = str.charAt(pos);
+          }
+          return result;
+        };
+        getIdent = function() {
+          var result = '';
+          chr = str.charAt(pos);
+          while (pos < l) {
+            if (isIdent(chr)) {
+              result += chr;
+            } else if (chr === '\\') {
+              pos++;
+              if (pos >= l) {
+                throw Error('Expected symbol but end of file reached.');
+              }
+              chr = str.charAt(pos);
+              if (identSpecialChars[chr]) {
+                result += chr;
+              } else if (isHex(chr)) {
+                var hex = chr;
+                pos++;
+                chr = str.charAt(pos);
+                while (isHex(chr)) {
+                  hex += chr;
+                  pos++;
+                  chr = str.charAt(pos);
+                }
+                if (chr === ' ') {
+                  pos++;
+                  chr = str.charAt(pos);
+                }
+                result += String.fromCharCode(parseInt(hex, 16));
+                continue;
+              } else {
+                result += chr;
+              }
+            } else {
+              return result;
+            }
+            pos++;
+            chr = str.charAt(pos);
+          }
+          return result;
+        };
+        skipWhitespace = function() {
+          chr = str.charAt(pos);
+          var result = false;
+          while (chr === ' ' || chr === '\t' || chr === '\n' || chr === '\r' || chr === '\f') {
+            result = true;
+            pos++;
+            chr = str.charAt(pos);
+          }
+          return result;
+        };
+        this.parse = function() {
+          var res = this.parseSelector();
+          if (pos < l) {
+            throw Error('Rule expected but "' + str.charAt(pos) + '" found.');
+          }
+          return res;
+        };
+        this.parseSelector = function() {
+          var res;
+          var selector = res = this.parseSingleSelector();
+          chr = str.charAt(pos);
+          while (chr === ',') {
+            pos++;
+            skipWhitespace();
+            if (res.type !== 'selectors') {
+              res = {
+                type: 'selectors',
+                selectors: [ selector ]
+              };
+            }
+            selector = this.parseSingleSelector();
+            if (!selector) {
+              throw Error('Rule expected after ",".');
+            }
+            res.selectors.push(selector);
+          }
+          return res;
+        };
+        this.parseSingleSelector = function() {
+          skipWhitespace();
+          var selector = {
+            type: 'ruleSet'
+          };
+          var rule = this.parseRule();
+          if (!rule) {
+            return null;
+          }
+          var currentRule = selector;
+          while (rule) {
+            rule.type = 'rule';
+            currentRule.rule = rule;
+            currentRule = rule;
+            skipWhitespace();
+            chr = str.charAt(pos);
+            if (pos >= l || chr === ',' || chr === ')') {
+              break;
+            }
+            if (ruleNestingOperators[chr]) {
+              var op = chr;
+              pos++;
+              skipWhitespace();
+              rule = this.parseRule();
+              if (!rule) {
+                throw Error('Rule expected after "' + op + '".');
+              }
+              rule.nestingOperator = op;
+            } else {
+              rule = this.parseRule();
+              if (rule) {
+                rule.nestingOperator = null;
+              }
+            }
+          }
+          return selector;
+        };
+        this.parseRule = function() {
+          var rule = null;
+          while (pos < l) {
+            chr = str.charAt(pos);
+            if (chr === '*') {
+              pos++;
+              (rule = rule || {}).tagName = '*';
+            } else if (isIdentStart(chr) || chr === '\\') {
+              (rule = rule || {}).tagName = getIdent();
+            } else if (chr === '.') {
+              pos++;
+              rule = rule || {};
+              (rule.classNames = rule.classNames || []).push(getIdent());
+            } else if (chr === '#') {
+              pos++;
+              (rule = rule || {}).id = getIdent();
+            } else if (chr === '[') {
+              pos++;
+              skipWhitespace();
+              var attr = {
+                name: getIdent()
+              };
+              skipWhitespace();
+              if (chr === ']') {
+                pos++;
+              } else {
+                var operator = '';
+                if (attrEqualityMods[chr]) {
+                  operator = chr;
+                  pos++;
+                  chr = str.charAt(pos);
+                }
+                if (pos >= l) {
+                  throw Error('Expected "=" but end of file reached.');
+                }
+                if (chr !== '=') {
+                  throw Error('Expected "=" but "' + chr + '" found.');
+                }
+                attr.operator = operator + '=';
+                pos++;
+                skipWhitespace();
+                var attrValue = '';
+                attr.valueType = 'string';
+                if (chr === '"') {
+                  attrValue = getStr('"', doubleQuotesEscapeChars);
+                } else if (chr === '\'') {
+                  attrValue = getStr('\'', singleQuoteEscapeChars);
+                } else if (substitutesEnabled && chr === '$') {
+                  pos++;
+                  attrValue = getIdent();
+                  attr.valueType = 'substitute';
+                } else {
+                  while (pos < l) {
+                    if (chr === ']') {
+                      break;
+                    }
+                    attrValue += chr;
+                    pos++;
+                    chr = str.charAt(pos);
+                  }
+                  attrValue = attrValue.trim();
+                }
+                skipWhitespace();
+                if (pos >= l) {
+                  throw Error('Expected "]" but end of file reached.');
+                }
+                if (chr !== ']') {
+                  throw Error('Expected "]" but "' + chr + '" found.');
+                }
+                pos++;
+                attr.value = attrValue;
+              }
+              rule = rule || {};
+              (rule.attrs = rule.attrs || []).push(attr);
+            } else if (chr === ':') {
+              pos++;
+              var pseudoName = getIdent();
+              var pseudo = {
+                name: pseudoName
+              };
+              if (chr === '(') {
+                pos++;
+                var value = '';
+                skipWhitespace();
+                if (pseudos[pseudoName] === 'selector') {
+                  pseudo.valueType = 'selector';
+                  value = this.parseSelector();
+                } else {
+                  pseudo.valueType = pseudos[pseudoName] || 'string';
+                  if (chr === '"') {
+                    value = getStr('"', doubleQuotesEscapeChars);
+                  } else if (chr === '\'') {
+                    value = getStr('\'', singleQuoteEscapeChars);
+                  } else if (substitutesEnabled && chr === '$') {
+                    pos++;
+                    value = getIdent();
+                    pseudo.valueType = 'substitute';
+                  } else {
+                    while (pos < l) {
+                      if (chr === ')') {
+                        break;
+                      }
+                      value += chr;
+                      pos++;
+                      chr = str.charAt(pos);
+                    }
+                    value = value.trim();
+                  }
+                  skipWhitespace();
+                }
+                if (pos >= l) {
+                  throw Error('Expected ")" but end of file reached.');
+                }
+                if (chr !== ')') {
+                  throw Error('Expected ")" but "' + chr + '" found.');
+                }
+                pos++;
+                pseudo.value = value;
+              }
+              rule = rule || {};
+              (rule.pseudos = rule.pseudos || []).push(pseudo);
+            } else {
+              break;
+            }
+          }
+          return rule;
+        };
+        return this;
+      }
+      CssSelectorParser.prototype.parse = function(str) {
+        var context = new ParseContext(str, 0, this.pseudos, this.attrEqualityMods, this.ruleNestingOperators, this.substitutesEnabled);
+        return context.parse();
+      };
+      CssSelectorParser.prototype.escapeIdentifier = function(s) {
+        var result = '';
+        var i = 0;
+        var len = s.length;
+        while (i < len) {
+          var chr = s.charAt(i);
+          if (identSpecialChars[chr]) {
+            result += '\\' + chr;
+          } else {
+            if (!(chr === '_' || chr === '-' || chr >= 'A' && chr <= 'Z' || chr >= 'a' && chr <= 'z' || i !== 0 && chr >= '0' && chr <= '9')) {
+              var charCode = chr.charCodeAt(0);
+              if ((charCode & 63488) === 55296) {
+                var extraCharCode = s.charCodeAt(i++);
+                if ((charCode & 64512) !== 55296 || (extraCharCode & 64512) !== 56320) {
+                  throw Error('UCS-2(decode): illegal sequence');
+                }
+                charCode = ((charCode & 1023) << 10) + (extraCharCode & 1023) + 65536;
+              }
+              result += '\\' + charCode.toString(16) + ' ';
+            } else {
+              result += chr;
+            }
+          }
+          i++;
+        }
+        return result;
+      };
+      CssSelectorParser.prototype.escapeStr = function(s) {
+        var result = '';
+        var i = 0;
+        var len = s.length;
+        var chr, replacement;
+        while (i < len) {
+          chr = s.charAt(i);
+          if (chr === '"') {
+            chr = '\\"';
+          } else if (chr === '\\') {
+            chr = '\\\\';
+          } else if (replacement = strReplacementsRev[chr]) {
+            chr = replacement;
+          }
+          result += chr;
+          i++;
+        }
+        return '"' + result + '"';
+      };
+      CssSelectorParser.prototype.render = function(path) {
+        return this._renderEntity(path).trim();
+      };
+      CssSelectorParser.prototype._renderEntity = function(entity) {
+        var currentEntity, parts, res;
+        res = '';
+        switch (entity.type) {
+         case 'ruleSet':
+          currentEntity = entity.rule;
+          parts = [];
+          while (currentEntity) {
+            if (currentEntity.nestingOperator) {
+              parts.push(currentEntity.nestingOperator);
+            }
+            parts.push(this._renderEntity(currentEntity));
+            currentEntity = currentEntity.rule;
+          }
+          res = parts.join(' ');
+          break;
+
+         case 'selectors':
+          res = entity.selectors.map(this._renderEntity, this).join(', ');
+          break;
+
+         case 'rule':
+          if (entity.tagName) {
+            if (entity.tagName === '*') {
+              res = '*';
+            } else {
+              res = this.escapeIdentifier(entity.tagName);
+            }
+          }
+          if (entity.id) {
+            res += '#' + this.escapeIdentifier(entity.id);
+          }
+          if (entity.classNames) {
+            res += entity.classNames.map(function(cn) {
+              return '.' + this.escapeIdentifier(cn);
+            }, this).join('');
+          }
+          if (entity.attrs) {
+            res += entity.attrs.map(function(attr) {
+              if (attr.operator) {
+                if (attr.valueType === 'substitute') {
+                  return '[' + this.escapeIdentifier(attr.name) + attr.operator + '$' + attr.value + ']';
+                } else {
+                  return '[' + this.escapeIdentifier(attr.name) + attr.operator + this.escapeStr(attr.value) + ']';
+                }
+              } else {
+                return '[' + this.escapeIdentifier(attr.name) + ']';
+              }
+            }, this).join('');
+          }
+          if (entity.pseudos) {
+            res += entity.pseudos.map(function(pseudo) {
+              if (pseudo.valueType) {
+                if (pseudo.valueType === 'selector') {
+                  return ':' + this.escapeIdentifier(pseudo.name) + '(' + this._renderEntity(pseudo.value) + ')';
+                } else if (pseudo.valueType === 'substitute') {
+                  return ':' + this.escapeIdentifier(pseudo.name) + '($' + pseudo.value + ')';
+                } else if (pseudo.valueType === 'numeric') {
+                  return ':' + this.escapeIdentifier(pseudo.name) + '(' + pseudo.value + ')';
+                } else {
+                  return ':' + this.escapeIdentifier(pseudo.name) + '(' + this.escapeIdentifier(pseudo.value) + ')';
+                }
+              } else {
+                return ':' + this.escapeIdentifier(pseudo.name);
+              }
+            }, this).join('');
+          }
+          break;
+
+         default:
+          throw Error('Unknown entity type: "' + entity.type(+'".'));
+        }
+        return res;
+      };
+      exports.CssSelectorParser = CssSelectorParser;
+    }, {} ],
+    31: [ function(_dereq_, module, exports) {
+      'use strict';
+      module.exports = function() {
+        return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
+      };
+    }, {} ],
+    32: [ function(_dereq_, module, exports) {
+      (function(process, global) {
+        (function(global, factory) {
+          typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : global.ES6Promise = factory();
+        })(this, function() {
+          'use strict';
+          function objectOrFunction(x) {
+            var type = typeof x;
+            return x !== null && (type === 'object' || type === 'function');
+          }
+          function isFunction(x) {
+            return typeof x === 'function';
+          }
+          var _isArray = void 0;
+          if (Array.isArray) {
+            _isArray = Array.isArray;
+          } else {
+            _isArray = function(x) {
+              return Object.prototype.toString.call(x) === '[object Array]';
+            };
+          }
+          var isArray = _isArray;
+          var len = 0;
+          var vertxNext = void 0;
+          var customSchedulerFn = void 0;
+          var asap = function asap(callback, arg) {
+            queue[len] = callback;
+            queue[len + 1] = arg;
+            len += 2;
+            if (len === 2) {
+              if (customSchedulerFn) {
+                customSchedulerFn(flush);
+              } else {
+                scheduleFlush();
+              }
+            }
+          };
+          function setScheduler(scheduleFn) {
+            customSchedulerFn = scheduleFn;
+          }
+          function setAsap(asapFn) {
+            asap = asapFn;
+          }
+          var browserWindow = typeof window !== 'undefined' ? window : undefined;
+          var browserGlobal = browserWindow || {};
+          var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
+          var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
+          var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
+          function useNextTick() {
+            return function() {
+              return process.nextTick(flush);
+            };
+          }
+          function useVertxTimer() {
+            if (typeof vertxNext !== 'undefined') {
+              return function() {
+                vertxNext(flush);
+              };
+            }
+            return useSetTimeout();
+          }
+          function useMutationObserver() {
+            var iterations = 0;
+            var observer = new BrowserMutationObserver(flush);
+            var node = document.createTextNode('');
+            observer.observe(node, {
+              characterData: true
+            });
+            return function() {
+              node.data = iterations = ++iterations % 2;
+            };
+          }
+          function useMessageChannel() {
+            var channel = new MessageChannel();
+            channel.port1.onmessage = flush;
+            return function() {
+              return channel.port2.postMessage(0);
+            };
+          }
+          function useSetTimeout() {
+            var globalSetTimeout = setTimeout;
+            return function() {
+              return globalSetTimeout(flush, 1);
+            };
+          }
+          var queue = new Array(1e3);
+          function flush() {
+            for (var i = 0; i < len; i += 2) {
+              var callback = queue[i];
+              var arg = queue[i + 1];
+              callback(arg);
+              queue[i] = undefined;
+              queue[i + 1] = undefined;
+            }
+            len = 0;
+          }
+          function attemptVertx() {
+            try {
+              var vertx = Function('return this')().require('vertx');
+              vertxNext = vertx.runOnLoop || vertx.runOnContext;
+              return useVertxTimer();
+            } catch (e) {
+              return useSetTimeout();
+            }
+          }
+          var scheduleFlush = void 0;
+          if (isNode) {
+            scheduleFlush = useNextTick();
+          } else if (BrowserMutationObserver) {
+            scheduleFlush = useMutationObserver();
+          } else if (isWorker) {
+            scheduleFlush = useMessageChannel();
+          } else if (browserWindow === undefined && typeof _dereq_ === 'function') {
+            scheduleFlush = attemptVertx();
+          } else {
+            scheduleFlush = useSetTimeout();
+          }
+          function then(onFulfillment, onRejection) {
+            var parent = this;
+            var child = new this.constructor(noop);
+            if (child[PROMISE_ID] === undefined) {
+              makePromise(child);
+            }
+            var _state = parent._state;
+            if (_state) {
+              var callback = arguments[_state - 1];
+              asap(function() {
+                return invokeCallback(_state, child, callback, parent._result);
+              });
+            } else {
+              subscribe(parent, child, onFulfillment, onRejection);
+            }
+            return child;
+          }
+          function resolve$1(object) {
+            var Constructor = this;
+            if (object && typeof object === 'object' && object.constructor === Constructor) {
+              return object;
+            }
+            var promise = new Constructor(noop);
+            resolve(promise, object);
+            return promise;
+          }
+          var PROMISE_ID = Math.random().toString(36).substring(2);
+          function noop() {}
+          var PENDING = void 0;
+          var FULFILLED = 1;
+          var REJECTED = 2;
+          function selfFulfillment() {
+            return new TypeError('You cannot resolve a promise with itself');
+          }
+          function cannotReturnOwn() {
+            return new TypeError('A promises callback cannot return that same promise.');
+          }
+          function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) {
+            try {
+              then$$1.call(value, fulfillmentHandler, rejectionHandler);
+            } catch (e) {
+              return e;
+            }
+          }
+          function handleForeignThenable(promise, thenable, then$$1) {
+            asap(function(promise) {
+              var sealed = false;
+              var error = tryThen(then$$1, thenable, function(value) {
+                if (sealed) {
+                  return;
+                }
+                sealed = true;
+                if (thenable !== value) {
+                  resolve(promise, value);
+                } else {
+                  fulfill(promise, value);
+                }
+              }, function(reason) {
+                if (sealed) {
+                  return;
+                }
+                sealed = true;
+                reject(promise, reason);
+              }, 'Settle: ' + (promise._label || ' unknown promise'));
+              if (!sealed && error) {
+                sealed = true;
+                reject(promise, error);
+              }
+            }, promise);
+          }
+          function handleOwnThenable(promise, thenable) {
+            if (thenable._state === FULFILLED) {
+              fulfill(promise, thenable._result);
+            } else if (thenable._state === REJECTED) {
+              reject(promise, thenable._result);
+            } else {
+              subscribe(thenable, undefined, function(value) {
+                return resolve(promise, value);
+              }, function(reason) {
+                return reject(promise, reason);
+              });
+            }
+          }
+          function handleMaybeThenable(promise, maybeThenable, then$$1) {
+            if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) {
+              handleOwnThenable(promise, maybeThenable);
+            } else {
+              if (then$$1 === undefined) {
+                fulfill(promise, maybeThenable);
+              } else if (isFunction(then$$1)) {
+                handleForeignThenable(promise, maybeThenable, then$$1);
+              } else {
+                fulfill(promise, maybeThenable);
+              }
+            }
+          }
+          function resolve(promise, value) {
+            if (promise === value) {
+              reject(promise, selfFulfillment());
+            } else if (objectOrFunction(value)) {
+              var then$$1 = void 0;
+              try {
+                then$$1 = value.then;
+              } catch (error) {
+                reject(promise, error);
+                return;
+              }
+              handleMaybeThenable(promise, value, then$$1);
+            } else {
+              fulfill(promise, value);
+            }
+          }
+          function publishRejection(promise) {
+            if (promise._onerror) {
+              promise._onerror(promise._result);
+            }
+            publish(promise);
+          }
+          function fulfill(promise, value) {
+            if (promise._state !== PENDING) {
+              return;
+            }
+            promise._result = value;
+            promise._state = FULFILLED;
+            if (promise._subscribers.length !== 0) {
+              asap(publish, promise);
+            }
+          }
+          function reject(promise, reason) {
+            if (promise._state !== PENDING) {
+              return;
+            }
+            promise._state = REJECTED;
+            promise._result = reason;
+            asap(publishRejection, promise);
+          }
+          function subscribe(parent, child, onFulfillment, onRejection) {
+            var _subscribers = parent._subscribers;
+            var length = _subscribers.length;
+            parent._onerror = null;
+            _subscribers[length] = child;
+            _subscribers[length + FULFILLED] = onFulfillment;
+            _subscribers[length + REJECTED] = onRejection;
+            if (length === 0 && parent._state) {
+              asap(publish, parent);
+            }
+          }
+          function publish(promise) {
+            var subscribers = promise._subscribers;
+            var settled = promise._state;
+            if (subscribers.length === 0) {
+              return;
+            }
+            var child = void 0, callback = void 0, detail = promise._result;
+            for (var i = 0; i < subscribers.length; i += 3) {
+              child = subscribers[i];
+              callback = subscribers[i + settled];
+              if (child) {
+                invokeCallback(settled, child, callback, detail);
+              } else {
+                callback(detail);
+              }
+            }
+            promise._subscribers.length = 0;
+          }
+          function invokeCallback(settled, promise, callback, detail) {
+            var hasCallback = isFunction(callback), value = void 0, error = void 0, succeeded = true;
+            if (hasCallback) {
+              try {
+                value = callback(detail);
+              } catch (e) {
+                succeeded = false;
+                error = e;
+              }
+              if (promise === value) {
+                reject(promise, cannotReturnOwn());
+                return;
+              }
+            } else {
+              value = detail;
+            }
+            if (promise._state !== PENDING) {} else if (hasCallback && succeeded) {
+              resolve(promise, value);
+            } else if (succeeded === false) {
+              reject(promise, error);
+            } else if (settled === FULFILLED) {
+              fulfill(promise, value);
+            } else if (settled === REJECTED) {
+              reject(promise, value);
+            }
+          }
+          function initializePromise(promise, resolver) {
+            try {
+              resolver(function resolvePromise(value) {
+                resolve(promise, value);
+              }, function rejectPromise(reason) {
+                reject(promise, reason);
+              });
+            } catch (e) {
+              reject(promise, e);
+            }
+          }
+          var id = 0;
+          function nextId() {
+            return id++;
+          }
+          function makePromise(promise) {
+            promise[PROMISE_ID] = id++;
+            promise._state = undefined;
+            promise._result = undefined;
+            promise._subscribers = [];
+          }
+          function validationError() {
+            return new Error('Array Methods must be provided an Array');
+          }
+          var Enumerator = function() {
+            function Enumerator(Constructor, input) {
+              this._instanceConstructor = Constructor;
+              this.promise = new Constructor(noop);
+              if (!this.promise[PROMISE_ID]) {
+                makePromise(this.promise);
+              }
+              if (isArray(input)) {
+                this.length = input.length;
+                this._remaining = input.length;
+                this._result = new Array(this.length);
+                if (this.length === 0) {
+                  fulfill(this.promise, this._result);
+                } else {
+                  this.length = this.length || 0;
+                  this._enumerate(input);
+                  if (this._remaining === 0) {
+                    fulfill(this.promise, this._result);
+                  }
+                }
+              } else {
+                reject(this.promise, validationError());
+              }
+            }
+            Enumerator.prototype._enumerate = function _enumerate(input) {
+              for (var i = 0; this._state === PENDING && i < input.length; i++) {
+                this._eachEntry(input[i], i);
+              }
+            };
+            Enumerator.prototype._eachEntry = function _eachEntry(entry, i) {
+              var c = this._instanceConstructor;
+              var resolve$$1 = c.resolve;
+              if (resolve$$1 === resolve$1) {
+                var _then = void 0;
+                var error = void 0;
+                var didError = false;
+                try {
+                  _then = entry.then;
+                } catch (e) {
+                  didError = true;
+                  error = e;
+                }
+                if (_then === then && entry._state !== PENDING) {
+                  this._settledAt(entry._state, i, entry._result);
+                } else if (typeof _then !== 'function') {
+                  this._remaining--;
+                  this._result[i] = entry;
+                } else if (c === Promise$1) {
+                  var promise = new c(noop);
+                  if (didError) {
+                    reject(promise, error);
+                  } else {
+                    handleMaybeThenable(promise, entry, _then);
+                  }
+                  this._willSettleAt(promise, i);
+                } else {
+                  this._willSettleAt(new c(function(resolve$$1) {
+                    return resolve$$1(entry);
+                  }), i);
+                }
+              } else {
+                this._willSettleAt(resolve$$1(entry), i);
+              }
+            };
+            Enumerator.prototype._settledAt = function _settledAt(state, i, value) {
+              var promise = this.promise;
+              if (promise._state === PENDING) {
+                this._remaining--;
+                if (state === REJECTED) {
+                  reject(promise, value);
+                } else {
+                  this._result[i] = value;
+                }
+              }
+              if (this._remaining === 0) {
+                fulfill(promise, this._result);
+              }
+            };
+            Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) {
+              var enumerator = this;
+              subscribe(promise, undefined, function(value) {
+                return enumerator._settledAt(FULFILLED, i, value);
+              }, function(reason) {
+                return enumerator._settledAt(REJECTED, i, reason);
+              });
+            };
+            return Enumerator;
+          }();
+          function all(entries) {
+            return new Enumerator(this, entries).promise;
+          }
+          function race(entries) {
+            var Constructor = this;
+            if (!isArray(entries)) {
+              return new Constructor(function(_, reject) {
+                return reject(new TypeError('You must pass an array to race.'));
+              });
+            } else {
+              return new Constructor(function(resolve, reject) {
+                var length = entries.length;
+                for (var i = 0; i < length; i++) {
+                  Constructor.resolve(entries[i]).then(resolve, reject);
+                }
+              });
+            }
+          }
+          function reject$1(reason) {
+            var Constructor = this;
+            var promise = new Constructor(noop);
+            reject(promise, reason);
+            return promise;
+          }
+          function needsResolver() {
+            throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
+          }
+          function needsNew() {
+            throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.');
+          }
+          var Promise$1 = function() {
+            function Promise(resolver) {
+              this[PROMISE_ID] = nextId();
+              this._result = this._state = undefined;
+              this._subscribers = [];
+              if (noop !== resolver) {
+                typeof resolver !== 'function' && needsResolver();
+                this instanceof Promise ? initializePromise(this, resolver) : needsNew();
+              }
+            }
+            Promise.prototype.catch = function _catch(onRejection) {
+              return this.then(null, onRejection);
+            };
+            Promise.prototype.finally = function _finally(callback) {
+              var promise = this;
+              var constructor = promise.constructor;
+              if (isFunction(callback)) {
+                return promise.then(function(value) {
+                  return constructor.resolve(callback()).then(function() {
+                    return value;
+                  });
+                }, function(reason) {
+                  return constructor.resolve(callback()).then(function() {
+                    throw reason;
+                  });
+                });
+              }
+              return promise.then(callback, callback);
+            };
+            return Promise;
+          }();
+          Promise$1.prototype.then = then;
+          Promise$1.all = all;
+          Promise$1.race = race;
+          Promise$1.resolve = resolve$1;
+          Promise$1.reject = reject$1;
+          Promise$1._setScheduler = setScheduler;
+          Promise$1._setAsap = setAsap;
+          Promise$1._asap = asap;
+          function polyfill() {
+            var local = void 0;
+            if (typeof global !== 'undefined') {
+              local = global;
+            } else if (typeof self !== 'undefined') {
+              local = self;
+            } else {
+              try {
+                local = Function('return this')();
+              } catch (e) {
+                throw new Error('polyfill failed because global object is unavailable in this environment');
+              }
+            }
+            var P = local.Promise;
+            if (P) {
+              var promiseToString = null;
+              try {
+                promiseToString = Object.prototype.toString.call(P.resolve());
+              } catch (e) {}
+              if (promiseToString === '[object Promise]' && !P.cast) {
+                return;
+              }
+            }
+            local.Promise = Promise$1;
+          }
+          Promise$1.polyfill = polyfill;
+          Promise$1.Promise = Promise$1;
+          return Promise$1;
+        });
+      }).call(this, _dereq_('_process'), typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : {});
+    }, {
+      _process: 33
+    } ],
+    33: [ function(_dereq_, module, exports) {
+      var process = module.exports = {};
+      var cachedSetTimeout;
+      var cachedClearTimeout;
+      function defaultSetTimout() {
+        throw new Error('setTimeout has not been defined');
+      }
+      function defaultClearTimeout() {
+        throw new Error('clearTimeout has not been defined');
+      }
+      (function() {
+        try {
+          if (typeof setTimeout === 'function') {
+            cachedSetTimeout = setTimeout;
+          } else {
+            cachedSetTimeout = defaultSetTimout;
+          }
+        } catch (e) {
+          cachedSetTimeout = defaultSetTimout;
+        }
+        try {
+          if (typeof clearTimeout === 'function') {
+            cachedClearTimeout = clearTimeout;
+          } else {
+            cachedClearTimeout = defaultClearTimeout;
+          }
+        } catch (e) {
+          cachedClearTimeout = defaultClearTimeout;
+        }
+      })();
+      function runTimeout(fun) {
+        if (cachedSetTimeout === setTimeout) {
+          return setTimeout(fun, 0);
+        }
+        if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+          cachedSetTimeout = setTimeout;
+          return setTimeout(fun, 0);
+        }
+        try {
+          return cachedSetTimeout(fun, 0);
+        } catch (e) {
+          try {
+            return cachedSetTimeout.call(null, fun, 0);
+          } catch (e) {
+            return cachedSetTimeout.call(this, fun, 0);
+          }
+        }
+      }
+      function runClearTimeout(marker) {
+        if (cachedClearTimeout === clearTimeout) {
+          return clearTimeout(marker);
+        }
+        if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+          cachedClearTimeout = clearTimeout;
+          return clearTimeout(marker);
+        }
+        try {
+          return cachedClearTimeout(marker);
+        } catch (e) {
+          try {
+            return cachedClearTimeout.call(null, marker);
+          } catch (e) {
+            return cachedClearTimeout.call(this, marker);
+          }
+        }
+      }
+      var queue = [];
+      var draining = false;
+      var currentQueue;
+      var queueIndex = -1;
+      function cleanUpNextTick() {
+        if (!draining || !currentQueue) {
+          return;
+        }
+        draining = false;
+        if (currentQueue.length) {
+          queue = currentQueue.concat(queue);
+        } else {
+          queueIndex = -1;
+        }
+        if (queue.length) {
+          drainQueue();
+        }
+      }
+      function drainQueue() {
+        if (draining) {
+          return;
+        }
+        var timeout = runTimeout(cleanUpNextTick);
+        draining = true;
+        var len = queue.length;
+        while (len) {
+          currentQueue = queue;
+          queue = [];
+          while (++queueIndex < len) {
+            if (currentQueue) {
+              currentQueue[queueIndex].run();
+            }
+          }
+          queueIndex = -1;
+          len = queue.length;
+        }
+        currentQueue = null;
+        draining = false;
+        runClearTimeout(timeout);
+      }
+      process.nextTick = function(fun) {
+        var args = new Array(arguments.length - 1);
+        if (arguments.length > 1) {
+          for (var i = 1; i < arguments.length; i++) {
+            args[i - 1] = arguments[i];
+          }
+        }
+        queue.push(new Item(fun, args));
+        if (queue.length === 1 && !draining) {
+          runTimeout(drainQueue);
+        }
+      };
+      function Item(fun, array) {
+        this.fun = fun;
+        this.array = array;
+      }
+      Item.prototype.run = function() {
+        this.fun.apply(null, this.array);
+      };
+      process.title = 'browser';
+      process.browser = true;
+      process.env = {};
+      process.argv = [];
+      process.version = '';
+      process.versions = {};
+      function noop() {}
+      process.on = noop;
+      process.addListener = noop;
+      process.once = noop;
+      process.off = noop;
+      process.removeListener = noop;
+      process.removeAllListeners = noop;
+      process.emit = noop;
+      process.prependListener = noop;
+      process.prependOnceListener = noop;
+      process.listeners = function(name) {
+        return [];
+      };
+      process.binding = function(name) {
+        throw new Error('process.binding is not supported');
+      };
+      process.cwd = function() {
+        return '/';
+      };
+      process.chdir = function(dir) {
+        throw new Error('process.chdir is not supported');
+      };
+      process.umask = function() {
+        return 0;
+      };
+    }, {} ],
+    34: [ function(_dereq_, module, exports) {
+      (function(global) {
+        (function(self) {
+          'use strict';
+          if (self.WeakMap) {
+            return;
+          }
+          var hasOwnProperty = Object.prototype.hasOwnProperty;
+          var defineProperty = function(object, name, value) {
+            if (Object.defineProperty) {
+              Object.defineProperty(object, name, {
+                configurable: true,
+                writable: true,
+                value: value
+              });
+            } else {
+              object[name] = value;
+            }
+          };
+          self.WeakMap = function() {
+            function WeakMap() {
+              if (this === void 0) {
+                throw new TypeError('Constructor WeakMap requires \'new\'');
+              }
+              defineProperty(this, '_id', genId('_WeakMap'));
+              if (arguments.length > 0) {
+                throw new TypeError('WeakMap iterable is not supported');
+              }
+            }
+            defineProperty(WeakMap.prototype, 'delete', function(key) {
+              checkInstance(this, 'delete');
+              if (!isObject(key)) {
+                return false;
+              }
+              var entry = key[this._id];
+              if (entry && entry[0] === key) {
+                delete key[this._id];
+                return true;
+              }
+              return false;
+            });
+            defineProperty(WeakMap.prototype, 'get', function(key) {
+              checkInstance(this, 'get');
+              if (!isObject(key)) {
+                return void 0;
+              }
+              var entry = key[this._id];
+              if (entry && entry[0] === key) {
+                return entry[1];
+              }
+              return void 0;
+            });
+            defineProperty(WeakMap.prototype, 'has', function(key) {
+              checkInstance(this, 'has');
+              if (!isObject(key)) {
+                return false;
+              }
+              var entry = key[this._id];
+              if (entry && entry[0] === key) {
+                return true;
+              }
+              return false;
+            });
+            defineProperty(WeakMap.prototype, 'set', function(key, value) {
+              checkInstance(this, 'set');
+              if (!isObject(key)) {
+                throw new TypeError('Invalid value used as weak map key');
+              }
+              var entry = key[this._id];
+              if (entry && entry[0] === key) {
+                entry[1] = value;
+                return this;
+              }
+              defineProperty(key, this._id, [ key, value ]);
+              return this;
+            });
+            function checkInstance(x, methodName) {
+              if (!isObject(x) || !hasOwnProperty.call(x, '_id')) {
+                throw new TypeError(methodName + ' method called on incompatible receiver ' + typeof x);
+              }
+            }
+            function genId(prefix) {
+              return prefix + '_' + rand() + '.' + rand();
+            }
+            function rand() {
+              return Math.random().toString().substring(2);
+            }
+            defineProperty(WeakMap, '_polyfill', true);
+            return WeakMap;
+          }();
+          function isObject(x) {
+            return Object(x) === x;
+          }
+        })(typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : this);
+      }).call(this, typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : {});
+    }, {} ]
+  }, {}, [ 1 ]);
   'use strict';
   var utils = axe.utils = {};
   'use strict';
   var helpers = {};
   'use strict';
-  var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-    return typeof obj;
-  } : function(obj) {
-    return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-  };
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
+  function _extends() {
+    _extends = Object.assign || function(target) {
+      for (var i = 1; i < arguments.length; i++) {
+        var source = arguments[i];
+        for (var key in source) {
+          if (Object.prototype.hasOwnProperty.call(source, key)) {
+            target[key] = source[key];
+          }
+        }
+      }
+      return target;
+    };
+    return _extends.apply(this, arguments);
+  }
   function getDefaultConfiguration(audit) {
     'use strict';
     var config;
@@ -68,7 +2546,7 @@
     config.reporter = config.reporter || null;
     config.rules = config.rules || [];
     config.checks = config.checks || [];
-    config.data = Object.assign({
+    config.data = _extends({
       checks: {},
       rules: {}
     }, config.data);
@@ -87,7 +2565,104 @@
     this.tagExclude = [ 'experimental' ];
     this.defaultConfig = audit;
     this._init();
+    this._defaultLocale = null;
   }
+  Audit.prototype._setDefaultLocale = function() {
+    if (this._defaultLocale) {
+      return;
+    }
+    var locale = {
+      checks: {},
+      rules: {}
+    };
+    var checkIDs = Object.keys(this.data.checks);
+    for (var i = 0; i < checkIDs.length; i++) {
+      var id = checkIDs[i];
+      var check = this.data.checks[id];
+      var _check$messages = check.messages, pass = _check$messages.pass, fail = _check$messages.fail, incomplete = _check$messages.incomplete;
+      locale.checks[id] = {
+        pass: pass,
+        fail: fail,
+        incomplete: incomplete
+      };
+    }
+    var ruleIDs = Object.keys(this.data.rules);
+    for (var _i = 0; _i < ruleIDs.length; _i++) {
+      var _id = ruleIDs[_i];
+      var rule = this.data.rules[_id];
+      var description = rule.description, help = rule.help;
+      locale.rules[_id] = {
+        description: description,
+        help: help
+      };
+    }
+    this._defaultLocale = locale;
+  };
+  Audit.prototype._resetLocale = function() {
+    var defaultLocale = this._defaultLocale;
+    if (!defaultLocale) {
+      return;
+    }
+    this.applyLocale(defaultLocale);
+  };
+  var mergeCheckLocale = function mergeCheckLocale(a, b) {
+    var pass = b.pass, fail = b.fail;
+    if (typeof pass === 'string') {
+      pass = axe.imports.doT.compile(pass);
+    }
+    if (typeof fail === 'string') {
+      fail = axe.imports.doT.compile(fail);
+    }
+    return _extends({}, a, {
+      messages: {
+        pass: pass || a.messages.pass,
+        fail: fail || a.messages.fail,
+        incomplete: _typeof(a.messages.incomplete) === 'object' ? _extends({}, a.messages.incomplete, {}, b.incomplete) : b.incomplete
+      }
+    });
+  };
+  var mergeRuleLocale = function mergeRuleLocale(a, b) {
+    var help = b.help, description = b.description;
+    if (typeof help === 'string') {
+      help = axe.imports.doT.compile(help);
+    }
+    if (typeof description === 'string') {
+      description = axe.imports.doT.compile(description);
+    }
+    return _extends({}, a, {
+      help: help || a.help,
+      description: description || a.description
+    });
+  };
+  Audit.prototype._applyCheckLocale = function(checks) {
+    var keys = Object.keys(checks);
+    for (var i = 0; i < keys.length; i++) {
+      var id = keys[i];
+      if (!this.data.checks[id]) {
+        throw new Error('Locale provided for unknown check: "'.concat(id, '"'));
+      }
+      this.data.checks[id] = mergeCheckLocale(this.data.checks[id], checks[id]);
+    }
+  };
+  Audit.prototype._applyRuleLocale = function(rules) {
+    var keys = Object.keys(rules);
+    for (var i = 0; i < keys.length; i++) {
+      var id = keys[i];
+      if (!this.data.rules[id]) {
+        throw new Error('Locale provided for unknown rule: "'.concat(id, '"'));
+      }
+      this.data.rules[id] = mergeRuleLocale(this.data.rules[id], rules[id]);
+    }
+  };
+  Audit.prototype.applyLocale = function(locale) {
+    this._setDefaultLocale();
+    if (locale.checks) {
+      this._applyCheckLocale(locale.checks);
+    }
+    if (locale.rules) {
+      this._applyRuleLocale(locale.rules);
+    }
+  };
   Audit.prototype._init = function() {
     var audit = getDefaultConfiguration(this.defaultConfig);
     axe.commons = commons = audit.commons;
@@ -123,7 +2698,7 @@
   Audit.prototype.addCheck = function(spec) {
     'use strict';
     var metadata = spec.metadata;
-    if ((typeof metadata === 'undefined' ? 'undefined' : _typeof(metadata)) === 'object') {
+    if (_typeof(metadata) === 'object') {
       this.data.checks[spec.id] = metadata;
       if (_typeof(metadata.messages) === 'object') {
         Object.keys(metadata.messages).filter(function(prop) {
@@ -141,54 +2716,110 @@
       this.checks[spec.id] = new Check(spec);
     }
   };
+  function getRulesToRun(rules, context, options) {
+    var base = {
+      now: [],
+      later: []
+    };
+    var splitRules = rules.reduce(function(out, rule) {
+      if (!axe.utils.ruleShouldRun(rule, context, options)) {
+        return out;
+      }
+      if (rule.preload) {
+        out.later.push(rule);
+        return out;
+      }
+      out.now.push(rule);
+      return out;
+    }, base);
+    return splitRules;
+  }
+  function getDefferedRule(rule, context, options) {
+    if (options.performanceTimer) {
+      axe.utils.performanceTimer.mark('mark_rule_start_' + rule.id);
+    }
+    return function(resolve, reject) {
+      rule.run(context, options, function(ruleResult) {
+        resolve(ruleResult);
+      }, function(err) {
+        if (!options.debug) {
+          var errResult = Object.assign(new RuleResult(rule), {
+            result: axe.constants.CANTTELL,
+            description: 'An error occured while running this rule',
+            message: err.message,
+            stack: err.stack,
+            error: err,
+            errorNode: err.errorNode
+          });
+          resolve(errResult);
+        } else {
+          reject(err);
+        }
+      });
+    };
+  }
   Audit.prototype.run = function(context, options, resolve, reject) {
     'use strict';
-    this.validateOptions(options);
-    axe._tree = axe.utils.getFlattenedTree(document.documentElement);
-    var q = axe.utils.queue();
-    this.rules.forEach(function(rule) {
-      if (axe.utils.ruleShouldRun(rule, context, options)) {
-        if (options.performanceTimer) {
-          var markEnd = 'mark_rule_end_' + rule.id;
-          var markStart = 'mark_rule_start_' + rule.id;
-          axe.utils.performanceTimer.mark(markStart);
-        }
-        q.defer(function(res, rej) {
-          rule.run(context, options, function(out) {
-            if (options.performanceTimer) {
-              axe.utils.performanceTimer.mark(markEnd);
-              axe.utils.performanceTimer.measure('rule_' + rule.id, markStart, markEnd);
-            }
-            res(out);
-          }, function(err) {
-            if (!options.debug) {
-              var errResult = Object.assign(new RuleResult(rule), {
-                result: axe.constants.CANTTELL,
-                description: 'An error occured while running this rule',
-                message: err.message,
-                stack: err.stack,
-                error: err
-              });
-              res(errResult);
-            } else {
-              rej(err);
-            }
-          });
-        });
-      }
+    this.normalizeOptions(options);
+    axe._selectCache = [];
+    var allRulesToRun = getRulesToRun(this.rules, context, options);
+    var runNowRules = allRulesToRun.now;
+    var runLaterRules = allRulesToRun.later;
+    var nowRulesQueue = axe.utils.queue();
+    runNowRules.forEach(function(rule) {
+      nowRulesQueue.defer(getDefferedRule(rule, context, options));
     });
-    q.then(function(results) {
-      axe._tree = undefined;
-      resolve(results.filter(function(result) {
-        return !!result;
-      }));
-    }).catch(reject);
+    var preloaderQueue = axe.utils.queue();
+    if (runLaterRules.length) {
+      preloaderQueue.defer(function(resolve) {
+        axe.utils.preload(options).then(function(assets) {
+          return resolve(assets);
+        })['catch'](function(err) {
+          console.warn('Couldn\'t load preload assets: ', err);
+          resolve(undefined);
+        });
+      });
+    }
+    var queueForNowRulesAndPreloader = axe.utils.queue();
+    queueForNowRulesAndPreloader.defer(nowRulesQueue);
+    queueForNowRulesAndPreloader.defer(preloaderQueue);
+    queueForNowRulesAndPreloader.then(function(nowRulesAndPreloaderResults) {
+      var assetsFromQueue = nowRulesAndPreloaderResults.pop();
+      if (assetsFromQueue && assetsFromQueue.length) {
+        var assets = assetsFromQueue[0];
+        if (assets) {
+          context = _extends({}, context, {}, assets);
+        }
+      }
+      var nowRulesResults = nowRulesAndPreloaderResults[0];
+      if (!runLaterRules.length) {
+        axe._selectCache = undefined;
+        resolve(nowRulesResults.filter(function(result) {
+          return !!result;
+        }));
+        return;
+      }
+      var laterRulesQueue = axe.utils.queue();
+      runLaterRules.forEach(function(rule) {
+        var deferredRule = getDefferedRule(rule, context, options);
+        laterRulesQueue.defer(deferredRule);
+      });
+      laterRulesQueue.then(function(laterRuleResults) {
+        axe._selectCache = undefined;
+        resolve(nowRulesResults.concat(laterRuleResults).filter(function(result) {
+          return !!result;
+        }));
+      })['catch'](reject);
+    })['catch'](reject);
   };
   Audit.prototype.after = function(results, options) {
     'use strict';
     var rules = this.rules;
     return results.map(function(ruleResult) {
       var rule = axe.utils.findBy(rules, 'id', ruleResult.id);
+      if (!rule) {
+        throw new Error('Result for unknown rule. You may be running mismatch axe-core versions');
+      }
       return rule.after(ruleResult, options);
     });
   };
@@ -197,34 +2828,43 @@
       return rule.id === ruleId;
     });
   };
-  Audit.prototype.validateOptions = function(options) {
+  Audit.prototype.normalizeOptions = function(options) {
     'use strict';
     var audit = this;
     if (_typeof(options.runOnly) === 'object') {
+      if (Array.isArray(options.runOnly)) {
+        options.runOnly = {
+          type: 'tag',
+          values: options.runOnly
+        };
+      }
       var only = options.runOnly;
-      if (only.type === 'rule' && Array.isArray(only.value)) {
-        only.value.forEach(function(ruleId) {
+      if (only.value && !only.values) {
+        only.values = only.value;
+        delete only.value;
+      }
+      if (!Array.isArray(only.values) || only.values.length === 0) {
+        throw new Error('runOnly.values must be a non-empty array');
+      }
+      if ([ 'rule', 'rules' ].includes(only.type)) {
+        only.type = 'rule';
+        only.values.forEach(function(ruleId) {
           if (!audit.getRule(ruleId)) {
             throw new Error('unknown rule `' + ruleId + '` in options.runOnly');
           }
         });
-      } else if (Array.isArray(only.value) && only.value.length > 0) {
-        var tags = [].concat(only.value);
-        audit.rules.forEach(function(rule) {
-          var tagPos, i, l;
-          if (!tags) {
-            return;
-          }
-          for (i = 0, l = rule.tags.length; i < l; i++) {
-            tagPos = tags.indexOf(rule.tags[i]);
-            if (tagPos !== -1) {
-              tags.splice(tagPos, 1);
-            }
-          }
-        });
-        if (tags.length !== 0) {
-          throw new Error('could not find tags `' + tags.join('`, `') + '`');
+      } else if ([ 'tag', 'tags', undefined ].includes(only.type)) {
+        only.type = 'tag';
+        var unmatchedTags = audit.rules.reduce(function(unmatchedTags, rule) {
+          return unmatchedTags.length ? unmatchedTags.filter(function(tag) {
+            return !rule.tags.includes(tag);
+          }) : unmatchedTags;
+        }, only.values);
+        if (unmatchedTags.length !== 0) {
+          axe.log('Could not find tags `' + unmatchedTags.join('`, `') + '`');
         }
+      } else {
+        throw new Error('Unknown runOnly type \''.concat(only.type, '\''));
       }
     }
     if (_typeof(options.rules) === 'object') {
@@ -257,7 +2897,7 @@
   Audit.prototype._constructHelpUrls = function() {
     var _this = this;
     var previous = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
-    var version = axe.version.substring(0, axe.version.lastIndexOf('.'));
+    var version = (axe.version.match(/^[1-9][0-9]*\.[0-9]+/) || [ 'x.y' ])[0];
     this.rules.forEach(function(rule) {
       if (!_this.data.rules[rule.id]) {
         _this.data.rules[rule.id] = {};
@@ -271,8 +2911,26 @@
   Audit.prototype.resetRulesAndChecks = function() {
     'use strict';
     this._init();
+    this._resetLocale();
   };
   'use strict';
+  (function() {
+    'use strict';
+    var _cache = {};
+    var cache = {
+      set: function set(key, value) {
+        _cache[key] = value;
+      },
+      get: function get(key) {
+        return _cache[key];
+      },
+      clear: function clear() {
+        _cache = {};
+      }
+    };
+    axe._cache = cache;
+  })();
+  'use strict';
   function CheckResult(check) {
     'use strict';
     this.id = check.id;
@@ -295,7 +2953,7 @@
     }
   }
   Check.prototype.enabled = true;
-  Check.prototype.run = function(node, options, resolve, reject) {
+  Check.prototype.run = function(node, options, context, resolve, reject) {
     'use strict';
     options = options || {};
     var enabled = options.hasOwnProperty('enabled') ? options.enabled : this.enabled, checkOptions = options.options || this.options;
@@ -304,21 +2962,46 @@
       var checkHelper = axe.utils.checkHelper(checkResult, options, resolve, reject);
       var result;
       try {
-        result = this.evaluate.call(checkHelper, node.actualNode, checkOptions, node);
+        result = this.evaluate.call(checkHelper, node.actualNode, checkOptions, node, context);
       } catch (e) {
+        if (node && node.actualNode) {
+          e.errorNode = new DqElement(node.actualNode).toJSON();
+        }
         reject(e);
         return;
       }
       if (!checkHelper.isAsync) {
         checkResult.result = result;
-        setTimeout(function() {
-          resolve(checkResult);
-        }, 0);
+        resolve(checkResult);
       }
     } else {
       resolve(null);
     }
   };
+  Check.prototype.runSync = function(node, options, context) {
+    options = options || {};
+    var _options = options, _options$enabled = _options.enabled, enabled = _options$enabled === void 0 ? this.enabled : _options$enabled;
+    if (!enabled) {
+      return null;
+    }
+    var checkOptions = options.options || this.options;
+    var checkResult = new CheckResult(this);
+    var checkHelper = axe.utils.checkHelper(checkResult, options);
+    checkHelper.async = function() {
+      throw new Error('Cannot run async check while in a synchronous run');
+    };
+    var result;
+    try {
+      result = this.evaluate.call(checkHelper, node.actualNode, checkOptions, node, context);
+    } catch (e) {
+      if (node && node.actualNode) {
+        e.errorNode = new DqElement(node.actualNode).toJSON();
+      }
+      throw e;
+    }
+    checkResult.result = result;
+    return checkResult;
+  };
   Check.prototype.configure = function(spec) {
     var _this = this;
     [ 'options', 'enabled' ].filter(function(prop) {
@@ -333,11 +3016,18 @@
     });
   };
   'use strict';
-  var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-    return typeof obj;
-  } : function(obj) {
-    return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-  };
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
   function pushUniqueFrame(collection, frame) {
     'use strict';
     if (axe.utils.isHidden(frame)) {
@@ -378,7 +3068,7 @@
   }
   function normalizeContext(context) {
     'use strict';
-    if (context && (typeof context === 'undefined' ? 'undefined' : _typeof(context)) === 'object' || context instanceof NodeList) {
+    if (context && _typeof(context) === 'object' || context instanceof NodeList) {
       if (context instanceof Node) {
         return {
           include: [ context ],
@@ -417,7 +3107,7 @@
       if (typeof item === 'string') {
         nodeList = Array.from(document.querySelectorAll(item));
         result = result.concat(nodeList.map(function(node) {
-          return axe.utils.getFlattenedTree(node)[0];
+          return axe.utils.getNodeFromTree(node);
         }));
         break;
       } else if (item && item.length && !(item instanceof Node)) {
@@ -426,11 +3116,15 @@
         } else {
           nodeList = Array.from(document.querySelectorAll(item[0]));
           result = result.concat(nodeList.map(function(node) {
-            return axe.utils.getFlattenedTree(node)[0];
+            return axe.utils.getNodeFromTree(node);
           }));
         }
       } else if (item instanceof Node) {
-        result.push(axe.utils.getFlattenedTree(item)[0]);
+        if (item.documentElement instanceof Node) {
+          result.push(context.flatTree[0]);
+        } else {
+          result.push(axe.utils.getNodeFromTree(item));
+        }
       }
     }
     return result.filter(function(r) {
@@ -451,20 +3145,35 @@
       });
     }
   }
+  function getRootNode(_ref) {
+    var include = _ref.include, exclude = _ref.exclude;
+    var selectors = Array.from(include).concat(Array.from(exclude));
+    var localDocument = selectors.reduce(function(result, item) {
+      if (result) {
+        return result;
+      } else if (item instanceof Element) {
+        return item.ownerDocument;
+      } else if (item instanceof Document) {
+        return item;
+      }
+    }, null);
+    return (localDocument || document).documentElement;
+  }
   function Context(spec) {
     'use strict';
-    var self = this;
+    var _this = this;
     this.frames = [];
     this.initiator = spec && typeof spec.initiator === 'boolean' ? spec.initiator : true;
     this.page = false;
     spec = normalizeContext(spec);
+    this.flatTree = axe.utils.getFlattenedTree(getRootNode(spec));
     this.exclude = spec.exclude;
     this.include = spec.include;
     this.include = parseSelectorArray(this, 'include');
     this.exclude = parseSelectorArray(this, 'exclude');
     axe.utils.select('frame, iframe', this).forEach(function(frame) {
-      if (isNodeInContext(frame, self)) {
-        pushUniqueFrame(self.frames, frame.actualNode);
+      if (isNodeInContext(frame, _this)) {
+        pushUniqueFrame(_this.frames, frame.actualNode);
       }
     });
     if (this.include.length === 1 && this.include[0].actualNode === document.documentElement) {
@@ -474,6 +3183,10 @@
     if (err instanceof Error) {
       throw err;
     }
+    if (!Array.isArray(this.include)) {
+      this.include = Array.from(this.include);
+    }
+    this.include.sort(axe.utils.nodeSorter);
   }
   'use strict';
   function RuleResult(rule) {
@@ -497,6 +3210,7 @@
     this.all = spec.all || [];
     this.none = spec.none || [];
     this.tags = spec.tags || [];
+    this.preload = spec.preload ? true : false;
     if (spec.matches) {
       this.matches = createExecutionContext(spec.matches);
     }
@@ -506,16 +3220,34 @@
     return true;
   };
   Rule.prototype.gather = function(context) {
-    'use strict';
+    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+    var markStart = 'mark_gather_start_' + this.id;
+    var markEnd = 'mark_gather_end_' + this.id;
+    var markHiddenStart = 'mark_isHidden_start_' + this.id;
+    var markHiddenEnd = 'mark_isHidden_end_' + this.id;
+    if (options.performanceTimer) {
+      axe.utils.performanceTimer.mark(markStart);
+    }
     var elements = axe.utils.select(this.selector, context);
     if (this.excludeHidden) {
-      return elements.filter(function(element) {
+      if (options.performanceTimer) {
+        axe.utils.performanceTimer.mark(markHiddenStart);
+      }
+      elements = elements.filter(function(element) {
         return !axe.utils.isHidden(element.actualNode);
       });
+      if (options.performanceTimer) {
+        axe.utils.performanceTimer.mark(markHiddenEnd);
+        axe.utils.performanceTimer.measure('rule_' + this.id + '#gather_axe.utils.isHidden', markHiddenStart, markHiddenEnd);
+      }
+    }
+    if (options.performanceTimer) {
+      axe.utils.performanceTimer.mark(markEnd);
+      axe.utils.performanceTimer.measure('rule_' + this.id + '#gather', markStart, markEnd);
     }
     return elements;
   };
-  Rule.prototype.runChecks = function(type, node, options, resolve, reject) {
+  Rule.prototype.runChecks = function(type, node, options, context, resolve, reject) {
     'use strict';
     var self = this;
     var checkQueue = axe.utils.queue();
@@ -523,7 +3255,7 @@
       var check = self._audit.checks[c.id || c];
       var option = axe.utils.getCheckOption(check, self.id, options);
       checkQueue.defer(function(res, rej) {
-        check.run(node, option, res, rej);
+        check.run(node, option, context, res, rej);
       });
     });
     checkQueue.then(function(results) {
@@ -534,17 +3266,38 @@
         type: type,
         results: results
       });
-    }).catch(reject);
+    })['catch'](reject);
   };
-  Rule.prototype.run = function(context, options, resolve, reject) {
+  Rule.prototype.runChecksSync = function(type, node, options, context) {
+    'use strict';
+    var self = this;
+    var results = [];
+    this[type].forEach(function(c) {
+      var check = self._audit.checks[c.id || c];
+      var option = axe.utils.getCheckOption(check, self.id, options);
+      results.push(check.runSync(node, option, context));
+    });
+    results = results.filter(function(check) {
+      return check;
+    });
+    return {
+      type: type,
+      results: results
+    };
+  };
+  Rule.prototype.run = function(context) {
     var _this = this;
+    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+    var resolve = arguments.length > 2 ? arguments[2] : undefined;
+    var reject = arguments.length > 3 ? arguments[3] : undefined;
+    if (options.performanceTimer) {
+      this._trackPerformance();
+    }
     var q = axe.utils.queue();
     var ruleResult = new RuleResult(this);
-    var nodes = void 0;
+    var nodes;
     try {
-      nodes = this.gather(context).filter(function(node) {
-        return _this.matches(node.actualNode, node);
-      });
+      nodes = this.gatherAndMatchNodes(context, options);
     } catch (error) {
       reject(new SupportError({
         cause: error,
@@ -553,49 +3306,126 @@
       return;
     }
     if (options.performanceTimer) {
-      axe.log('gather (', nodes.length, '):', axe.utils.performanceTimer.timeElapsed() + 'ms');
+      this._logGatherPerformance(nodes);
     }
     nodes.forEach(function(node) {
       q.defer(function(resolveNode, rejectNode) {
         var checkQueue = axe.utils.queue();
-        checkQueue.defer(function(res, rej) {
-          _this.runChecks('any', node, options, res, rej);
-        });
-        checkQueue.defer(function(res, rej) {
-          _this.runChecks('all', node, options, res, rej);
-        });
-        checkQueue.defer(function(res, rej) {
-          _this.runChecks('none', node, options, res, rej);
+        [ 'any', 'all', 'none' ].forEach(function(type) {
+          checkQueue.defer(function(res, rej) {
+            _this.runChecks(type, node, options, context, res, rej);
+          });
         });
         checkQueue.then(function(results) {
-          if (results.length) {
-            var hasResults = false, result = {};
-            results.forEach(function(r) {
-              var res = r.results.filter(function(result) {
-                return result;
-              });
-              result[r.type] = res;
-              if (res.length) {
-                hasResults = true;
-              }
-            });
-            if (hasResults) {
-              result.node = new axe.utils.DqElement(node.actualNode, options);
-              ruleResult.nodes.push(result);
-            }
+          var result = getResult(results);
+          if (result) {
+            result.node = new axe.utils.DqElement(node.actualNode, options);
+            ruleResult.nodes.push(result);
           }
           resolveNode();
-        }).catch(function(err) {
+        })['catch'](function(err) {
           return rejectNode(err);
         });
       });
     });
+    q.defer(function(resolve) {
+      return setTimeout(resolve, 0);
+    });
+    if (options.performanceTimer) {
+      this._logRulePerformance();
+    }
     q.then(function() {
       return resolve(ruleResult);
-    }).catch(function(error) {
+    })['catch'](function(error) {
       return reject(error);
     });
   };
+  Rule.prototype.runSync = function(context) {
+    var _this2 = this;
+    var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+    if (options.performanceTimer) {
+      this._trackPerformance();
+    }
+    var ruleResult = new RuleResult(this);
+    var nodes;
+    try {
+      nodes = this.gatherAndMatchNodes(context, options);
+    } catch (error) {
+      throw new SupportError({
+        cause: error,
+        ruleId: this.id
+      });
+    }
+    if (options.performanceTimer) {
+      this._logGatherPerformance(nodes);
+    }
+    nodes.forEach(function(node) {
+      var results = [];
+      [ 'any', 'all', 'none' ].forEach(function(type) {
+        results.push(_this2.runChecksSync(type, node, options, context));
+      });
+      var result = getResult(results);
+      if (result) {
+        result.node = node.actualNode ? new axe.utils.DqElement(node.actualNode, options) : null;
+        ruleResult.nodes.push(result);
+      }
+    });
+    if (options.performanceTimer) {
+      this._logRulePerformance();
+    }
+    return ruleResult;
+  };
+  Rule.prototype._trackPerformance = function() {
+    this._markStart = 'mark_rule_start_' + this.id;
+    this._markEnd = 'mark_rule_end_' + this.id;
+    this._markChecksStart = 'mark_runchecks_start_' + this.id;
+    this._markChecksEnd = 'mark_runchecks_end_' + this.id;
+  };
+  Rule.prototype._logGatherPerformance = function(nodes) {
+    axe.log('gather (', nodes.length, '):', axe.utils.performanceTimer.timeElapsed() + 'ms');
+    axe.utils.performanceTimer.mark(this._markChecksStart);
+  };
+  Rule.prototype._logRulePerformance = function() {
+    axe.utils.performanceTimer.mark(this._markChecksEnd);
+    axe.utils.performanceTimer.mark(this._markEnd);
+    axe.utils.performanceTimer.measure('runchecks_' + this.id, this._markChecksStart, this._markChecksEnd);
+    axe.utils.performanceTimer.measure('rule_' + this.id, this._markStart, this._markEnd);
+  };
+  function getResult(results) {
+    if (results.length) {
+      var hasResults = false, result = {};
+      results.forEach(function(r) {
+        var res = r.results.filter(function(result) {
+          return result;
+        });
+        result[r.type] = res;
+        if (res.length) {
+          hasResults = true;
+        }
+      });
+      if (hasResults) {
+        return result;
+      }
+      return null;
+    }
+  }
+  Rule.prototype.gatherAndMatchNodes = function(context, options) {
+    var _this3 = this;
+    var markMatchesStart = 'mark_matches_start_' + this.id;
+    var markMatchesEnd = 'mark_matches_end_' + this.id;
+    var nodes = this.gather(context, options);
+    if (options.performanceTimer) {
+      axe.utils.performanceTimer.mark(markMatchesStart);
+    }
+    nodes = nodes.filter(function(node) {
+      return _this3.matches(node.actualNode, node, context);
+    });
+    if (options.performanceTimer) {
+      axe.utils.performanceTimer.mark(markMatchesEnd);
+      axe.utils.performanceTimer.measure('rule_' + this.id + '#matches', markMatchesStart, markMatchesEnd);
+    }
+    return nodes;
+  };
   function findAfterChecks(rule) {
     'use strict';
     return axe.utils.getAllChecks(rule).map(function(c) {
@@ -697,6 +3527,188 @@
     }
   };
   'use strict';
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
+  function _possibleConstructorReturn(self, call) {
+    if (call && (_typeof(call) === 'object' || typeof call === 'function')) {
+      return call;
+    }
+    return _assertThisInitialized(self);
+  }
+  function _getPrototypeOf(o) {
+    _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
+      return o.__proto__ || Object.getPrototypeOf(o);
+    };
+    return _getPrototypeOf(o);
+  }
+  function _assertThisInitialized(self) {
+    if (self === void 0) {
+      throw new ReferenceError('this hasn\'t been initialised - super() hasn\'t been called');
+    }
+    return self;
+  }
+  function _inherits(subClass, superClass) {
+    if (typeof superClass !== 'function' && superClass !== null) {
+      throw new TypeError('Super expression must either be null or a function');
+    }
+    subClass.prototype = Object.create(superClass && superClass.prototype, {
+      constructor: {
+        value: subClass,
+        writable: true,
+        configurable: true
+      }
+    });
+    if (superClass) {
+      _setPrototypeOf(subClass, superClass);
+    }
+  }
+  function _setPrototypeOf(o, p) {
+    _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
+      o.__proto__ = p;
+      return o;
+    };
+    return _setPrototypeOf(o, p);
+  }
+  function _classCallCheck(instance, Constructor) {
+    if (!(instance instanceof Constructor)) {
+      throw new TypeError('Cannot call a class as a function');
+    }
+  }
+  function _defineProperties(target, props) {
+    for (var i = 0; i < props.length; i++) {
+      var descriptor = props[i];
+      descriptor.enumerable = descriptor.enumerable || false;
+      descriptor.configurable = true;
+      if ('value' in descriptor) {
+        descriptor.writable = true;
+      }
+      Object.defineProperty(target, descriptor.key, descriptor);
+    }
+  }
+  function _createClass(Constructor, protoProps, staticProps) {
+    if (protoProps) {
+      _defineProperties(Constructor.prototype, protoProps);
+    }
+    if (staticProps) {
+      _defineProperties(Constructor, staticProps);
+    }
+    return Constructor;
+  }
+  var whitespaceRegex = /[\t\r\n\f]/g;
+  var AbstractVirtualNode = function() {
+    function AbstractVirtualNode() {
+      _classCallCheck(this, AbstractVirtualNode);
+      this.children = [];
+      this.parent = null;
+    }
+    _createClass(AbstractVirtualNode, [ {
+      key: 'hasClass',
+      value: function hasClass() {
+        throw new Error('VirtualNode class must have a "hasClass" function');
+      }
+    }, {
+      key: 'attr',
+      value: function attr() {
+        throw new Error('VirtualNode class must have a "attr" function');
+      }
+    }, {
+      key: 'hasAttr',
+      value: function hasAttr() {
+        throw new Error('VirtualNode class must have a "hasAttr" function');
+      }
+    }, {
+      key: 'props',
+      get: function get() {
+        throw new Error('VirtualNode class must have a "props" object consisting ' + 'of "nodeType" and "nodeName" properties');
+      }
+    } ]);
+    return AbstractVirtualNode;
+  }();
+  var VirtualNode = function(_AbstractVirtualNode) {
+    _inherits(VirtualNode, _AbstractVirtualNode);
+    function VirtualNode(node, parent, shadowId) {
+      var _this;
+      _classCallCheck(this, VirtualNode);
+      _this = _possibleConstructorReturn(this, _getPrototypeOf(VirtualNode).call(this));
+      _this.shadowId = shadowId;
+      _this.children = [];
+      _this.actualNode = node;
+      _this.parent = parent;
+      _this._isHidden = null;
+      _this._cache = {};
+      if (axe._cache.get('nodeMap')) {
+        axe._cache.get('nodeMap').set(node, _assertThisInitialized(_this));
+      }
+      return _this;
+    }
+    _createClass(VirtualNode, [ {
+      key: 'hasClass',
+      value: function hasClass(className) {
+        var classAttr = this.attr('class');
+        if (!classAttr) {
+          return false;
+        }
+        var selector = ' ' + className + ' ';
+        return (' ' + classAttr + ' ').replace(whitespaceRegex, ' ').indexOf(selector) >= 0;
+      }
+    }, {
+      key: 'attr',
+      value: function attr(attrName) {
+        if (typeof this.actualNode.getAttribute !== 'function') {
+          return null;
+        }
+        return this.actualNode.getAttribute(attrName);
+      }
+    }, {
+      key: 'hasAttr',
+      value: function hasAttr(attrName) {
+        if (typeof this.actualNode.hasAttribute !== 'function') {
+          return false;
+        }
+        return this.actualNode.hasAttribute(attrName);
+      }
+    }, {
+      key: 'props',
+      get: function get() {
+        var _this$actualNode = this.actualNode, nodeType = _this$actualNode.nodeType, nodeName = _this$actualNode.nodeName, id = _this$actualNode.id, type = _this$actualNode.type;
+        return {
+          nodeType: nodeType,
+          nodeName: nodeName.toLowerCase(),
+          id: id,
+          type: type
+        };
+      }
+    }, {
+      key: 'isFocusable',
+      get: function get() {
+        if (!this._cache.hasOwnProperty('isFocusable')) {
+          this._cache.isFocusable = axe.commons.dom.isFocusable(this.actualNode);
+        }
+        return this._cache.isFocusable;
+      }
+    }, {
+      key: 'tabbableElements',
+      get: function get() {
+        if (!this._cache.hasOwnProperty('tabbableElements')) {
+          this._cache.tabbableElements = axe.commons.dom.getTabbableElements(this);
+        }
+        return this._cache.tabbableElements;
+      }
+    } ]);
+    return VirtualNode;
+  }(AbstractVirtualNode);
+  axe.AbstractVirtualNode = AbstractVirtualNode;
+  'use strict';
   (function(axe) {
     var definitions = [ {
       name: 'NA',
@@ -724,7 +3736,11 @@
       results: [],
       resultGroups: [],
       resultGroupMap: {},
-      impact: Object.freeze([ 'minor', 'moderate', 'serious', 'critical' ])
+      impact: Object.freeze([ 'minor', 'moderate', 'serious', 'critical' ]),
+      preload: Object.freeze({
+        assets: [ 'cssom' ],
+        timeout: 1e4
+      })
     };
     definitions.forEach(function(definition) {
       var name = definition.name;
@@ -750,11 +3766,18 @@
     });
   })(axe);
   'use strict';
-  var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-    return typeof obj;
-  } : function(obj) {
-    return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-  };
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
   axe.log = function() {
     'use strict';
     if ((typeof console === 'undefined' ? 'undefined' : _typeof(console)) === 'object' && console.log) {
@@ -762,42 +3785,10 @@
     }
   };
   'use strict';
-  var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-    return typeof obj;
-  } : function(obj) {
-    return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-  };
-  axe.a11yCheck = function(context, options, callback) {
-    'use strict';
-    if (typeof options === 'function') {
-      callback = options;
-      options = {};
-    }
-    if (!options || (typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') {
-      options = {};
-    }
-    var audit = axe._audit;
-    if (!audit) {
-      throw new Error('No audit configured');
-    }
-    options.reporter = options.reporter || audit.reporter || 'v2';
-    if (options.performanceTimer) {
-      axe.utils.performanceTimer.start();
-    }
-    var reporter = axe.getReporter(options.reporter);
-    axe._runRules(context, options, function(results) {
-      var res = reporter(results, options, callback);
-      if (res !== undefined) {
-        if (options.performanceTimer) {
-          axe.utils.performanceTimer.end();
-        }
-        callback(res);
-      }
-    }, axe.log);
-  };
-  'use strict';
   function cleanupPlugins(resolve, reject) {
     'use strict';
+    resolve = resolve || function() {};
+    reject = reject || axe.log;
     if (!axe._audit) {
       throw new Error('No audit configured');
     }
@@ -816,9 +3807,10 @@
         }
       });
     });
-    axe.utils.toArray(document.querySelectorAll('frame, iframe')).forEach(function(frame) {
+    var flattenedTree = axe.utils.getFlattenedTree(document.body);
+    axe.utils.querySelectorAll(flattenedTree, 'iframe, frame').forEach(function(node) {
       q.defer(function(res, rej) {
-        return axe.utils.sendCommandToFrame(frame, {
+        return axe.utils.sendCommandToFrame(node.actualNode, {
           command: 'cleanup-plugin'
         }, res, rej);
       });
@@ -829,7 +3821,7 @@
       } else {
         reject(cleanupErrors);
       }
-    }).catch(reject);
+    })['catch'](reject);
   }
   axe.cleanup = cleanupPlugins;
   'use strict';
@@ -848,11 +3840,20 @@
         audit.addCheck(check);
       });
     }
+    var modifiedRules = [];
     if (spec.rules) {
       spec.rules.forEach(function(rule) {
+        modifiedRules.push(rule.id);
         audit.addRule(rule);
       });
     }
+    if (spec.disableOtherRules) {
+      audit.rules.forEach(function(rule) {
+        if (modifiedRules.includes(rule.id) === false) {
+          rule.enabled = false;
+        }
+      });
+    }
     if (typeof spec.branding !== 'undefined') {
       audit.setBranding(spec.branding);
     } else {
@@ -861,6 +3862,9 @@
     if (spec.tagExclude) {
       audit.tagExclude = spec.tagExclude;
     }
+    if (spec.locale) {
+      audit.applyLocale(spec.locale);
+    }
   }
   axe.configure = configureChecksRulesAndBranding;
   'use strict';
@@ -895,13 +3899,16 @@
       callback(err);
     };
     var context = data && data.context || {};
-    if (context.include && !context.include.length) {
+    if (context.hasOwnProperty('include') && !context.include.length) {
       context.include = [ document ];
     }
     var options = data && data.options || {};
     switch (data.command) {
      case 'rules':
-      return runRules(context, options, resolve, reject);
+      return runRules(context, options, function(results, cleanup) {
+        resolve(results);
+        cleanup();
+      }, reject);
 
      case 'cleanup-plugin':
       return cleanupPlugins(resolve, reject);
@@ -994,11 +4001,19 @@
   }
   axe.reset = resetConfiguration;
   'use strict';
+  function cleanup() {
+    axe._cache.clear();
+    axe._tree = undefined;
+    axe._selectorData = undefined;
+  }
   function runRules(context, options, resolve, reject) {
     'use strict';
     try {
       context = new Context(context);
+      axe._tree = context.flatTree;
+      axe._selectorData = axe.utils.getSelectorData(context.flatTree);
     } catch (e) {
+      cleanup();
       return reject(e);
     }
     var q = axe.utils.queue();
@@ -1011,23 +4026,24 @@
         axe.utils.collectResultsFromFrames(context, options, 'rules', null, res, rej);
       });
     }
+    var scrollState;
     q.defer(function(res, rej) {
       if (options.restoreScroll) {
-        var scrollState = axe.utils.getScrollState();
-        audit.run(context, options, res, rej);
-        axe.utils.setScrollState(scrollState);
-      } else {
-        audit.run(context, options, res, rej);
+        scrollState = axe.utils.getScrollState();
       }
+      audit.run(context, options, res, rej);
     });
     q.then(function(data) {
       try {
+        if (scrollState) {
+          axe.utils.setScrollState(scrollState);
+        }
         if (options.performanceTimer) {
           axe.utils.performanceTimer.auditEnd();
         }
-        var results = axe.utils.mergeResults(data.map(function(d) {
+        var results = axe.utils.mergeResults(data.map(function(results) {
           return {
-            results: d
+            results: results
           };
         }));
         if (context.initiator) {
@@ -1036,22 +4052,80 @@
           results = results.map(axe.utils.finalizeRuleResult);
         }
         try {
-          resolve(results);
+          resolve(results, cleanup);
         } catch (e) {
+          cleanup();
           axe.log(e);
         }
       } catch (e) {
+        cleanup();
         reject(e);
       }
-    }).catch(reject);
+    })['catch'](function(e) {
+      cleanup();
+      reject(e);
+    });
   }
   axe._runRules = runRules;
   'use strict';
-  var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-    return typeof obj;
-  } : function(obj) {
-    return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+  function _extends() {
+    _extends = Object.assign || function(target) {
+      for (var i = 1; i < arguments.length; i++) {
+        var source = arguments[i];
+        for (var key in source) {
+          if (Object.prototype.hasOwnProperty.call(source, key)) {
+            target[key] = source[key];
+          }
+        }
+      }
+      return target;
+    };
+    return _extends.apply(this, arguments);
+  }
+  axe.runVirtualRule = function(ruleId, vNode) {
+    var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+    options.reporter = options.reporter || axe._audit.reporter || 'v1';
+    axe._selectorData = {};
+    var rule = axe._audit.rules.find(function(rule) {
+      return rule.id === ruleId;
+    });
+    if (!rule) {
+      throw new Error('unknown rule `' + ruleId + '`');
+    }
+    rule = Object.create(rule, {
+      excludeHidden: {
+        value: false
+      }
+    });
+    var context = {
+      include: [ vNode ]
+    };
+    var rawResults = rule.runSync(context, options);
+    axe.utils.publishMetaData(rawResults);
+    axe.utils.finalizeRuleResult(rawResults);
+    var results = axe.utils.aggregateResult([ rawResults ]);
+    results.violations.forEach(function(result) {
+      return result.nodes.forEach(function(nodeResult) {
+        nodeResult.failureSummary = helpers.failureSummary(nodeResult);
+      });
+    });
+    return _extends({}, helpers.getEnvironmentData(), {}, results, {
+      toolOptions: options
+    });
   };
+  'use strict';
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
   function isContext(potential) {
     'use strict';
     switch (true) {
@@ -1061,7 +4135,7 @@
      case NodeList && potential instanceof NodeList:
       return true;
 
-     case (typeof potential === 'undefined' ? 'undefined' : _typeof(potential)) !== 'object':
+     case _typeof(potential) !== 'object':
       return false;
 
      case potential.include !== undefined:
@@ -1085,7 +4159,7 @@
       options = context;
       context = document;
     }
-    if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') {
+    if (_typeof(options) !== 'object') {
       if (callback !== undefined) {
         throw typeErr;
       }
@@ -1114,17 +4188,18 @@
     if (options.performanceTimer) {
       axe.utils.performanceTimer.start();
     }
-    var p = void 0;
+    var p;
     var reject = noop;
     var resolve = noop;
-    if (window.Promise && callback === noop) {
+    if (typeof Promise === 'function' && callback === noop) {
       p = new Promise(function(_resolve, _reject) {
         reject = _reject;
         resolve = _resolve;
       });
     }
-    axe._runRules(context, options, function(rawResults) {
+    axe._runRules(context, options, function(rawResults, cleanup) {
       var respond = function respond(results) {
+        cleanup();
         try {
           callback(null, results);
         } catch (e) {
@@ -1142,6 +4217,7 @@
           respond(results);
         }
       } catch (err) {
+        cleanup();
         callback(err);
         reject(err);
       }
@@ -1172,16 +4248,47 @@
     }).join('\n\n');
   };
   'use strict';
+  helpers.getEnvironmentData = function getEnvironmentData() {
+    var win = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : window;
+    var _win$screen = win.screen, screen = _win$screen === void 0 ? {} : _win$screen, _win$navigator = win.navigator, navigator = _win$navigator === void 0 ? {} : _win$navigator, _win$location = win.location, location = _win$location === void 0 ? {} : _win$location, innerHeight = win.innerHeight, innerWidth = win.innerWidth;
+    var orientation = screen.msOrientation || screen.orientation || screen.mozOrientation || {};
+    return {
+      testEngine: {
+        name: 'axe-core',
+        version: axe.version
+      },
+      testRunner: {
+        name: axe._audit.brand
+      },
+      testEnvironment: {
+        userAgent: navigator.userAgent,
+        windowWidth: innerWidth,
+        windowHeight: innerHeight,
+        orientationAngle: orientation.angle,
+        orientationType: orientation.type
+      },
+      timestamp: new Date().toISOString(),
+      url: location.href
+    };
+  };
+  'use strict';
   helpers.incompleteFallbackMessage = function incompleteFallbackMessage() {
     'use strict';
     return axe._audit.data.incompleteFallbackMessage();
   };
   'use strict';
-  var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-    return typeof obj;
-  } : function(obj) {
-    return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-  };
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
   function normalizeRelatedNodes(node, options) {
     'use strict';
     [ 'any', 'all', 'none' ].forEach(function(type) {
@@ -1212,9 +4319,14 @@
   var resultKeys = axe.constants.resultGroups;
   helpers.processAggregate = function(results, options) {
     var resultObject = axe.utils.aggregateResult(results);
-    resultObject.timestamp = new Date().toISOString();
-    resultObject.url = window.location.href;
     resultKeys.forEach(function(key) {
+      if (options.resultTypes && !options.resultTypes.includes(key)) {
+        (resultObject[key] || []).forEach(function(ruleResult) {
+          if (Array.isArray(ruleResult.nodes) && ruleResult.nodes.length > 0) {
+            ruleResult.nodes = [ ruleResult.nodes[0] ];
+          }
+        });
+      }
       resultObject[key] = (resultObject[key] || []).map(function(ruleResult) {
         ruleResult = Object.assign({}, ruleResult);
         if (Array.isArray(ruleResult.nodes) && ruleResult.nodes.length > 0) {
@@ -1248,46 +4360,135 @@
     return resultObject;
   };
   'use strict';
+  function _extends() {
+    _extends = Object.assign || function(target) {
+      for (var i = 1; i < arguments.length; i++) {
+        var source = arguments[i];
+        for (var key in source) {
+          if (Object.prototype.hasOwnProperty.call(source, key)) {
+            target[key] = source[key];
+          }
+        }
+      }
+      return target;
+    };
+    return _extends.apply(this, arguments);
+  }
   axe.addReporter('na', function(results, options, callback) {
     'use strict';
+    console.warn('"na" reporter will be deprecated in axe v4.0. Use the "v2" reporter instead.');
     if (typeof options === 'function') {
       callback = options;
       options = {};
     }
     var out = helpers.processAggregate(results, options);
-    callback({
+    callback(_extends({}, helpers.getEnvironmentData(), {
+      toolOptions: options,
       violations: out.violations,
       passes: out.passes,
       incomplete: out.incomplete,
-      inapplicable: out.inapplicable,
-      timestamp: out.timestamp,
-      url: out.url
-    });
+      inapplicable: out.inapplicable
+    }));
   });
   'use strict';
+  function _extends() {
+    _extends = Object.assign || function(target) {
+      for (var i = 1; i < arguments.length; i++) {
+        var source = arguments[i];
+        for (var key in source) {
+          if (Object.prototype.hasOwnProperty.call(source, key)) {
+            target[key] = source[key];
+          }
+        }
+      }
+      return target;
+    };
+    return _extends.apply(this, arguments);
+  }
   axe.addReporter('no-passes', function(results, options, callback) {
     'use strict';
     if (typeof options === 'function') {
       callback = options;
       options = {};
     }
+    options.resultTypes = [ 'violations' ];
     var out = helpers.processAggregate(results, options);
-    callback({
-      violations: out.violations,
-      timestamp: out.timestamp,
-      url: out.url
-    });
+    callback(_extends({}, helpers.getEnvironmentData(), {
+      toolOptions: options,
+      violations: out.violations
+    }));
   });
   'use strict';
+  axe.addReporter('rawEnv', function(results, options, callback) {
+    if (typeof options === 'function') {
+      callback = options;
+      options = {};
+    }
+    function rawCallback(raw) {
+      var env = helpers.getEnvironmentData();
+      callback({
+        raw: raw,
+        env: env
+      });
+    }
+    axe.getReporter('raw')(results, options, rawCallback);
+  });
+  'use strict';
+  function _extends() {
+    _extends = Object.assign || function(target) {
+      for (var i = 1; i < arguments.length; i++) {
+        var source = arguments[i];
+        for (var key in source) {
+          if (Object.prototype.hasOwnProperty.call(source, key)) {
+            target[key] = source[key];
+          }
+        }
+      }
+      return target;
+    };
+    return _extends.apply(this, arguments);
+  }
   axe.addReporter('raw', function(results, options, callback) {
     'use strict';
     if (typeof options === 'function') {
       callback = options;
       options = {};
     }
-    callback(results);
+    if (!results || !Array.isArray(results)) {
+      return callback(results);
+    }
+    var transformedResults = results.map(function(result) {
+      var transformedResult = _extends({}, result);
+      var types = [ 'passes', 'violations', 'incomplete', 'inapplicable' ];
+      for (var _i = 0, _types = types; _i < _types.length; _i++) {
+        var type = _types[_i];
+        if (transformedResult[type] && Array.isArray(transformedResult[type])) {
+          transformedResult[type] = transformedResult[type].map(function(typeResult) {
+            return _extends({}, typeResult, {
+              node: typeResult.node.toJSON()
+            });
+          });
+        }
+      }
+      return transformedResult;
+    });
+    callback(transformedResults);
   });
   'use strict';
+  function _extends() {
+    _extends = Object.assign || function(target) {
+      for (var i = 1; i < arguments.length; i++) {
+        var source = arguments[i];
+        for (var key in source) {
+          if (Object.prototype.hasOwnProperty.call(source, key)) {
+            target[key] = source[key];
+          }
+        }
+      }
+      return target;
+    };
+    return _extends.apply(this, arguments);
+  }
   axe.addReporter('v1', function(results, options, callback) {
     'use strict';
     if (typeof options === 'function') {
@@ -1300,16 +4501,29 @@
         nodeResult.failureSummary = helpers.failureSummary(nodeResult);
       });
     });
-    callback({
+    callback(_extends({}, helpers.getEnvironmentData(), {
+      toolOptions: options,
       violations: out.violations,
       passes: out.passes,
       incomplete: out.incomplete,
-      inapplicable: out.inapplicable,
-      timestamp: out.timestamp,
-      url: out.url
-    });
+      inapplicable: out.inapplicable
+    }));
   });
   'use strict';
+  function _extends() {
+    _extends = Object.assign || function(target) {
+      for (var i = 1; i < arguments.length; i++) {
+        var source = arguments[i];
+        for (var key in source) {
+          if (Object.prototype.hasOwnProperty.call(source, key)) {
+            target[key] = source[key];
+          }
+        }
+      }
+      return target;
+    };
+    return _extends.apply(this, arguments);
+  }
   axe.addReporter('v2', function(results, options, callback) {
     'use strict';
     if (typeof options === 'function') {
@@ -1317,14 +4531,13 @@
       options = {};
     }
     var out = helpers.processAggregate(results, options);
-    callback({
+    callback(_extends({}, helpers.getEnvironmentData(), {
+      toolOptions: options,
       violations: out.violations,
       passes: out.passes,
       incomplete: out.incomplete,
-      inapplicable: out.inapplicable,
-      timestamp: out.timestamp,
-      url: out.url
-    });
+      inapplicable: out.inapplicable
+    }));
   }, true);
   'use strict';
   axe.utils.aggregate = function(map, values, initial) {
@@ -1338,6 +4551,7 @@
     return map[sorting.pop()];
   };
   'use strict';
+  var _axe$constants = axe.constants, CANTTELL_PRIO = _axe$constants.CANTTELL_PRIO, FAIL_PRIO = _axe$constants.FAIL_PRIO;
   var checkMap = [];
   checkMap[axe.constants.PASS_PRIO] = true;
   checkMap[axe.constants.CANTTELL_PRIO] = null;
@@ -1354,32 +4568,38 @@
   axe.utils.aggregateChecks = function(nodeResOriginal) {
     var nodeResult = Object.assign({}, nodeResOriginal);
     anyAllNone(nodeResult, function(check, type) {
-      var i = checkMap.indexOf(check.result);
+      var i = typeof check.result === 'undefined' ? -1 : checkMap.indexOf(check.result);
       check.priority = i !== -1 ? i : axe.constants.CANTTELL_PRIO;
       if (type === 'none') {
-        check.priority = 4 - check.priority;
+        if (check.priority === axe.constants.PASS_PRIO) {
+          check.priority = axe.constants.FAIL_PRIO;
+        } else if (check.priority === axe.constants.FAIL_PRIO) {
+          check.priority = axe.constants.PASS_PRIO;
+        }
       }
     });
-    var priorities = anyAllNone(nodeResult, function(c) {
-      return c.priority;
-    });
-    nodeResult.priority = Math.max(priorities.all.reduce(function(a, b) {
-      return Math.max(a, b);
-    }, 0), priorities.none.reduce(function(a, b) {
-      return Math.max(a, b);
-    }, 0), priorities.any.reduce(function(a, b) {
-      return Math.min(a, b);
-    }, 4) % 4);
+    var priorities = {
+      all: nodeResult.all.reduce(function(a, b) {
+        return Math.max(a, b.priority);
+      }, 0),
+      none: nodeResult.none.reduce(function(a, b) {
+        return Math.max(a, b.priority);
+      }, 0),
+      any: nodeResult.any.reduce(function(a, b) {
+        return Math.min(a, b.priority);
+      }, 4) % 4
+    };
+    nodeResult.priority = Math.max(priorities.all, priorities.none, priorities.any);
     var impacts = [];
     checkTypes.forEach(function(type) {
       nodeResult[type] = nodeResult[type].filter(function(check) {
-        return check.priority === nodeResult.priority;
+        return check.priority === nodeResult.priority && check.priority === priorities[type];
       });
       nodeResult[type].forEach(function(check) {
         return impacts.push(check.impact);
       });
     });
-    if (nodeResult.priority === axe.constants.FAIL_PRIO) {
+    if ([ CANTTELL_PRIO, FAIL_PRIO ].includes(nodeResult.priority)) {
       nodeResult.impact = axe.utils.aggregate(axe.constants.impact, impacts);
     } else {
       nodeResult.impact = null;
@@ -1393,6 +4613,49 @@
     return nodeResult;
   };
   'use strict';
+  (function() {
+    axe.utils.aggregateNodeResults = function(nodeResults) {
+      var ruleResult = {};
+      nodeResults = nodeResults.map(function(nodeResult) {
+        if (nodeResult.any && nodeResult.all && nodeResult.none) {
+          return axe.utils.aggregateChecks(nodeResult);
+        } else if (Array.isArray(nodeResult.node)) {
+          return axe.utils.finalizeRuleResult(nodeResult);
+        } else {
+          throw new TypeError('Invalid Result type');
+        }
+      });
+      if (nodeResults && nodeResults.length) {
+        var resultList = nodeResults.map(function(node) {
+          return node.result;
+        });
+        ruleResult.result = axe.utils.aggregate(axe.constants.results, resultList, ruleResult.result);
+      } else {
+        ruleResult.result = 'inapplicable';
+      }
+      axe.constants.resultGroups.forEach(function(group) {
+        return ruleResult[group] = [];
+      });
+      nodeResults.forEach(function(nodeResult) {
+        var groupName = axe.constants.resultGroupMap[nodeResult.result];
+        ruleResult[groupName].push(nodeResult);
+      });
+      var impactGroup = axe.constants.FAIL_GROUP;
+      if (ruleResult[impactGroup].length === 0) {
+        impactGroup = axe.constants.CANTTELL_GROUP;
+      }
+      if (ruleResult[impactGroup].length > 0) {
+        var impactList = ruleResult[impactGroup].map(function(failure) {
+          return failure.impact;
+        });
+        ruleResult.impact = axe.utils.aggregate(axe.constants.impact, impactList) || null;
+      } else {
+        ruleResult.impact = null;
+      }
+      return ruleResult;
+    };
+  })();
+  'use strict';
   function copyToGroup(resultObject, subResult, group) {
     var resultCopy = Object.assign({}, subResult);
     resultCopy.nodes = (resultCopy[group] || []).concat();
@@ -1422,42 +4685,6 @@
     return resultObject;
   };
   'use strict';
-  (function() {
-    axe.utils.aggregateRule = function(subResults) {
-      var ruleResult = {};
-      subResults = subResults.map(function(subResult) {
-        if (subResult.any && subResult.all && subResult.none) {
-          return axe.utils.aggregateChecks(subResult);
-        } else if (Array.isArray(subResult.node)) {
-          return axe.utils.finalizeRuleResult(subResult);
-        } else {
-          throw new TypeError('Invalid Result type');
-        }
-      });
-      var resultList = subResults.map(function(node) {
-        return node.result;
-      });
-      ruleResult.result = axe.utils.aggregate(axe.constants.results, resultList, ruleResult.result);
-      axe.constants.resultGroups.forEach(function(group) {
-        return ruleResult[group] = [];
-      });
-      subResults.forEach(function(subResult) {
-        var groupName = axe.constants.resultGroupMap[subResult.result];
-        ruleResult[groupName].push(subResult);
-      });
-      var failGroup = axe.constants.FAIL_GROUP;
-      if (ruleResult[failGroup].length > 0) {
-        var impactList = ruleResult[failGroup].map(function(failure) {
-          return failure.impact;
-        });
-        ruleResult.impact = axe.utils.aggregate(axe.constants.impact, impactList) || null;
-      } else {
-        ruleResult.impact = null;
-      }
-      return ruleResult;
-    };
-  })();
-  'use strict';
   function areStylesSet(el, styles, stopAt) {
     'use strict';
     var styl = window.getComputedStyle(el, null);
@@ -1488,7 +4715,7 @@
         this.isAsync = true;
         return function(result) {
           if (result instanceof Error === false) {
-            checkResult.value = result;
+            checkResult.result = result;
             resolve(checkResult);
           } else {
             reject(result);
@@ -1507,15 +4734,22 @@
     };
   };
   'use strict';
-  var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-    return typeof obj;
-  } : function(obj) {
-    return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-  };
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
   axe.utils.clone = function(obj) {
     'use strict';
     var index, length, out = obj;
-    if (obj !== null && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object') {
+    if (obj !== null && _typeof(obj) === 'object') {
       if (Array.isArray(obj)) {
         out = [];
         for (index = 0, length = obj.length; index < length; index++) {
@@ -1533,7 +4767,11 @@
   'use strict';
   function err(message, node) {
     'use strict';
-    return new Error(message + ': ' + axe.utils.getSelector(node));
+    var selector;
+    if (axe._tree) {
+      selector = axe.utils.getSelector(node);
+    }
+    return new Error(message + ': ' + (selector || node));
   }
   axe.utils.sendCommandToFrame = function(node, parameters, resolve, reject) {
     'use strict';
@@ -1545,20 +4783,19 @@
     }
     var timeout = setTimeout(function() {
       timeout = setTimeout(function() {
-        var errMsg = err('No response from frame', node);
         if (!parameters.debug) {
-          axe.log(errMsg);
           resolve(null);
         } else {
-          reject(errMsg);
+          reject(err('No response from frame', node));
         }
       }, 0);
     }, 500);
     axe.utils.respondable(win, 'axe.ping', null, undefined, function() {
       clearTimeout(timeout);
+      var frameWaitTime = parameters.options && parameters.options.frameWaitTime || 6e4;
       timeout = setTimeout(function() {
         reject(err('Axe in frame timed out', node));
-      }, 3e4);
+      }, frameWaitTime);
       axe.utils.respondable(win, 'axe.start', parameters, undefined, function(data) {
         clearTimeout(timeout);
         if (data instanceof Error === false) {
@@ -1601,611 +4838,43 @@
     });
     q.then(function(data) {
       resolve(axe.utils.mergeResults(data, options));
-    }).catch(reject);
+    })['catch'](reject);
   }
   axe.utils.collectResultsFromFrames = collectResultsFromFrames;
   'use strict';
-  axe.utils.contains = function(node, otherNode) {
+  axe.utils.contains = function(vNode, otherVNode) {
     'use strict';
-    function containsShadowChild(node, otherNode) {
-      if (node.shadowId === otherNode.shadowId) {
+    function containsShadowChild(vNode, otherVNode) {
+      if (vNode.shadowId === otherVNode.shadowId) {
         return true;
       }
-      return !!node.children.find(function(child) {
-        return containsShadowChild(child, otherNode);
+      return !!vNode.children.find(function(child) {
+        return containsShadowChild(child, otherVNode);
       });
     }
-    if (node.shadowId || otherNode.shadowId) {
-      return containsShadowChild(node, otherNode);
+    if (vNode.shadowId || otherVNode.shadowId) {
+      return containsShadowChild(vNode, otherVNode);
     }
-    if (typeof node.actualNode.contains === 'function') {
-      return node.actualNode.contains(otherNode.actualNode);
+    if (vNode.actualNode) {
+      if (typeof vNode.actualNode.contains === 'function') {
+        return vNode.actualNode.contains(otherVNode.actualNode);
+      }
+      return !!(vNode.actualNode.compareDocumentPosition(otherVNode.actualNode) & 16);
+    } else {
+      do {
+        if (otherVNode === vNode) {
+          return true;
+        }
+      } while (otherVNode = otherVNode && otherVNode.parent);
     }
-    return !!(node.actualNode.compareDocumentPosition(otherNode.actualNode) & 16);
+    return false;
   };
   'use strict';
   (function(axe) {
-    /*!
-  * The copyright below covers the code within this function block only
-  *
-  * Copyright (c) 2013 Dulin Marat
-  * 
-  * Permission is hereby granted, free of charge, to any person obtaining a copy
-  * of this software and associated documentation files (the "Software"), to deal
-  * in the Software without restriction, including without limitation the rights
-  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-  * copies of the Software, and to permit persons to whom the Software is
-  * furnished to do so, subject to the following conditions:
-  * 
-  * The above copyright notice and this permission notice shall be included in
-  * all copies or substantial portions of the Software.
-  * 
-  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-  * THE SOFTWARE.
-  */
-    function CssSelectorParser() {
-      this.pseudos = {};
-      this.attrEqualityMods = {};
-      this.ruleNestingOperators = {};
-      this.substitutesEnabled = false;
-    }
-    CssSelectorParser.prototype.registerSelectorPseudos = function(name) {
-      for (var j = 0, len = arguments.length; j < len; j++) {
-        name = arguments[j];
-        this.pseudos[name] = 'selector';
-      }
-      return this;
-    };
-    CssSelectorParser.prototype.unregisterSelectorPseudos = function(name) {
-      for (var j = 0, len = arguments.length; j < len; j++) {
-        name = arguments[j];
-        delete this.pseudos[name];
-      }
-      return this;
-    };
-    CssSelectorParser.prototype.registerNumericPseudos = function(name) {
-      for (var j = 0, len = arguments.length; j < len; j++) {
-        name = arguments[j];
-        this.pseudos[name] = 'numeric';
-      }
-      return this;
-    };
-    CssSelectorParser.prototype.unregisterNumericPseudos = function(name) {
-      for (var j = 0, len = arguments.length; j < len; j++) {
-        name = arguments[j];
-        delete this.pseudos[name];
-      }
-      return this;
-    };
-    CssSelectorParser.prototype.registerNestingOperators = function(operator) {
-      for (var j = 0, len = arguments.length; j < len; j++) {
-        operator = arguments[j];
-        this.ruleNestingOperators[operator] = true;
-      }
-      return this;
-    };
-    CssSelectorParser.prototype.unregisterNestingOperators = function(operator) {
-      for (var j = 0, len = arguments.length; j < len; j++) {
-        operator = arguments[j];
-        delete this.ruleNestingOperators[operator];
-      }
-      return this;
-    };
-    CssSelectorParser.prototype.registerAttrEqualityMods = function(mod) {
-      for (var j = 0, len = arguments.length; j < len; j++) {
-        mod = arguments[j];
-        this.attrEqualityMods[mod] = true;
-      }
-      return this;
-    };
-    CssSelectorParser.prototype.unregisterAttrEqualityMods = function(mod) {
-      for (var j = 0, len = arguments.length; j < len; j++) {
-        mod = arguments[j];
-        delete this.attrEqualityMods[mod];
-      }
-      return this;
-    };
-    CssSelectorParser.prototype.enableSubstitutes = function() {
-      this.substitutesEnabled = true;
-      return this;
-    };
-    CssSelectorParser.prototype.disableSubstitutes = function() {
-      this.substitutesEnabled = false;
-      return this;
-    };
-    function isIdentStart(c) {
-      return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c === '-' || c === '_';
-    }
-    function isIdent(c) {
-      return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c === '-' || c === '_';
-    }
-    function isHex(c) {
-      return c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F' || c >= '0' && c <= '9';
-    }
-    function isDecimal(c) {
-      return c >= '0' && c <= '9';
-    }
-    function isAttrMatchOperator(chr) {
-      return chr === '=' || chr === '^' || chr === '$' || chr === '*' || chr === '~';
-    }
-    var identSpecialChars = {
-      '!': true,
-      '"': true,
-      '#': true,
-      $: true,
-      '%': true,
-      '&': true,
-      '\'': true,
-      '(': true,
-      ')': true,
-      '*': true,
-      '+': true,
-      ',': true,
-      '.': true,
-      '/': true,
-      ';': true,
-      '<': true,
-      '=': true,
-      '>': true,
-      '?': true,
-      '@': true,
-      '[': true,
-      '\\': true,
-      ']': true,
-      '^': true,
-      '`': true,
-      '{': true,
-      '|': true,
-      '}': true,
-      '~': true
-    };
-    var strReplacementsRev = {
-      '\n': '\\n',
-      '\r': '\\r',
-      '\t': '\\t',
-      '\f': '\\f',
-      '\v': '\\v'
-    };
-    var singleQuoteEscapeChars = {
-      n: '\n',
-      r: '\r',
-      t: '\t',
-      f: '\f',
-      '\\': '\\',
-      '\'': '\''
-    };
-    var doubleQuotesEscapeChars = {
-      n: '\n',
-      r: '\r',
-      t: '\t',
-      f: '\f',
-      '\\': '\\',
-      '"': '"'
-    };
-    function ParseContext(str, pos, pseudos, attrEqualityMods, ruleNestingOperators, substitutesEnabled) {
-      var chr, getIdent, getStr, l, skipWhitespace;
-      l = str.length;
-      chr = null;
-      getStr = function getStr(quote, escapeTable) {
-        var esc, hex, result;
-        result = '';
-        pos++;
-        chr = str.charAt(pos);
-        while (pos < l) {
-          if (chr === quote) {
-            pos++;
-            return result;
-          } else if (chr === '\\') {
-            pos++;
-            chr = str.charAt(pos);
-            if (chr === quote) {
-              result += quote;
-            } else if (esc = escapeTable[chr]) {
-              result += esc;
-            } else if (isHex(chr)) {
-              hex = chr;
-              pos++;
-              chr = str.charAt(pos);
-              while (isHex(chr)) {
-                hex += chr;
-                pos++;
-                chr = str.charAt(pos);
-              }
-              if (chr === ' ') {
-                pos++;
-                chr = str.charAt(pos);
-              }
-              result += String.fromCharCode(parseInt(hex, 16));
-              continue;
-            } else {
-              result += chr;
-            }
-          } else {
-            result += chr;
-          }
-          pos++;
-          chr = str.charAt(pos);
-        }
-        return result;
-      };
-      getIdent = function getIdent() {
-        var result = '';
-        chr = str.charAt(pos);
-        while (pos < l) {
-          if (isIdent(chr)) {
-            result += chr;
-          } else if (chr === '\\') {
-            pos++;
-            if (pos >= l) {
-              throw Error('Expected symbol but end of file reached.');
-            }
-            chr = str.charAt(pos);
-            if (identSpecialChars[chr]) {
-              result += chr;
-            } else if (isHex(chr)) {
-              var hex = chr;
-              pos++;
-              chr = str.charAt(pos);
-              while (isHex(chr)) {
-                hex += chr;
-                pos++;
-                chr = str.charAt(pos);
-              }
-              if (chr === ' ') {
-                pos++;
-                chr = str.charAt(pos);
-              }
-              result += String.fromCharCode(parseInt(hex, 16));
-              continue;
-            } else {
-              result += chr;
-            }
-          } else {
-            return result;
-          }
-          pos++;
-          chr = str.charAt(pos);
-        }
-        return result;
-      };
-      skipWhitespace = function skipWhitespace() {
-        chr = str.charAt(pos);
-        var result = false;
-        while (chr === ' ' || chr === '\t' || chr === '\n' || chr === '\r' || chr === '\f') {
-          result = true;
-          pos++;
-          chr = str.charAt(pos);
-        }
-        return result;
-      };
-      this.parse = function() {
-        var res = this.parseSelector();
-        if (pos < l) {
-          throw Error('Rule expected but "' + str.charAt(pos) + '" found.');
-        }
-        return res;
-      };
-      this.parseSelector = function() {
-        var res;
-        var selector = res = this.parseSingleSelector();
-        chr = str.charAt(pos);
-        while (chr === ',') {
-          pos++;
-          skipWhitespace();
-          if (res.type !== 'selectors') {
-            res = {
-              type: 'selectors',
-              selectors: [ selector ]
-            };
-          }
-          selector = this.parseSingleSelector();
-          if (!selector) {
-            throw Error('Rule expected after ",".');
-          }
-          res.selectors.push(selector);
-        }
-        return res;
-      };
-      this.parseSingleSelector = function() {
-        skipWhitespace();
-        var selector = {
-          type: 'ruleSet'
-        };
-        var rule = this.parseRule();
-        if (!rule) {
-          return null;
-        }
-        var currentRule = selector;
-        while (rule) {
-          rule.type = 'rule';
-          currentRule.rule = rule;
-          currentRule = rule;
-          skipWhitespace();
-          chr = str.charAt(pos);
-          if (pos >= l || chr === ',' || chr === ')') {
-            break;
-          }
-          if (ruleNestingOperators[chr]) {
-            var op = chr;
-            pos++;
-            skipWhitespace();
-            rule = this.parseRule();
-            if (!rule) {
-              throw Error('Rule expected after "' + op + '".');
-            }
-            rule.nestingOperator = op;
-          } else {
-            rule = this.parseRule();
-            if (rule) {
-              rule.nestingOperator = null;
-            }
-          }
-        }
-        return selector;
-      };
-      this.parseRule = function() {
-        var rule = null;
-        while (pos < l) {
-          chr = str.charAt(pos);
-          if (chr === '*') {
-            pos++;
-            (rule = rule || {}).tagName = '*';
-          } else if (isIdentStart(chr) || chr === '\\') {
-            (rule = rule || {}).tagName = getIdent();
-          } else if (chr === '.') {
-            pos++;
-            rule = rule || {};
-            (rule.classNames = rule.classNames || []).push(getIdent());
-          } else if (chr === '#') {
-            pos++;
-            (rule = rule || {}).id = getIdent();
-          } else if (chr === '[') {
-            pos++;
-            skipWhitespace();
-            var attr = {
-              name: getIdent()
-            };
-            skipWhitespace();
-            if (chr === ']') {
-              pos++;
-            } else {
-              var operator = '';
-              if (attrEqualityMods[chr]) {
-                operator = chr;
-                pos++;
-                chr = str.charAt(pos);
-              }
-              if (pos >= l) {
-                throw Error('Expected "=" but end of file reached.');
-              }
-              if (chr !== '=') {
-                throw Error('Expected "=" but "' + chr + '" found.');
-              }
-              attr.operator = operator + '=';
-              pos++;
-              skipWhitespace();
-              var attrValue = '';
-              attr.valueType = 'string';
-              if (chr === '"') {
-                attrValue = getStr('"', doubleQuotesEscapeChars);
-              } else if (chr === '\'') {
-                attrValue = getStr('\'', singleQuoteEscapeChars);
-              } else if (substitutesEnabled && chr === '$') {
-                pos++;
-                attrValue = getIdent();
-                attr.valueType = 'substitute';
-              } else {
-                while (pos < l) {
-                  if (chr === ']') {
-                    break;
-                  }
-                  attrValue += chr;
-                  pos++;
-                  chr = str.charAt(pos);
-                }
-                attrValue = attrValue.trim();
-              }
-              skipWhitespace();
-              if (pos >= l) {
-                throw Error('Expected "]" but end of file reached.');
-              }
-              if (chr !== ']') {
-                throw Error('Expected "]" but "' + chr + '" found.');
-              }
-              pos++;
-              attr.value = attrValue;
-            }
-            rule = rule || {};
-            (rule.attrs = rule.attrs || []).push(attr);
-          } else if (chr === ':') {
-            pos++;
-            var pseudoName = getIdent();
-            var pseudo = {
-              name: pseudoName
-            };
-            if (chr === '(') {
-              pos++;
-              var value = '';
-              skipWhitespace();
-              if (pseudos[pseudoName] === 'selector') {
-                pseudo.valueType = 'selector';
-                value = this.parseSelector();
-              } else {
-                pseudo.valueType = pseudos[pseudoName] || 'string';
-                if (chr === '"') {
-                  value = getStr('"', doubleQuotesEscapeChars);
-                } else if (chr === '\'') {
-                  value = getStr('\'', singleQuoteEscapeChars);
-                } else if (substitutesEnabled && chr === '$') {
-                  pos++;
-                  value = getIdent();
-                  pseudo.valueType = 'substitute';
-                } else {
-                  while (pos < l) {
-                    if (chr === ')') {
-                      break;
-                    }
-                    value += chr;
-                    pos++;
-                    chr = str.charAt(pos);
-                  }
-                  value = value.trim();
-                }
-                skipWhitespace();
-              }
-              if (pos >= l) {
-                throw Error('Expected ")" but end of file reached.');
-              }
-              if (chr !== ')') {
-                throw Error('Expected ")" but "' + chr + '" found.');
-              }
-              pos++;
-              pseudo.value = value;
-            }
-            rule = rule || {};
-            (rule.pseudos = rule.pseudos || []).push(pseudo);
-          } else {
-            break;
-          }
-        }
-        return rule;
-      };
-      return this;
-    }
-    CssSelectorParser.prototype.parse = function(str) {
-      var context = new ParseContext(str, 0, this.pseudos, this.attrEqualityMods, this.ruleNestingOperators, this.substitutesEnabled);
-      return context.parse();
-    };
-    CssSelectorParser.prototype.escapeIdentifier = function(s) {
-      var result = '';
-      var i = 0;
-      var len = s.length;
-      while (i < len) {
-        var chr = s.charAt(i);
-        if (identSpecialChars[chr]) {
-          result += '\\' + chr;
-        } else {
-          if (!(chr === '_' || chr === '-' || chr >= 'A' && chr <= 'Z' || chr >= 'a' && chr <= 'z' || i !== 0 && chr >= '0' && chr <= '9')) {
-            var charCode = chr.charCodeAt(0);
-            if ((charCode & 63488) === 55296) {
-              var extraCharCode = s.charCodeAt(i++);
-              if ((charCode & 64512) !== 55296 || (extraCharCode & 64512) !== 56320) {
-                throw Error('UCS-2(decode): illegal sequence');
-              }
-              charCode = ((charCode & 1023) << 10) + (extraCharCode & 1023) + 65536;
-            }
-            result += '\\' + charCode.toString(16) + ' ';
-          } else {
-            result += chr;
-          }
-        }
-        i++;
-      }
-      return result;
-    };
-    CssSelectorParser.prototype.escapeStr = function(s) {
-      var result = '';
-      var i = 0;
-      var len = s.length;
-      var chr, replacement;
-      while (i < len) {
-        chr = s.charAt(i);
-        if (chr === '"') {
-          chr = '\\"';
-        } else if (chr === '\\') {
-          chr = '\\\\';
-        } else if (replacement = strReplacementsRev[chr]) {
-          chr = replacement;
-        }
-        result += chr;
-        i++;
-      }
-      return '"' + result + '"';
-    };
-    CssSelectorParser.prototype.render = function(path) {
-      return this._renderEntity(path).trim();
-    };
-    CssSelectorParser.prototype._renderEntity = function(entity) {
-      var currentEntity, parts, res;
-      res = '';
-      switch (entity.type) {
-       case 'ruleSet':
-        currentEntity = entity.rule;
-        parts = [];
-        while (currentEntity) {
-          if (currentEntity.nestingOperator) {
-            parts.push(currentEntity.nestingOperator);
-          }
-          parts.push(this._renderEntity(currentEntity));
-          currentEntity = currentEntity.rule;
-        }
-        res = parts.join(' ');
-        break;
-
-       case 'selectors':
-        res = entity.selectors.map(this._renderEntity, this).join(', ');
-        break;
-
-       case 'rule':
-        if (entity.tagName) {
-          if (entity.tagName === '*') {
-            res = '*';
-          } else {
-            res = this.escapeIdentifier(entity.tagName);
-          }
-        }
-        if (entity.id) {
-          res += '#' + this.escapeIdentifier(entity.id);
-        }
-        if (entity.classNames) {
-          res += entity.classNames.map(function(cn) {
-            return '.' + this.escapeIdentifier(cn);
-          }, this).join('');
-        }
-        if (entity.attrs) {
-          res += entity.attrs.map(function(attr) {
-            if (attr.operator) {
-              if (attr.valueType === 'substitute') {
-                return '[' + this.escapeIdentifier(attr.name) + attr.operator + '$' + attr.value + ']';
-              } else {
-                return '[' + this.escapeIdentifier(attr.name) + attr.operator + this.escapeStr(attr.value) + ']';
-              }
-            } else {
-              return '[' + this.escapeIdentifier(attr.name) + ']';
-            }
-          }, this).join('');
-        }
-        if (entity.pseudos) {
-          res += entity.pseudos.map(function(pseudo) {
-            if (pseudo.valueType) {
-              if (pseudo.valueType === 'selector') {
-                return ':' + this.escapeIdentifier(pseudo.name) + '(' + this._renderEntity(pseudo.value) + ')';
-              } else if (pseudo.valueType === 'substitute') {
-                return ':' + this.escapeIdentifier(pseudo.name) + '($' + pseudo.value + ')';
-              } else if (pseudo.valueType === 'numeric') {
-                return ':' + this.escapeIdentifier(pseudo.name) + '(' + pseudo.value + ')';
-              } else {
-                return ':' + this.escapeIdentifier(pseudo.name) + '(' + this.escapeIdentifier(pseudo.value) + ')';
-              }
-            } else {
-              return ':' + this.escapeIdentifier(pseudo.name);
-            }
-          }, this).join('');
-        }
-        break;
-
-       default:
-        throw Error('Unknown entity type: "' + entity.type(+'".'));
-      }
-      return res;
-    };
-    var parser = new CssSelectorParser();
+    var parser = new axe.imports.CssSelectorParser();
+    parser.registerSelectorPseudos('not');
     parser.registerNestingOperators('>');
+    parser.registerAttrEqualityMods('^', '$', '*');
     axe.utils.cssParser = parser;
   })(axe);
   'use strict';
@@ -2267,20 +4936,23 @@
   axe.utils.matchesSelector = function() {
     'use strict';
     var method;
-    function getMethod(win) {
-      var index, candidate, elProto = win.Element.prototype, candidates = [ 'matches', 'matchesSelector', 'mozMatchesSelector', 'webkitMatchesSelector', 'msMatchesSelector' ], length = candidates.length;
+    function getMethod(node) {
+      var index, candidate, candidates = [ 'matches', 'matchesSelector', 'mozMatchesSelector', 'webkitMatchesSelector', 'msMatchesSelector' ], length = candidates.length;
       for (index = 0; index < length; index++) {
         candidate = candidates[index];
-        if (elProto[candidate]) {
+        if (node[candidate]) {
           return candidate;
         }
       }
     }
     return function(node, selector) {
       if (!method || !node[method]) {
-        method = getMethod(node.ownerDocument.defaultView);
+        method = getMethod(node);
       }
-      return node[method](selector);
+      if (node[method]) {
+        return node[method](selector);
+      }
+      return false;
     };
   }();
   'use strict';
@@ -2295,13 +4967,14 @@
     while (++index < length) {
       codeUnit = string.charCodeAt(index);
       if (codeUnit == 0) {
-        throw new Error('INVALID_CHARACTER_ERR');
+        result += '�';
+        continue;
       }
-      if (codeUnit >= 1 && codeUnit <= 31 || codeUnit >= 127 && codeUnit <= 159 || index == 0 && codeUnit >= 48 && codeUnit <= 57 || index == 1 && codeUnit >= 48 && codeUnit <= 57 && firstCodeUnit == 45) {
+      if (codeUnit >= 1 && codeUnit <= 31 || codeUnit == 127 || index == 0 && codeUnit >= 48 && codeUnit <= 57 || index == 1 && codeUnit >= 48 && codeUnit <= 57 && firstCodeUnit == 45) {
         result += '\\' + codeUnit.toString(16) + ' ';
         continue;
       }
-      if (index == 1 && codeUnit == 45 && firstCodeUnit == 45) {
+      if (index == 0 && length == 1 && codeUnit == 45) {
         result += '\\' + string.charAt(index);
         continue;
       }
@@ -2327,20 +5000,27 @@
   };
   'use strict';
   axe.utils.finalizeRuleResult = function(ruleResult) {
-    Object.assign(ruleResult, axe.utils.aggregateRule(ruleResult.nodes));
+    Object.assign(ruleResult, axe.utils.aggregateNodeResults(ruleResult.nodes));
     delete ruleResult.nodes;
     return ruleResult;
   };
   'use strict';
-  var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-    return typeof obj;
-  } : function(obj) {
-    return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-  };
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
   axe.utils.findBy = function(array, key, value) {
     if (Array.isArray(array)) {
       return array.find(function(obj) {
-        return (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && obj[key] === value;
+        return _typeof(obj) === 'object' && obj[key] === value;
       });
     }
   };
@@ -2348,13 +5028,6 @@
   var axe = axe || {
     utils: {}
   };
-  function virtualDOMfromNode(node, shadowId) {
-    return {
-      shadowId: shadowId,
-      children: [],
-      actualNode: node
-    };
-  }
   function getSlotChildren(node) {
     var retVal = [];
     node = node.firstChild;
@@ -2364,10 +5037,10 @@
     }
     return retVal;
   }
-  axe.utils.getFlattenedTree = function(node, shadowId) {
+  function flattenTree(node, shadowId, parent) {
     var retVal, realArray, nodeName;
-    function reduceShadowDOM(res, child) {
-      var replacements = axe.utils.getFlattenedTree(child, shadowId);
+    function reduceShadowDOM(res, child, parent) {
+      var replacements = flattenTree(child, shadowId, parent);
       if (replacements) {
         res = res.concat(replacements);
       }
@@ -2377,59 +5050,59 @@
       node = node.documentElement;
     }
     nodeName = node.nodeName.toLowerCase();
-    if (node.shadowRoot && nodeName !== 'marquee') {
-      retVal = virtualDOMfromNode(node, shadowId);
+    if (axe.utils.isShadowRoot(node)) {
+      retVal = new VirtualNode(node, parent, shadowId);
       shadowId = 'a' + Math.random().toString().substring(2);
       realArray = Array.from(node.shadowRoot.childNodes);
-      retVal.children = realArray.reduce(reduceShadowDOM, []);
+      retVal.children = realArray.reduce(function(res, child) {
+        return reduceShadowDOM(res, child, retVal);
+      }, []);
       return [ retVal ];
     } else {
-      if (nodeName === 'content') {
+      if (nodeName === 'content' && typeof node.getDistributedNodes === 'function') {
         realArray = Array.from(node.getDistributedNodes());
-        return realArray.reduce(reduceShadowDOM, []);
-      } else if (nodeName === 'slot') {
+        return realArray.reduce(function(res, child) {
+          return reduceShadowDOM(res, child, parent);
+        }, []);
+      } else if (nodeName === 'slot' && typeof node.assignedNodes === 'function') {
         realArray = Array.from(node.assignedNodes());
         if (!realArray.length) {
           realArray = getSlotChildren(node);
         }
         var styl = window.getComputedStyle(node);
         if (false && styl.display !== 'contents') {
-          retVal = virtualDOMfromNode(node, shadowId);
-          retVal.children = realArray.reduce(reduceShadowDOM, []);
+          retVal = new VirtualNode(node, parent, shadowId);
+          retVal.children = realArray.reduce(function(res, child) {
+            return reduceShadowDOM(res, child, retVal);
+          }, []);
           return [ retVal ];
         } else {
-          return realArray.reduce(reduceShadowDOM, []);
+          return realArray.reduce(function(res, child) {
+            return reduceShadowDOM(res, child, parent);
+          }, []);
         }
       } else {
         if (node.nodeType === 1) {
-          retVal = virtualDOMfromNode(node, shadowId);
+          retVal = new VirtualNode(node, parent, shadowId);
           realArray = Array.from(node.childNodes);
-          retVal.children = realArray.reduce(reduceShadowDOM, []);
+          retVal.children = realArray.reduce(function(res, child) {
+            return reduceShadowDOM(res, child, retVal);
+          }, []);
           return [ retVal ];
         } else if (node.nodeType === 3) {
-          return [ virtualDOMfromNode(node) ];
+          return [ new VirtualNode(node, parent) ];
         }
         return undefined;
       }
     }
+  }
+  axe.utils.getFlattenedTree = function(node, shadowId) {
+    axe._cache.set('nodeMap', new WeakMap());
+    return flattenTree(node, shadowId);
   };
   axe.utils.getNodeFromTree = function(vNode, node) {
-    var found;
-    if (vNode.actualNode === node) {
-      return vNode;
-    }
-    vNode.children.forEach(function(candidate) {
-      var retVal;
-      if (candidate.actualNode === node) {
-        found = candidate;
-      } else {
-        retVal = axe.utils.getNodeFromTree(candidate, node);
-        if (retVal) {
-          found = retVal;
-        }
-      }
-    });
-    return found;
+    var el = node || vNode;
+    return axe._cache.get('nodeMap') ? axe._cache.get('nodeMap').get(el) : null;
   };
   'use strict';
   axe.utils.getAllChecks = function getAllChecks(object) {
@@ -2438,6 +5111,13 @@
     return result.concat(object.any || []).concat(object.all || []).concat(object.none || []);
   };
   'use strict';
+  axe.utils.getBaseLang = function getBaseLang(lang) {
+    if (!lang) {
+      return '';
+    }
+    return lang.trim().split('-')[0].toLowerCase();
+  };
+  'use strict';
   axe.utils.getCheckOption = function(check, ruleID, options) {
     var ruleCheckOption = ((options.rules && options.rules[ruleID] || {}).checks || {})[check.id];
     var checkOption = (options.checks || {})[check.id];
@@ -2466,45 +5146,45 @@
     };
   };
   'use strict';
-  var _slicedToArray = function() {
-    function sliceIterator(arr, i) {
-      var _arr = [];
-      var _n = true;
-      var _d = false;
-      var _e = undefined;
+  function _slicedToArray(arr, i) {
+    return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest();
+  }
+  function _nonIterableRest() {
+    throw new TypeError('Invalid attempt to destructure non-iterable instance');
+  }
+  function _iterableToArrayLimit(arr, i) {
+    var _arr = [];
+    var _n = true;
+    var _d = false;
+    var _e = undefined;
+    try {
+      for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
+        _arr.push(_s.value);
+        if (i && _arr.length === i) {
+          break;
+        }
+      }
+    } catch (err) {
+      _d = true;
+      _e = err;
+    } finally {
       try {
-        for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
-          _arr.push(_s.value);
-          if (i && _arr.length === i) {
-            break;
-          }
+        if (!_n && _i['return'] != null) {
+          _i['return']();
         }
-      } catch (err) {
-        _d = true;
-        _e = err;
       } finally {
-        try {
-          if (!_n && _i['return']) {
-            _i['return']();
-          }
-        } finally {
-          if (_d) {
-            throw _e;
-          }
+        if (_d) {
+          throw _e;
         }
       }
-      return _arr;
     }
-    return function(arr, i) {
-      if (Array.isArray(arr)) {
-        return arr;
-      } else if (Symbol.iterator in Object(arr)) {
-        return sliceIterator(arr, i);
-      } else {
-        throw new TypeError('Invalid attempt to destructure non-iterable instance');
-      }
-    };
-  }();
+    return _arr;
+  }
+  function _arrayWithHoles(arr) {
+    if (Array.isArray(arr)) {
+      return arr;
+    }
+  }
   function isMostlyNumbers() {
     var str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
     return str.length !== 0 && (str.match(/[0-9]/g) || '').length >= str.length / 2;
@@ -2512,6 +5192,9 @@
   function splitString(str, splitIndex) {
     return [ str.substring(0, splitIndex), str.substring(splitIndex) ];
   }
+  function trimRight(str) {
+    return str.replace(/\s+$/, '');
+  }
   function uriParser(url) {
     var original = url;
     var protocol = '', domain = '', port = '', path = '', query = '', hash = '';
@@ -2569,61 +5252,168 @@
     if (uri.length <= 1 || uri.substr(0, 5) === 'data:' || uri.substr(0, 11) === 'javascript:' || uri.includes('?')) {
       return;
     }
-    var currentDomain = options.currentDomain, _options$maxLength = options.maxLength, maxLength = _options$maxLength === undefined ? 25 : _options$maxLength;
+    var currentDomain = options.currentDomain, _options$maxLength = options.maxLength, maxLength = _options$maxLength === void 0 ? 25 : _options$maxLength;
     var _uriParser = uriParser(uri), path = _uriParser.path, domain = _uriParser.domain, hash = _uriParser.hash;
     var pathEnd = path.substr(path.substr(0, path.length - 2).lastIndexOf('/') + 1);
     if (hash) {
       if (pathEnd && (pathEnd + hash).length <= maxLength) {
-        return pathEnd + hash;
+        return trimRight(pathEnd + hash);
       } else if (pathEnd.length < 2 && hash.length > 2 && hash.length <= maxLength) {
-        return hash;
+        return trimRight(hash);
       } else {
         return;
       }
     } else if (domain && domain.length < maxLength && path.length <= 1) {
-      return domain + path;
+      return trimRight(domain + path);
     }
     if (path === '/' + pathEnd && domain && currentDomain && domain !== currentDomain && (domain + path).length <= maxLength) {
-      return domain + path;
+      return trimRight(domain + path);
     }
     var lastDotIndex = pathEnd.lastIndexOf('.');
     if ((lastDotIndex === -1 || lastDotIndex > 1) && (lastDotIndex !== -1 || pathEnd.length > 2) && pathEnd.length <= maxLength && !pathEnd.match(/index(\.[a-zA-Z]{2-4})?/) && !isMostlyNumbers(pathEnd)) {
-      return pathEnd;
+      return trimRight(pathEnd);
     }
   };
   'use strict';
-  function _toConsumableArray(arr) {
-    if (Array.isArray(arr)) {
-      for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
-        arr2[i] = arr[i];
-      }
-      return arr2;
-    } else {
-      return Array.from(arr);
+  axe.utils.getNodeAttributes = function getNodeAttributes(node) {
+    if (node.attributes instanceof window.NamedNodeMap) {
+      return node.attributes;
     }
-  }
+    return node.cloneNode(false).attributes;
+  };
+  'use strict';
+  axe.utils.getRootNode = function getRootNode(node) {
+    var doc = node.getRootNode && node.getRootNode() || document;
+    if (doc === node) {
+      doc = document;
+    }
+    return doc;
+  };
+  'use strict';
+  axe.utils.getScroll = function getScroll(elm) {
+    var buffer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
+    var overflowX = elm.scrollWidth > elm.clientWidth + buffer;
+    var overflowY = elm.scrollHeight > elm.clientHeight + buffer;
+    if (!(overflowX || overflowY)) {
+      return;
+    }
+    var style = window.getComputedStyle(elm);
+    var overflowXStyle = style.getPropertyValue('overflow-x');
+    var overflowYStyle = style.getPropertyValue('overflow-y');
+    var scrollableX = overflowXStyle !== 'visible' && overflowXStyle !== 'hidden';
+    var scrollableY = overflowYStyle !== 'visible' && overflowYStyle !== 'hidden';
+    if (overflowX && scrollableX || overflowY && scrollableY) {
+      return {
+        elm: elm,
+        top: elm.scrollTop,
+        left: elm.scrollLeft
+      };
+    }
+  };
+  'use strict';
   var escapeSelector = axe.utils.escapeSelector;
-  function isUncommonClassName(className) {
-    return ![ 'focus', 'hover', 'hidden', 'visible', 'dirty', 'touched', 'valid', 'disable', 'enable', 'active', 'col-' ].find(function(str) {
-      return className.includes(str);
-    });
-  }
-  function getDistinctClassList(elm) {
-    if (!elm.classList || elm.classList.length === 0) {
-      return [];
-    }
-    var siblings = elm.parentNode && Array.from(elm.parentNode.children || '') || [];
-    return siblings.reduce(function(classList, childElm) {
-      if (elm === childElm) {
-        return classList;
+  var isXHTML;
+  var ignoredAttributes = [ 'class', 'style', 'id', 'selected', 'checked', 'disabled', 'tabindex', 'aria-checked', 'aria-selected', 'aria-invalid', 'aria-activedescendant', 'aria-busy', 'aria-disabled', 'aria-expanded', 'aria-grabbed', 'aria-pressed', 'aria-valuenow' ];
+  var MAXATTRIBUTELENGTH = 31;
+  function getAttributeNameValue(node, at) {
+    var name = at.name;
+    var atnv;
+    if (name.indexOf('href') !== -1 || name.indexOf('src') !== -1) {
+      var friendly = axe.utils.getFriendlyUriEnd(node.getAttribute(name));
+      if (friendly) {
+        var value = encodeURI(friendly);
+        if (value) {
+          atnv = escapeSelector(at.name) + '$="' + escapeSelector(value) + '"';
+        } else {
+          return;
+        }
       } else {
-        return classList.filter(function(classItem) {
-          return !childElm.classList.contains(classItem);
-        });
+        atnv = escapeSelector(at.name) + '="' + escapeSelector(node.getAttribute(name)) + '"';
       }
-    }, Array.from(elm.classList).filter(isUncommonClassName));
+    } else {
+      atnv = escapeSelector(name) + '="' + escapeSelector(at.value) + '"';
+    }
+    return atnv;
   }
-  var commonNodes = [ 'div', 'span', 'p', 'b', 'i', 'u', 'strong', 'em', 'h2', 'h3' ];
+  function countSort(a, b) {
+    return a.count < b.count ? -1 : a.count === b.count ? 0 : 1;
+  }
+  function filterAttributes(at) {
+    return !ignoredAttributes.includes(at.name) && at.name.indexOf(':') === -1 && (!at.value || at.value.length < MAXATTRIBUTELENGTH);
+  }
+  axe.utils.getSelectorData = function(domTree) {
+    var data = {
+      classes: {},
+      tags: {},
+      attributes: {}
+    };
+    domTree = Array.isArray(domTree) ? domTree : [ domTree ];
+    var currentLevel = domTree.slice();
+    var stack = [];
+    var _loop = function _loop() {
+      var current = currentLevel.pop();
+      var node = current.actualNode;
+      if (!!node.querySelectorAll) {
+        var tag = node.nodeName;
+        if (data.tags[tag]) {
+          data.tags[tag]++;
+        } else {
+          data.tags[tag] = 1;
+        }
+        if (node.classList) {
+          Array.from(node.classList).forEach(function(cl) {
+            var ind = escapeSelector(cl);
+            if (data.classes[ind]) {
+              data.classes[ind]++;
+            } else {
+              data.classes[ind] = 1;
+            }
+          });
+        }
+        if (node.hasAttributes()) {
+          Array.from(axe.utils.getNodeAttributes(node)).filter(filterAttributes).forEach(function(at) {
+            var atnv = getAttributeNameValue(node, at);
+            if (atnv) {
+              if (data.attributes[atnv]) {
+                data.attributes[atnv]++;
+              } else {
+                data.attributes[atnv] = 1;
+              }
+            }
+          });
+        }
+      }
+      if (current.children.length) {
+        stack.push(currentLevel);
+        currentLevel = current.children.slice();
+      }
+      while (!currentLevel.length && stack.length) {
+        currentLevel = stack.pop();
+      }
+    };
+    while (currentLevel.length) {
+      _loop();
+    }
+    return data;
+  };
+  function uncommonClasses(node, selectorData) {
+    var retVal = [];
+    var classData = selectorData.classes;
+    var tagData = selectorData.tags;
+    if (node.classList) {
+      Array.from(node.classList).forEach(function(cl) {
+        var ind = escapeSelector(cl);
+        if (classData[ind] < tagData[node.nodeName]) {
+          retVal.push({
+            name: ind,
+            count: classData[ind],
+            species: 'class'
+          });
+        }
+      });
+    }
+    return retVal.sort(countSort);
+  }
   function getNthChildString(elm, selector) {
     var siblings = elm.parentNode && Array.from(elm.parentNode.children || '') || [];
     var hasMatchingSiblings = siblings.find(function(sibling) {
@@ -2636,124 +5426,108 @@
       return '';
     }
   }
-  var createSelector = {
-    getElmId: function getElmId(elm) {
-      if (!elm.getAttribute('id')) {
-        return;
-      }
-      var doc = elm.getRootNode && elm.getRootNode() || document;
-      var id = '#' + escapeSelector(elm.getAttribute('id') || '');
-      if (!id.match(/player_uid_/) && doc.querySelectorAll(id).length === 1) {
-        return id;
-      }
-    },
-    getCustomElm: function getCustomElm(elm, _ref) {
-      var isCustomElm = _ref.isCustomElm, nodeName = _ref.nodeName;
-      if (isCustomElm) {
-        return nodeName;
-      }
-    },
-    getElmRoleProp: function getElmRoleProp(elm) {
-      if (elm.hasAttribute('role')) {
-        return '[role="' + escapeSelector(elm.getAttribute('role')) + '"]';
-      }
-    },
-    getUncommonElm: function getUncommonElm(elm, _ref2) {
-      var isCommonElm = _ref2.isCommonElm, isCustomElm = _ref2.isCustomElm, nodeName = _ref2.nodeName;
-      if (!isCommonElm && !isCustomElm) {
-        nodeName = escapeSelector(nodeName);
-        if (nodeName === 'input' && elm.hasAttribute('type')) {
-          nodeName += '[type="' + elm.type + '"]';
+  function getElmId(elm) {
+    if (!elm.getAttribute('id')) {
+      return;
+    }
+    var doc = elm.getRootNode && elm.getRootNode() || document;
+    var id = '#' + escapeSelector(elm.getAttribute('id') || '');
+    if (!id.match(/player_uid_/) && doc.querySelectorAll(id).length === 1) {
+      return id;
+    }
+  }
+  function getBaseSelector(elm) {
+    if (typeof isXHTML === 'undefined') {
+      isXHTML = axe.utils.isXHTML(document);
+    }
+    return escapeSelector(isXHTML ? elm.localName : elm.nodeName.toLowerCase());
+  }
+  function uncommonAttributes(node, selectorData) {
+    var retVal = [];
+    var attData = selectorData.attributes;
+    var tagData = selectorData.tags;
+    if (node.hasAttributes()) {
+      Array.from(axe.utils.getNodeAttributes(node)).filter(filterAttributes).forEach(function(at) {
+        var atnv = getAttributeNameValue(node, at);
+        if (atnv && attData[atnv] < tagData[node.nodeName]) {
+          retVal.push({
+            name: atnv,
+            count: attData[atnv],
+            species: 'attribute'
+          });
         }
-        return nodeName;
-      }
-    },
-    getElmNameProp: function getElmNameProp(elm) {
-      if (!elm.hasAttribute('id') && elm.name) {
-        return '[name="' + escapeSelector(elm.name) + '"]';
-      }
-    },
-    getDistinctClass: function getDistinctClass(elm, _ref3) {
-      var distinctClassList = _ref3.distinctClassList;
-      if (distinctClassList.length > 0 && distinctClassList.length < 3) {
-        return '.' + distinctClassList.map(escapeSelector).join('.');
-      }
-    },
-    getFileRefProp: function getFileRefProp(elm) {
-      var attr = void 0;
-      if (elm.hasAttribute('href')) {
-        attr = 'href';
-      } else if (elm.hasAttribute('src')) {
-        attr = 'src';
+      });
+    }
+    return retVal.sort(countSort);
+  }
+  function getThreeLeastCommonFeatures(elm, selectorData) {
+    var selector = '';
+    var features;
+    var clss = uncommonClasses(elm, selectorData);
+    var atts = uncommonAttributes(elm, selectorData);
+    if (clss.length && clss[0].count === 1) {
+      features = [ clss[0] ];
+    } else if (atts.length && atts[0].count === 1) {
+      features = [ atts[0] ];
+      selector = getBaseSelector(elm);
+    } else {
+      features = clss.concat(atts);
+      features.sort(countSort);
+      features = features.slice(0, 3);
+      if (!features.some(function(feat) {
+        return feat.species === 'class';
+      })) {
+        selector = getBaseSelector(elm);
       } else {
-        return;
-      }
-      var friendlyUriEnd = axe.utils.getFriendlyUriEnd(elm.getAttribute(attr));
-      if (friendlyUriEnd) {
-        return '[' + attr + '$="' + encodeURI(friendlyUriEnd) + '"]';
-      }
-    },
-    getCommonName: function getCommonName(elm, _ref4) {
-      var nodeName = _ref4.nodeName, isCommonElm = _ref4.isCommonElm;
-      if (isCommonElm) {
-        return nodeName;
+        features.sort(function(a, b) {
+          return a.species !== b.species && a.species === 'class' ? -1 : a.species === b.species ? 0 : 1;
+        });
       }
     }
-  };
-  function getElmFeatures(elm, featureCount) {
-    var nodeName = elm.nodeName.toLowerCase();
-    var classList = Array.from(elm.classList) || [];
-    var props = {
-      nodeName: nodeName,
-      classList: classList,
-      isCustomElm: nodeName.includes('-'),
-      isCommonElm: commonNodes.includes(nodeName),
-      distinctClassList: getDistinctClassList(elm)
-    };
-    return [ createSelector.getCustomElm, createSelector.getElmRoleProp, createSelector.getUncommonElm, createSelector.getElmNameProp, createSelector.getDistinctClass, createSelector.getFileRefProp, createSelector.getCommonName ].reduce(function(features, func) {
-      if (features.length === featureCount) {
-        return features;
+    return selector += features.reduce(function(val, feat) {
+      switch (feat.species) {
+       case 'class':
+        return val + '.' + feat.name;
+
+       case 'attribute':
+        return val + '[' + feat.name + ']';
       }
-      var feature = func(elm, props);
-      if (feature) {
-        if (!feature[0].match(/[a-z]/)) {
-          features.push(feature);
-        } else {
-          features.unshift(feature);
-        }
-      }
-      return features;
-    }, []);
+      return val;
+    }, '');
   }
   function generateSelector(elm, options, doc) {
-    var selector = void 0, addParent = void 0;
-    var _options$isUnique = options.isUnique, isUnique = _options$isUnique === undefined ? false : _options$isUnique;
-    var idSelector = createSelector.getElmId(elm);
-    var _options$featureCount = options.featureCount, featureCount = _options$featureCount === undefined ? 2 : _options$featureCount, _options$minDepth = options.minDepth, minDepth = _options$minDepth === undefined ? 1 : _options$minDepth, _options$toRoot = options.toRoot, toRoot = _options$toRoot === undefined ? false : _options$toRoot, _options$childSelecto = options.childSelectors, childSelectors = _options$childSelecto === undefined ? [] : _options$childSelecto;
-    if (idSelector) {
-      selector = idSelector;
-      isUnique = true;
-    } else {
-      selector = getElmFeatures(elm, featureCount).join('');
-      selector += getNthChildString(elm, selector);
-      isUnique = options.isUnique || doc.querySelectorAll(selector).length === 1;
-      if (!isUnique && elm === document.documentElement) {
-        selector += ':root';
+    if (!axe._selectorData) {
+      throw new Error('Expect axe._selectorData to be set up');
+    }
+    var _options$toRoot = options.toRoot, toRoot = _options$toRoot === void 0 ? false : _options$toRoot;
+    var selector;
+    var similar;
+    do {
+      var features = getElmId(elm);
+      if (!features) {
+        features = getThreeLeastCommonFeatures(elm, axe._selectorData);
+        features += getNthChildString(elm, features);
       }
-      addParent = minDepth !== 0 || !isUnique;
+      if (selector) {
+        selector = features + ' > ' + selector;
+      } else {
+        selector = features;
+      }
+      if (!similar) {
+        similar = Array.from(doc.querySelectorAll(selector));
+      } else {
+        similar = similar.filter(function(item) {
+          return axe.utils.matchesSelector(item, selector);
+        });
+      }
+      elm = elm.parentElement;
+    } while ((similar.length > 1 || toRoot) && elm && elm.nodeType !== 11);
+    if (similar.length === 1) {
+      return selector;
+    } else if (selector.indexOf(' > ') !== -1) {
+      return ':root' + selector.substring(selector.indexOf(' > '));
     }
-    var selectorParts = [ selector ].concat(_toConsumableArray(childSelectors));
-    if (elm.parentElement && elm.parentElement.nodeType !== 11 && (toRoot || addParent)) {
-      return generateSelector(elm.parentNode, {
-        toRoot: toRoot,
-        isUnique: isUnique,
-        childSelectors: selectorParts,
-        featureCount: 1,
-        minDepth: minDepth - 1
-      }, doc);
-    } else {
-      return selectorParts.join(' > ');
-    }
+    return ':root';
   }
   axe.utils.getSelector = function createUniqueSelector(elm) {
     var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
@@ -2783,6 +5557,30 @@
     }
   };
   'use strict';
+  axe.utils.getStyleSheetFactory = function getStyleSheetFactory(dynamicDoc) {
+    if (!dynamicDoc) {
+      throw new Error('axe.utils.getStyleSheetFactory should be invoked with an argument');
+    }
+    return function(options) {
+      var data = options.data, _options$isCrossOrigi = options.isCrossOrigin, isCrossOrigin = _options$isCrossOrigi === void 0 ? false : _options$isCrossOrigi, shadowId = options.shadowId, root = options.root, priority = options.priority, _options$isLink = options.isLink, isLink = _options$isLink === void 0 ? false : _options$isLink;
+      var style = dynamicDoc.createElement('style');
+      if (isLink) {
+        var text = dynamicDoc.createTextNode('@import "'.concat(data.href, '"'));
+        style.appendChild(text);
+      } else {
+        style.appendChild(dynamicDoc.createTextNode(data));
+      }
+      dynamicDoc.head.appendChild(style);
+      return {
+        sheet: style.sheet,
+        isCrossOrigin: isCrossOrigin,
+        shadowId: shadowId,
+        root: root,
+        priority: priority
+      };
+    };
+  };
+  'use strict';
   function getXPathArray(node, path) {
     var sibling, count;
     if (!node) {
@@ -2839,9 +5637,9 @@
   function xpathToString(xpathArray) {
     return xpathArray.reduce(function(str, elm) {
       if (elm.id) {
-        return '/' + elm.str + '[@id=\'' + elm.id + '\']';
+        return '/'.concat(elm.str, '[@id=\'').concat(elm.id, '\']');
       } else {
-        return str + ('/' + elm.str) + (elm.count > 0 ? '[' + elm.count + ']' : '');
+        return str + '/'.concat(elm.str) + (elm.count > 0 ? '['.concat(elm.count, ']') : '');
       }
     }, '');
   }
@@ -2879,19 +5677,51 @@
   'use strict';
   axe.utils.isHidden = function isHidden(el, recursed) {
     'use strict';
-    var parent;
+    var node = axe.utils.getNodeFromTree(el);
     if (el.nodeType === 9) {
       return false;
     }
     if (el.nodeType === 11) {
       el = el.host;
     }
+    if (node && node._isHidden !== null) {
+      return node._isHidden;
+    }
     var style = window.getComputedStyle(el, null);
     if (!style || !el.parentNode || style.getPropertyValue('display') === 'none' || !recursed && style.getPropertyValue('visibility') === 'hidden' || el.getAttribute('aria-hidden') === 'true') {
       return true;
     }
-    parent = el.assignedSlot ? el.assignedSlot : el.parentNode;
-    return axe.utils.isHidden(parent, true);
+    var parent = el.assignedSlot ? el.assignedSlot : el.parentNode;
+    var isHidden = axe.utils.isHidden(parent, true);
+    if (node) {
+      node._isHidden = isHidden;
+    }
+    return isHidden;
+  };
+  'use strict';
+  var htmlTags = [ 'a', 'abbr', 'address', 'area', 'article', 'aside', 'audio', 'b', 'base', 'bdi', 'bdo', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'cite', 'code', 'col', 'colgroup', 'data', 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'div', 'dl', 'dt', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'keygen', 'label', 'legend', 'li', 'link', 'main', 'map', 'mark', 'math', 'menu', 'menuitem', 'meta', 'meter', 'nav', 'noscript', 'object', 'ol', 'optgroup', 'option', 'output', 'p', 'param', 'picture', 'pre', 'progress', 'q', 'rb', 'rp', 'rt', 'rtc', 'ruby', 's', 'samp', 'script', 'section', 'select', 'slot', 'small', 'source', 'span', 'strong', 'style', 'sub', 'summary', 'sup', 'svg', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'track', 'u', 'ul', 'var', 'video', 'wbr' ];
+  axe.utils.isHtmlElement = function isHtmlElement(node) {
+    var tagName = node.nodeName.toLowerCase();
+    return htmlTags.includes(tagName) && node.namespaceURI !== 'http://www.w3.org/2000/svg';
+  };
+  'use strict';
+  var possibleShadowRoots = [ 'article', 'aside', 'blockquote', 'body', 'div', 'footer', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'main', 'nav', 'p', 'section', 'span' ];
+  axe.utils.isShadowRoot = function isShadowRoot(node) {
+    var nodeName = node.nodeName.toLowerCase();
+    if (node.shadowRoot) {
+      if (/^[a-z][a-z0-9_.-]*-[a-z0-9_.-]*$/.test(nodeName) || possibleShadowRoots.includes(nodeName)) {
+        return true;
+      }
+    }
+    return false;
+  };
+  'use strict';
+  axe.utils.isXHTML = function(doc) {
+    'use strict';
+    if (!doc.createElement) {
+      return false;
+    }
+    return doc.createElement('A').localName === 'A';
   };
   'use strict';
   function pushFrame(resultSet, options, frameElement, frameSelector) {
@@ -2969,17 +5799,125 @@
     return result;
   };
   'use strict';
-  axe.utils.nodeSorter = function nodeSorter(a, b) {
-    'use strict';
-    if (a.actualNode === b.actualNode) {
+  axe.utils.nodeSorter = function nodeSorter(nodeA, nodeB) {
+    nodeA = nodeA.actualNode || nodeA;
+    nodeB = nodeB.actualNode || nodeB;
+    if (nodeA === nodeB) {
       return 0;
     }
-    if (a.actualNode.compareDocumentPosition(b.actualNode) & 4) {
+    if (nodeA.compareDocumentPosition(nodeB) & 4) {
       return -1;
+    } else {
+      return 1;
     }
-    return 1;
   };
   'use strict';
+  axe.utils.parseCrossOriginStylesheet = function parseCrossOriginStylesheet(url, options, priority, importedUrls, isCrossOrigin) {
+    var axiosOptions = {
+      method: 'get',
+      url: url
+    };
+    importedUrls.push(url);
+    return axe.imports.axios(axiosOptions).then(function(_ref) {
+      var data = _ref.data;
+      var result = options.convertDataToStylesheet({
+        data: data,
+        isCrossOrigin: isCrossOrigin,
+        priority: priority,
+        root: options.rootNode,
+        shadowId: options.shadowId
+      });
+      return axe.utils.parseStylesheet(result.sheet, options, priority, importedUrls, result.isCrossOrigin);
+    });
+  };
+  'use strict';
+  function _toConsumableArray(arr) {
+    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
+  }
+  function _nonIterableSpread() {
+    throw new TypeError('Invalid attempt to spread non-iterable instance');
+  }
+  function _iterableToArray(iter) {
+    if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === '[object Arguments]') {
+      return Array.from(iter);
+    }
+  }
+  function _arrayWithoutHoles(arr) {
+    if (Array.isArray(arr)) {
+      for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
+        arr2[i] = arr[i];
+      }
+      return arr2;
+    }
+  }
+  axe.utils.parseSameOriginStylesheet = function parseSameOriginStylesheet(sheet, options, priority, importedUrls) {
+    var isCrossOrigin = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
+    var rules = Array.from(sheet.cssRules);
+    if (!rules) {
+      return Promise.resolve();
+    }
+    var cssImportRules = rules.filter(function(r) {
+      return r.type === 3;
+    });
+    if (!cssImportRules.length) {
+      return Promise.resolve({
+        isCrossOrigin: isCrossOrigin,
+        priority: priority,
+        root: options.rootNode,
+        shadowId: options.shadowId,
+        sheet: sheet
+      });
+    }
+    var cssImportUrlsNotAlreadyImported = cssImportRules.filter(function(rule) {
+      return rule.href;
+    }).map(function(rule) {
+      return rule.href;
+    }).filter(function(url) {
+      return !importedUrls.includes(url);
+    });
+    var promises = cssImportUrlsNotAlreadyImported.map(function(importUrl, cssRuleIndex) {
+      var newPriority = [].concat(_toConsumableArray(priority), [ cssRuleIndex ]);
+      var isCrossOriginRequest = /^https?:\/\/|^\/\//i.test(importUrl);
+      return axe.utils.parseCrossOriginStylesheet(importUrl, options, newPriority, importedUrls, isCrossOriginRequest);
+    });
+    var nonImportCSSRules = rules.filter(function(r) {
+      return r.type !== 3;
+    });
+    if (!nonImportCSSRules.length) {
+      return Promise.all(promises);
+    }
+    promises.push(Promise.resolve(options.convertDataToStylesheet({
+      data: nonImportCSSRules.map(function(rule) {
+        return rule.cssText;
+      }).join(),
+      isCrossOrigin: isCrossOrigin,
+      priority: priority,
+      root: options.rootNode,
+      shadowId: options.shadowId
+    })));
+    return Promise.all(promises);
+  };
+  'use strict';
+  axe.utils.parseStylesheet = function parseStylesheet(sheet, options, priority, importedUrls) {
+    var isCrossOrigin = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
+    var isSameOrigin = isSameOriginStylesheet(sheet);
+    if (isSameOrigin) {
+      return axe.utils.parseSameOriginStylesheet(sheet, options, priority, importedUrls, isCrossOrigin);
+    }
+    return axe.utils.parseCrossOriginStylesheet(sheet.href, options, priority, importedUrls, true);
+  };
+  function isSameOriginStylesheet(sheet) {
+    try {
+      var rules = sheet.cssRules;
+      if (!rules && sheet.href) {
+        return false;
+      }
+      return true;
+    } catch (e) {
+      return false;
+    }
+  }
+  'use strict';
   utils.performanceTimer = function() {
     'use strict';
     function now() {
@@ -3021,7 +5959,10 @@
           axe.log('Measure ' + req.name + ' took ' + req.duration + 'ms');
         }
         if (window.performance && window.performance.getEntriesByType !== undefined) {
-          var measures = window.performance.getEntriesByType('measure');
+          var axeStart = window.performance.getEntriesByName('mark_axe_start')[0];
+          var measures = window.performance.getEntriesByType('measure').filter(function(measure) {
+            return measure.startTime >= axeStart.startTime;
+          });
           for (var i = 0; i < measures.length; ++i) {
             var req = measures[i];
             if (req.name === measureName) {
@@ -3067,25 +6008,27 @@
     })();
   }
   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;
+    Object.defineProperty(Array.prototype, 'find', {
+      value: function value(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;
       }
-      return undefined;
-    };
+    });
   }
   axe.utils.pollyfillElementsFromPoint = function() {
     if (document.elementsFromPoint) {
@@ -3116,6 +6059,10 @@
         });
         current.style.setProperty(cssProp, cssDisableVal, 'important');
       }
+      if (elements.indexOf(document.documentElement) < elements.length - 1) {
+        elements.splice(elements.indexOf(document.documentElement), 1);
+        elements.push(document.documentElement);
+      }
       for (i = previousPointerEvents.length; !!(d = previousPointerEvents[--i]); ) {
         elements[i].style.setProperty(cssProp, d.value ? d.value : '', d.priority);
       }
@@ -3127,108 +6074,114 @@
     document.elementsFromPoint = axe.utils.pollyfillElementsFromPoint();
   }
   if (!Array.prototype.includes) {
-    Array.prototype.includes = function(searchElement) {
-      'use strict';
-      var O = Object(this);
-      var len = parseInt(O.length, 10) || 0;
-      if (len === 0) {
+    Object.defineProperty(Array.prototype, 'includes', {
+      value: function value(searchElement) {
+        'use strict';
+        var O = Object(this);
+        var len = parseInt(O.length, 10) || 0;
+        if (len === 0) {
+          return false;
+        }
+        var n = parseInt(arguments[1], 10) || 0;
+        var k;
+        if (n >= 0) {
+          k = n;
+        } else {
+          k = len + n;
+          if (k < 0) {
+            k = 0;
+          }
+        }
+        var currentElement;
+        while (k < len) {
+          currentElement = O[k];
+          if (searchElement === currentElement || searchElement !== searchElement && currentElement !== currentElement) {
+            return true;
+          }
+          k++;
+        }
         return false;
       }
-      var n = parseInt(arguments[1], 10) || 0;
-      var k;
-      if (n >= 0) {
-        k = n;
-      } else {
-        k = len + n;
-        if (k < 0) {
-          k = 0;
-        }
-      }
-      var currentElement;
-      while (k < len) {
-        currentElement = O[k];
-        if (searchElement === currentElement || searchElement !== searchElement && currentElement !== currentElement) {
-          return true;
-        }
-        k++;
-      }
-      return false;
-    };
+    });
   }
   if (!Array.prototype.some) {
-    Array.prototype.some = function(fun) {
-      'use strict';
-      if (this == null) {
-        throw new TypeError('Array.prototype.some called on null or undefined');
-      }
-      if (typeof fun !== 'function') {
-        throw new TypeError();
-      }
-      var t = Object(this);
-      var len = t.length >>> 0;
-      var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
-      for (var i = 0; i < len; i++) {
-        if (i in t && fun.call(thisArg, t[i], i, t)) {
-          return true;
+    Object.defineProperty(Array.prototype, 'some', {
+      value: function value(fun) {
+        'use strict';
+        if (this == null) {
+          throw new TypeError('Array.prototype.some called on null or undefined');
         }
+        if (typeof fun !== 'function') {
+          throw new TypeError();
+        }
+        var t = Object(this);
+        var len = t.length >>> 0;
+        var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
+        for (var i = 0; i < len; i++) {
+          if (i in t && fun.call(thisArg, t[i], i, t)) {
+            return true;
+          }
+        }
+        return false;
       }
-      return false;
-    };
+    });
   }
   if (!Array.from) {
-    Array.from = function() {
-      var toStr = Object.prototype.toString;
-      var isCallable = function isCallable(fn) {
-        return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
-      };
-      var toInteger = function toInteger(value) {
-        var number = Number(value);
-        if (isNaN(number)) {
-          return 0;
-        }
-        if (number === 0 || !isFinite(number)) {
-          return number;
-        }
-        return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
-      };
-      var maxSafeInteger = Math.pow(2, 53) - 1;
-      var toLength = function toLength(value) {
-        var len = toInteger(value);
-        return Math.min(Math.max(len, 0), maxSafeInteger);
-      };
-      return function from(arrayLike) {
-        var C = this;
-        var items = Object(arrayLike);
-        if (arrayLike == null) {
-          throw new TypeError('Array.from requires an array-like object - not null or undefined');
-        }
-        var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
-        var T;
-        if (typeof mapFn !== 'undefined') {
-          if (!isCallable(mapFn)) {
-            throw new TypeError('Array.from: when provided, the second argument must be a function');
+    Object.defineProperty(Array, 'from', {
+      value: function() {
+        var toStr = Object.prototype.toString;
+        var isCallable = function isCallable(fn) {
+          return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
+        };
+        var toInteger = function toInteger(value) {
+          var number = Number(value);
+          if (isNaN(number)) {
+            return 0;
           }
-          if (arguments.length > 2) {
-            T = arguments[2];
+          if (number === 0 || !isFinite(number)) {
+            return number;
           }
-        }
-        var len = toLength(items.length);
-        var A = isCallable(C) ? Object(new C(len)) : new Array(len);
-        var k = 0;
-        var kValue;
-        while (k < len) {
-          kValue = items[k];
-          if (mapFn) {
-            A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
-          } else {
-            A[k] = kValue;
+          return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
+        };
+        var maxSafeInteger = Math.pow(2, 53) - 1;
+        var toLength = function toLength(value) {
+          var len = toInteger(value);
+          return Math.min(Math.max(len, 0), maxSafeInteger);
+        };
+        return function from(arrayLike) {
+          var C = this;
+          var items = Object(arrayLike);
+          if (arrayLike == null) {
+            throw new TypeError('Array.from requires an array-like object - not null or undefined');
           }
-          k += 1;
-        }
-        A.length = len;
-        return A;
-      };
-    }();
+          var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
+          var T;
+          if (typeof mapFn !== 'undefined') {
+            if (!isCallable(mapFn)) {
+              throw new TypeError('Array.from: when provided, the second argument must be a function');
+            }
+            if (arguments.length > 2) {
+              T = arguments[2];
+            }
+          }
+          var len = toLength(items.length);
+          var A = isCallable(C) ? Object(new C(len)) : new Array(len);
+          var k = 0;
+          var kValue;
+          while (k < len) {
+            kValue = items[k];
+            if (mapFn) {
+              A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
+            } else {
+              A[k] = kValue;
+            }
+            k += 1;
+          }
+          A.length = len;
+          return A;
+        };
+      }()
+    });
   }
   if (!String.prototype.includes) {
     String.prototype.includes = function(search, start) {
@@ -3243,15 +6196,238 @@
     };
   }
   'use strict';
-  var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-    return typeof obj;
-  } : function(obj) {
-    return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+  axe.utils.preloadCssom = function preloadCssom(_ref) {
+    var _ref$treeRoot = _ref.treeRoot, treeRoot = _ref$treeRoot === void 0 ? axe._tree[0] : _ref$treeRoot;
+    var rootNodes = getAllRootNodesInTree(treeRoot);
+    if (!rootNodes.length) {
+      return Promise.resolve();
+    }
+    var dynamicDoc = document.implementation.createHTMLDocument('Dynamic document for loading cssom');
+    var convertDataToStylesheet = axe.utils.getStyleSheetFactory(dynamicDoc);
+    return getCssomForAllRootNodes(rootNodes, convertDataToStylesheet).then(function(assets) {
+      return flattenAssets(assets);
+    });
   };
+  function getAllRootNodesInTree(tree) {
+    var ids = [];
+    var rootNodes = axe.utils.querySelectorAllFilter(tree, '*', function(node) {
+      if (ids.includes(node.shadowId)) {
+        return false;
+      }
+      ids.push(node.shadowId);
+      return true;
+    }).map(function(node) {
+      return {
+        shadowId: node.shadowId,
+        rootNode: axe.utils.getRootNode(node.actualNode)
+      };
+    });
+    return axe.utils.uniqueArray(rootNodes, []);
+  }
+  function getCssomForAllRootNodes(rootNodes, convertDataToStylesheet) {
+    var promises = [];
+    rootNodes.forEach(function(_ref2, index) {
+      var rootNode = _ref2.rootNode, shadowId = _ref2.shadowId;
+      var sheets = getStylesheetsOfRootNode(rootNode, shadowId, convertDataToStylesheet);
+      if (!sheets) {
+        return Promise.all(promises);
+      }
+      var rootIndex = index + 1;
+      var parseOptions = {
+        rootNode: rootNode,
+        shadowId: shadowId,
+        convertDataToStylesheet: convertDataToStylesheet,
+        rootIndex: rootIndex
+      };
+      var importedUrls = [];
+      var p = Promise.all(sheets.map(function(sheet, sheetIndex) {
+        var priority = [ rootIndex, sheetIndex ];
+        return axe.utils.parseStylesheet(sheet, parseOptions, priority, importedUrls);
+      }));
+      promises.push(p);
+    });
+    return Promise.all(promises);
+  }
+  function flattenAssets(assets) {
+    return assets.reduce(function(acc, val) {
+      return Array.isArray(val) ? acc.concat(flattenAssets(val)) : acc.concat(val);
+    }, []);
+  }
+  function getStylesheetsOfRootNode(rootNode, shadowId, convertDataToStylesheet) {
+    var sheets;
+    if (rootNode.nodeType === 11 && shadowId) {
+      sheets = getStylesheetsFromDocumentFragment(rootNode, convertDataToStylesheet);
+    } else {
+      sheets = getStylesheetsFromDocument(rootNode);
+    }
+    return filterStylesheetsWithSameHref(sheets);
+  }
+  function getStylesheetsFromDocumentFragment(rootNode, convertDataToStylesheet) {
+    return Array.from(rootNode.children).filter(filerStyleAndLinkAttributesInDocumentFragment).reduce(function(out, node) {
+      var nodeName = node.nodeName.toUpperCase();
+      var data = nodeName === 'STYLE' ? node.textContent : node;
+      var isLink = nodeName === 'LINK';
+      var stylesheet = convertDataToStylesheet({
+        data: data,
+        isLink: isLink,
+        root: rootNode
+      });
+      out.push(stylesheet.sheet);
+      return out;
+    }, []);
+  }
+  function getStylesheetsFromDocument(rootNode) {
+    return Array.from(rootNode.styleSheets).filter(function(sheet) {
+      return filterMediaIsPrint(sheet.media.mediaText);
+    });
+  }
+  function filerStyleAndLinkAttributesInDocumentFragment(node) {
+    var nodeName = node.nodeName.toUpperCase();
+    var linkHref = node.getAttribute('href');
+    var linkRel = node.getAttribute('rel');
+    var isLink = nodeName === 'LINK' && linkHref && linkRel && node.rel.toUpperCase().includes('STYLESHEET');
+    var isStyle = nodeName === 'STYLE';
+    return isStyle || isLink && filterMediaIsPrint(node.media);
+  }
+  function filterMediaIsPrint(media) {
+    if (!media) {
+      return true;
+    }
+    return !media.toUpperCase().includes('PRINT');
+  }
+  function filterStylesheetsWithSameHref(sheets) {
+    var hrefs = [];
+    return sheets.filter(function(sheet) {
+      if (!sheet.href) {
+        return true;
+      }
+      if (hrefs.includes(sheet.href)) {
+        return false;
+      }
+      hrefs.push(sheet.href);
+      return true;
+    });
+  }
+  'use strict';
+  function _extends() {
+    _extends = Object.assign || function(target) {
+      for (var i = 1; i < arguments.length; i++) {
+        var source = arguments[i];
+        for (var key in source) {
+          if (Object.prototype.hasOwnProperty.call(source, key)) {
+            target[key] = source[key];
+          }
+        }
+      }
+      return target;
+    };
+    return _extends.apply(this, arguments);
+  }
+  function _defineProperty(obj, key, value) {
+    if (key in obj) {
+      Object.defineProperty(obj, key, {
+        value: value,
+        enumerable: true,
+        configurable: true,
+        writable: true
+      });
+    } else {
+      obj[key] = value;
+    }
+    return obj;
+  }
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
+  function isValidPreloadObject(preload) {
+    return _typeof(preload) === 'object' && Array.isArray(preload.assets);
+  }
+  axe.utils.shouldPreload = function shouldPreload(options) {
+    if (!options || options.preload === undefined || options.preload === null) {
+      return true;
+    }
+    if (typeof options.preload === 'boolean') {
+      return options.preload;
+    }
+    return isValidPreloadObject(options.preload);
+  };
+  axe.utils.getPreloadConfig = function getPreloadConfig(options) {
+    var _axe$constants$preloa = axe.constants.preload, assets = _axe$constants$preloa.assets, timeout = _axe$constants$preloa.timeout;
+    var config = {
+      assets: assets,
+      timeout: timeout
+    };
+    if (!options.preload) {
+      return config;
+    }
+    if (typeof options.preload === 'boolean') {
+      return config;
+    }
+    var areRequestedAssetsValid = options.preload.assets.every(function(a) {
+      return assets.includes(a.toLowerCase());
+    });
+    if (!areRequestedAssetsValid) {
+      throw new Error('Requested assets, not supported. ' + 'Supported assets are: '.concat(assets.join(', '), '.'));
+    }
+    config.assets = axe.utils.uniqueArray(options.preload.assets.map(function(a) {
+      return a.toLowerCase();
+    }), []);
+    if (options.preload.timeout && typeof options.preload.timeout === 'number' && !Number.isNaN(options.preload.timeout)) {
+      config.timeout = options.preload.timeout;
+    }
+    return config;
+  };
+  axe.utils.preload = function preload(options) {
+    var preloadFunctionsMap = {
+      cssom: axe.utils.preloadCssom
+    };
+    var shouldPreload = axe.utils.shouldPreload(options);
+    if (!shouldPreload) {
+      return Promise.resolve();
+    }
+    return new Promise(function(resolve, reject) {
+      var _axe$utils$getPreload = axe.utils.getPreloadConfig(options), assets = _axe$utils$getPreload.assets, timeout = _axe$utils$getPreload.timeout;
+      setTimeout(function() {
+        return reject('Preload assets timed out.');
+      }, timeout);
+      Promise.all(assets.map(function(asset) {
+        return preloadFunctionsMap[asset](options).then(function(results) {
+          return _defineProperty({}, asset, results);
+        });
+      })).then(function(results) {
+        var preloadAssets = results.reduce(function(out, result) {
+          return _extends({}, out, {}, result);
+        }, {});
+        resolve(preloadAssets);
+      });
+    });
+  };
+  'use strict';
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
   function getIncompleteReason(checkData, messages) {
     function getDefaultMsg(messages) {
-      if (messages.incomplete && messages.incomplete.default) {
-        return messages.incomplete.default;
+      if (messages.incomplete && messages.incomplete['default']) {
+        return messages.incomplete['default'];
       } else {
         return helpers.incompleteFallbackMessage();
       }
@@ -3313,22 +6489,22 @@
   'use strict';
   var convertExpressions = function convertExpressions() {};
   var matchExpressions = function matchExpressions() {};
-  function matchesTag(node, exp) {
-    return node.nodeType === 1 && (exp.tag === '*' || node.nodeName.toLowerCase() === exp.tag);
+  function matchesTag(vNode, exp) {
+    return vNode.props.nodeType === 1 && (exp.tag === '*' || vNode.props.nodeName === exp.tag);
   }
-  function matchesClasses(node, exp) {
-    return !exp.classes || exp.classes.reduce(function(result, cl) {
-      return result && node.className && node.className.match(cl.regexp);
-    }, true);
+  function matchesClasses(vNode, exp) {
+    return !exp.classes || exp.classes.every(function(cl) {
+      return vNode.hasClass(cl.value);
+    });
   }
-  function matchesAttributes(node, exp) {
+  function matchesAttributes(vNode, exp) {
     return !exp.attributes || exp.attributes.reduce(function(result, att) {
-      var nodeAtt = node.getAttribute(att.key);
+      var nodeAtt = vNode.attr(att.key);
       return result && nodeAtt !== null && (!att.value || att.test(nodeAtt));
     }, true);
   }
-  function matchesId(node, exp) {
-    return !exp.id || node.id === exp.id;
+  function matchesId(vNode, exp) {
+    return !exp.id || vNode.props.id === exp.id;
   }
   function matchesPseudos(target, exp) {
     if (!exp.pseudos || exp.pseudos.reduce(function(result, pseudo) {
@@ -3341,23 +6517,7 @@
     }
     return false;
   }
-  function matchSelector(targets, exp, recurse) {
-    var result = [];
-    targets = Array.isArray(targets) ? targets : [ targets ];
-    targets.forEach(function(target) {
-      if (matchesTag(target.actualNode, exp) && matchesClasses(target.actualNode, exp) && matchesAttributes(target.actualNode, exp) && matchesId(target.actualNode, exp) && matchesPseudos(target, exp)) {
-        result.push(target);
-      }
-      if (recurse) {
-        result = result.concat(matchSelector(target.children.filter(function(child) {
-          return !exp.id || child.shadowId === target.shadowId;
-        }), exp, recurse));
-      }
-    });
-    return result;
-  }
   var escapeRegExp = function() {
-    /*! Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License */
     var from = /(?=[\-\[\]{}()*+?.\\\^$|,#\s])/g;
     var to = '\\';
     return function(string) {
@@ -3366,7 +6526,6 @@
   }();
   var reUnescape = /\\/g;
   function convertAttributes(atts) {
-    /*! Credit Mootools Copyright Mootools, MIT License */
     if (!atts) {
       return;
     }
@@ -3399,7 +6558,7 @@
 
        case '*=':
         test = function test(value) {
-          return value && value.indexOf(attributeValue) > -1;
+          return value && value.includes(attributeValue);
         };
         break;
 
@@ -3450,7 +6609,7 @@
     return pseudos.map(function(p) {
       var expressions;
       if (p.name === 'not') {
-        expressions = axe.utils.cssParser.parse(p.value);
+        expressions = p.value;
         expressions = expressions.selectors ? expressions.selectors : [ expressions ];
         expressions = convertExpressions(expressions);
       }
@@ -3479,34 +6638,87 @@
       return newExp;
     });
   };
-  matchExpressions = function matchExpressions(domTree, expressions, recurse) {
-    return expressions.reduce(function(collected, exprArr) {
-      var candidates = domTree;
-      exprArr.forEach(function(exp, index) {
-        recurse = exp.combinator === '>' ? false : recurse;
-        if ([ ' ', '>' ].indexOf(exp.combinator) === -1) {
-          throw new Error('axe.utils.querySelectorAll does not support the combinator: ' + exp.combinator);
+  function createLocalVariables(vNodes, anyLevel, thisLevel, parentShadowId) {
+    var retVal = {
+      vNodes: vNodes.slice(),
+      anyLevel: anyLevel,
+      thisLevel: thisLevel,
+      parentShadowId: parentShadowId
+    };
+    retVal.vNodes.reverse();
+    return retVal;
+  }
+  function matchesSelector(vNode, exp) {
+    return matchesTag(vNode, exp[0]) && matchesClasses(vNode, exp[0]) && matchesAttributes(vNode, exp[0]) && matchesId(vNode, exp[0]) && matchesPseudos(vNode, exp[0]);
+  }
+  matchExpressions = function matchExpressions(domTree, expressions, recurse, filter) {
+    var stack = [];
+    var vNodes = Array.isArray(domTree) ? domTree : [ domTree ];
+    var currentLevel = createLocalVariables(vNodes, expressions, [], domTree[0].shadowId);
+    var result = [];
+    while (currentLevel.vNodes.length) {
+      var vNode = currentLevel.vNodes.pop();
+      var childOnly = [];
+      var childAny = [];
+      var combined = currentLevel.anyLevel.slice().concat(currentLevel.thisLevel);
+      var added = false;
+      for (var i = 0; i < combined.length; i++) {
+        var exp = combined[i];
+        if (matchesSelector(vNode, exp) && (!exp[0].id || vNode.shadowId === currentLevel.parentShadowId)) {
+          if (exp.length === 1) {
+            if (!added && (!filter || filter(vNode))) {
+              result.push(vNode);
+              added = true;
+            }
+          } else {
+            var rest = exp.slice(1);
+            if ([ ' ', '>' ].includes(rest[0].combinator) === false) {
+              throw new Error('axe.utils.querySelectorAll does not support the combinator: ' + exp[1].combinator);
+            }
+            if (rest[0].combinator === '>') {
+              childOnly.push(rest);
+            } else {
+              childAny.push(rest);
+            }
+          }
         }
-        candidates = candidates.reduce(function(result, node) {
-          return result.concat(matchSelector(index ? node.children : node, exp, recurse));
-        }, []);
-      });
-      return collected.concat(candidates);
-    }, []);
+        if (currentLevel.anyLevel.includes(exp) && (!exp[0].id || vNode.shadowId === currentLevel.parentShadowId)) {
+          childAny.push(exp);
+        }
+      }
+      if (vNode.children && vNode.children.length && recurse) {
+        stack.push(currentLevel);
+        currentLevel = createLocalVariables(vNode.children, childAny, childOnly, vNode.shadowId);
+      }
+      while (!currentLevel.vNodes.length && stack.length) {
+        currentLevel = stack.pop();
+      }
+    }
+    return result;
   };
   axe.utils.querySelectorAll = function(domTree, selector) {
+    return axe.utils.querySelectorAllFilter(domTree, selector);
+  };
+  axe.utils.querySelectorAllFilter = function(domTree, selector, filter) {
     domTree = Array.isArray(domTree) ? domTree : [ domTree ];
     var expressions = axe.utils.cssParser.parse(selector);
     expressions = expressions.selectors ? expressions.selectors : [ expressions ];
     expressions = convertExpressions(expressions);
-    return matchExpressions(domTree, expressions, true);
+    return matchExpressions(domTree, expressions, true, filter);
   };
   'use strict';
-  var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-    return typeof obj;
-  } : function(obj) {
-    return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-  };
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
   (function() {
     'use strict';
     function noop() {}
@@ -3559,10 +6771,10 @@
       }
       var q = {
         defer: function defer(fn) {
-          if ((typeof fn === 'undefined' ? 'undefined' : _typeof(fn)) === 'object' && fn.then && fn.catch) {
+          if (_typeof(fn) === 'object' && fn.then && fn['catch']) {
             var defer = fn;
             fn = function fn(resolve, reject) {
-              defer.then(resolve).catch(reject);
+              defer.then(resolve)['catch'](reject);
             };
           }
           funcGuard(fn);
@@ -3610,17 +6822,24 @@
     axe.utils.queue = queue;
   })();
   'use strict';
-  var _typeof = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? function(obj) {
-    return typeof obj;
-  } : function(obj) {
-    return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
-  };
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
   (function(exports) {
     'use strict';
-    var messages = {}, subscribers = {};
+    var messages = {}, subscribers = {}, errorTypes = Object.freeze([ 'EvalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError' ]);
     function _getSource() {
-      var application = 'axe', version = '', src;
-      if (typeof axe !== 'undefined' && axe._audit && !axe._audit.application) {
+      var application = 'axeAPI', version = '', src;
+      if (typeof axe !== 'undefined' && axe._audit && axe._audit.application) {
         application = axe._audit.application;
       }
       if (typeof axe !== 'undefined') {
@@ -3630,9 +6849,9 @@
       return src;
     }
     function verify(postedMessage) {
-      if ((typeof postedMessage === 'undefined' ? 'undefined' : _typeof(postedMessage)) === 'object' && typeof postedMessage.uuid === 'string' && postedMessage._respondable === true) {
+      if (_typeof(postedMessage) === 'object' && typeof postedMessage.uuid === 'string' && postedMessage._respondable === true) {
         var messageSource = _getSource();
-        return postedMessage._source === messageSource || postedMessage._source === 'axe.x.y.z' || messageSource === 'axe.x.y.z';
+        return postedMessage._source === messageSource || postedMessage._source === 'axeAPI.x.y.z' || messageSource === 'axeAPI.x.y.z';
       }
       return false;
     }
@@ -3676,17 +6895,18 @@
         post(source, topic, message, uuid, keepalive, callback);
       };
     }
-    function publish(target, data, keepalive) {
+    function publish(source, data, keepalive) {
       var topic = data.topic;
       var subscriber = subscribers[topic];
       if (subscriber) {
-        var responder = createResponder(target, null, data.uuid);
+        var responder = createResponder(source, null, data.uuid);
         subscriber(data.message, keepalive, responder);
       }
     }
     function buildErrorObject(error) {
       var msg = error.message || 'Unknown error occurred';
-      var ErrConstructor = window[error.name] || Error;
+      var errorName = errorTypes.includes(error.name) ? error.name : 'Error';
+      var ErrConstructor = window[errorName] || Error;
       if (error.stack) {
         msg += '\n' + error.stack.replace(error.message, '');
       }
@@ -3743,7 +6963,7 @@
     'use strict';
     var include, exclude, matching;
     var defaultExclude = axe._audit && axe._audit.tagExclude ? axe._audit.tagExclude : [];
-    if (runOnly.include || runOnly.exclude) {
+    if (runOnly.hasOwnProperty('include') || runOnly.hasOwnProperty('exclude')) {
       include = runOnly.include || [];
       include = Array.isArray(include) ? include : [ include ];
       exclude = runOnly.exclude || [];
@@ -3785,21 +7005,9 @@
     }
   };
   'use strict';
-  function getScroll(elm) {
-    var style = window.getComputedStyle(elm);
-    var visibleOverflowY = style.getPropertyValue('overflow-y') === 'visible';
-    var visibleOverflowX = style.getPropertyValue('overflow-x') === 'visible';
-    if (!visibleOverflowY && elm.scrollHeight > elm.clientHeight || !visibleOverflowX && elm.scrollWidth > elm.clientWidth) {
-      return {
-        elm: elm,
-        top: elm.scrollTop,
-        left: elm.scrollLeft
-      };
-    }
-  }
   function setScroll(elm, top, left) {
     if (elm === window) {
-      return elm.scroll(top, left);
+      return elm.scroll(left, top);
     } else {
       elm.scrollTop = top;
       elm.scrollLeft = left;
@@ -3807,7 +7015,7 @@
   }
   function getElmScrollRecursive(root) {
     return Array.from(root.children).reduce(function(scrolls, elm) {
-      var scroll = getScroll(elm);
+      var scroll = axe.utils.getScroll(elm);
       if (scroll) {
         scrolls.push(scroll);
       }
@@ -3857,33 +7065,77 @@
     }
     return false;
   }
-  function pushNode(result, nodes, context) {
+  function pushNode(result, nodes) {
     'use strict';
+    var temp;
+    if (result.length === 0) {
+      return nodes;
+    }
+    if (result.length < nodes.length) {
+      temp = result;
+      result = nodes;
+      nodes = temp;
+    }
     for (var i = 0, l = nodes.length; i < l; i++) {
-      if (!result.find(function(item) {
-        return item.actualNode === nodes[i].actualNode;
-      }) && isNodeInContext(nodes[i], context)) {
+      if (!result.includes(nodes[i])) {
         result.push(nodes[i]);
       }
     }
+    return result;
+  }
+  function reduceIncludes(includes) {
+    return includes.reduce(function(res, el) {
+      if (!res.length || !axe.utils.contains(res[res.length - 1], el)) {
+        res.push(el);
+      }
+      return res;
+    }, []);
   }
   axe.utils.select = function select(selector, context) {
     'use strict';
-    var result = [], candidate;
-    for (var i = 0, l = context.include.length; i < l; i++) {
-      candidate = context.include[i];
-      if (candidate.actualNode.nodeType === candidate.actualNode.ELEMENT_NODE && axe.utils.matchesSelector(candidate.actualNode, selector)) {
-        pushNode(result, [ candidate ], context);
+    var result = [];
+    var candidate;
+    if (axe._selectCache) {
+      for (var j = 0, l = axe._selectCache.length; j < l; j++) {
+        var item = axe._selectCache[j];
+        if (item.selector === selector) {
+          return item.result;
+        }
       }
-      pushNode(result, axe.utils.querySelectorAll(candidate, selector), context);
     }
-    return result.sort(axe.utils.nodeSorter);
+    var curried = function(context) {
+      return function(node) {
+        return isNodeInContext(node, context);
+      };
+    }(context);
+    var reducedIncludes = reduceIncludes(context.include);
+    for (var i = 0; i < reducedIncludes.length; i++) {
+      candidate = reducedIncludes[i];
+      result = pushNode(result, axe.utils.querySelectorAllFilter(candidate, selector, curried));
+    }
+    if (axe._selectCache) {
+      axe._selectCache.push({
+        selector: selector,
+        result: result
+      });
+    }
+    return result;
   };
   'use strict';
   axe.utils.toArray = function(thing) {
     'use strict';
     return Array.prototype.slice.call(thing);
   };
+  axe.utils.uniqueArray = function(arr1, arr2) {
+    return arr1.concat(arr2).filter(function(elem, pos, arr) {
+      return arr.indexOf(elem) === pos;
+    });
+  };
+  'use strict';
+  axe.utils.tokenList = function(str) {
+    'use strict';
+    return str.trim().replace(/\s{2,}/g, ' ').split(' ');
+  };
   'use strict';
   var uuid;
   (function(_global) {
@@ -4000,6 +7252,62 @@
     uuid.BufferClass = BufferClass;
   })(window);
   'use strict';
+  axe.utils.validInputTypes = function validInputTypes() {
+    'use strict';
+    return [ 'hidden', 'text', 'search', 'tel', 'url', 'email', 'password', 'date', 'month', 'week', 'time', 'datetime-local', 'number', 'range', 'color', 'checkbox', 'radio', 'file', 'submit', 'image', 'reset', 'button' ];
+  };
+  'use strict';
+  var langs = [ 'aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar', 'as', 'av', 'ay', 'az', 'ba', 'be', 'bg', 'bh', 'bi', 'bm', 'bn', 'bo', 'br', 'bs', 'ca', 'ce', 'ch', 'co', 'cr', 'cs', 'cu', 'cv', 'cy', 'da', 'de', 'dv', 'dz', 'ee', 'el', 'en', 'eo', 'es', 'et', 'eu', 'fa', 'ff', 'fi', 'fj', 'fo', 'fr', 'fy', 'ga', 'gd', 'gl', 'gn', 'gu', 'gv', 'ha', 'he', 'hi', 'ho', 'hr', 'ht', 'hu', 'hy', 'hz', 'ia', 'id', 'ie', 'ig', 'ii', 'ik', 'in', 'io', 'is', 'it', 'iu', 'iw', 'ja', 'ji', 'jv', 'jw', 'ka', 'kg', 'ki', 'kj', 'kk', 'kl', 'km', 'kn', 'ko', 'kr', 'ks', 'ku', 'kv', 'kw', 'ky', 'la', 'lb', 'lg', 'li', 'ln', 'lo', 'lt', 'lu', 'lv', 'mg', 'mh', 'mi', 'mk', 'ml', 'mn', 'mo', 'mr', 'ms', 'mt', 'my', 'na', 'nb', 'nd', 'ne', 'ng', 'nl', 'nn', 'no', 'nr', 'nv', 'ny', 'oc', 'oj', 'om', 'or', 'os', 'pa', 'pi', 'pl', 'ps', 'pt', 'qu', 'rm', 'rn', 'ro', 'ru', 'rw', 'sa', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sk', 'sl', 'sm', 'sn', 'so', 'sq', 'sr', 'ss', 'st', 'su', 'sv', 'sw', 'ta', 'te', 'tg', 'th', 'ti', 'tk', 'tl', 'tn', 'to', 'tr', 'ts', 'tt', 'tw', 'ty', 'ug', 'uk', 'ur', 'uz', 've', 'vi', 'vo', 'wa', 'wo', 'xh', 'yi', 'yo', 'za', 'zh', 'zu', 'aaa', 'aab', 'aac', 'aad', 'aae', 'aaf', 'aag', 'aah', 'aai', 'aak', 'aal', 'aam', 'aan', 'aao', 'aap', 'aaq', 'aas', 'aat', 'aau', 'aav', 'aaw', 'aax', 'aaz', 'aba', 'abb', 'abc', 'abd', 'abe', 'abf', 'abg', 'abh', 'abi', 'abj', 'abl', 'abm', 'abn', 'abo', 'abp', 'abq', 'abr', 'abs', 'abt', 'abu', 'abv', 'abw', 'abx', 'aby', 'abz', 'aca', 'acb', 'acd', 'ace', 'acf', 'ach', 'aci', 'ack', 'acl', 'acm', 'acn', 'acp', 'acq', 'acr', 'acs', 'act', 'acu', 'acv', 'acw', 'acx', 'acy', 'acz', 'ada', 'adb', 'add', 'ade', 'adf', 'adg', 'adh', 'adi', 'adj', 'adl', 'adn', 'ado', 'adp', 'adq', 'adr', 'ads', 'adt', 'adu', 'adw', 'adx', 'ady', 'adz', 'aea', 'aeb', 'aec', 'aed', 'aee', 'aek', 'ael', 'aem', 'aen', 'aeq', 'aer', 'aes', 'aeu', 'aew', 'aey', 'aez', 'afa', 'afb', 'afd', 'afe', 'afg', 'afh', 'afi', 'afk', 'afn', 'afo', 'afp', 'afs', 'aft', 'afu', 'afz', 'aga', 'agb', 'agc', 'agd', 'age', 'agf', 'agg', 'agh', 'agi', 'agj', 'agk', 'agl', 'agm', 'agn', 'ago', 'agp', 'agq', 'agr', 'ags', 'agt', 'agu', 'agv', 'agw', 'agx', 'agy', 'agz', 'aha', 'ahb', 'ahg', 'ahh', 'ahi', 'ahk', 'ahl', 'ahm', 'ahn', 'aho', 'ahp', 'ahr', 'ahs', 'aht', 'aia', 'aib', 'aic', 'aid', 'aie', 'aif', 'aig', 'aih', 'aii', 'aij', 'aik', 'ail', 'aim', 'ain', 'aio', 'aip', 'aiq', 'air', 'ais', 'ait', 'aiw', 'aix', 'aiy', 'aja', 'ajg', 'aji', 'ajn', 'ajp', 'ajt', 'aju', 'ajw', 'ajz', 'akb', 'akc', 'akd', 'ake', 'akf', 'akg', 'akh', 'aki', 'akj', 'akk', 'akl', 'akm', 'ako', 'akp', 'akq', 'akr', 'aks', 'akt', 'aku', 'akv', 'akw', 'akx', 'aky', 'akz', 'ala', 'alc', 'ald', 'ale', 'alf', 'alg', 'alh', 'ali', 'alj', 'alk', 'all', 'alm', 'aln', 'alo', 'alp', 'alq', 'alr', 'als', 'alt', 'alu', 'alv', 'alw', 'alx', 'aly', 'alz', 'ama', 'amb', 'amc', 'ame', 'amf', 'amg', 'ami', 'amj', 'amk', 'aml', 'amm', 'amn', 'amo', 'amp', 'amq', 'amr', 'ams', 'amt', 'amu', 'amv', 'amw', 'amx', 'amy', 'amz', 'ana', 'anb', 'anc', 'and', 'ane', 'anf', 'ang', 'anh', 'ani', 'anj', 'ank', 'anl', 'anm', 'ann', 'ano', 'anp', 'anq', 'anr', 'ans', 'ant', 'anu', 'anv', 'anw', 'anx', 'any', 'anz', 'aoa', 'aob', 'aoc', 'aod', 'aoe', 'aof', 'aog', 'aoh', 'aoi', 'aoj', 'aok', 'aol', 'aom', 'aon', 'aor', 'aos', 'aot', 'aou', 'aox', 'aoz', 'apa', 'apb', 'apc', 'apd', 'ape', 'apf', 'apg', 'aph', 'api', 'apj', 'apk', 'apl', 'apm', 'apn', 'apo', 'app', 'apq', 'apr', 'aps', 'apt', 'apu', 'apv', 'apw', 'apx', 'apy', 'apz', 'aqa', 'aqc', 'aqd', 'aqg', 'aql', 'aqm', 'aqn', 'aqp', 'aqr', 'aqt', 'aqz', 'arb', 'arc', 'ard', 'are', 'arh', 'ari', 'arj', 'ark', 'arl', 'arn', 'aro', 'arp', 'arq', 'arr', 'ars', 'art', 'aru', 'arv', 'arw', 'arx', 'ary', 'arz', 'asa', 'asb', 'asc', 'asd', 'ase', 'asf', 'asg', 'ash', 'asi', 'asj', 'ask', 'asl', 'asn', 'aso', 'asp', 'asq', 'asr', 'ass', 'ast', 'asu', 'asv', 'asw', 'asx', 'asy', 'asz', 'ata', 'atb', 'atc', 'atd', 'ate', 'atg', 'ath', 'ati', 'atj', 'atk', 'atl', 'atm', 'atn', 'ato', 'atp', 'atq', 'atr', 'ats', 'att', 'atu', 'atv', 'atw', 'atx', 'aty', 'atz', 'aua', 'aub', 'auc', 'aud', 'aue', 'auf', 'aug', 'auh', 'aui', 'auj', 'auk', 'aul', 'aum', 'aun', 'auo', 'aup', 'auq', 'aur', 'aus', 'aut', 'auu', 'auw', 'aux', 'auy', 'auz', 'avb', 'avd', 'avi', 'avk', 'avl', 'avm', 'avn', 'avo', 'avs', 'avt', 'avu', 'avv', 'awa', 'awb', 'awc', 'awd', 'awe', 'awg', 'awh', 'awi', 'awk', 'awm', 'awn', 'awo', 'awr', 'aws', 'awt', 'awu', 'awv', 'aww', 'awx', 'awy', 'axb', 'axe', 'axg', 'axk', 'axl', 'axm', 'axx', 'aya', 'ayb', 'ayc', 'ayd', 'aye', 'ayg', 'ayh', 'ayi', 'ayk', 'ayl', 'ayn', 'ayo', 'ayp', 'ayq', 'ayr', 'ays', 'ayt', 'ayu', 'ayx', 'ayy', 'ayz', 'aza', 'azb', 'azc', 'azd', 'azg', 'azj', 'azm', 'azn', 'azo', 'azt', 'azz', 'baa', 'bab', 'bac', 'bad', 'bae', 'baf', 'bag', 'bah', 'bai', 'baj', 'bal', 'ban', 'bao', 'bap', 'bar', 'bas', 'bat', 'bau', 'bav', 'baw', 'bax', 'bay', 'baz', 'bba', 'bbb', 'bbc', 'bbd', 'bbe', 'bbf', 'bbg', 'bbh', 'bbi', 'bbj', 'bbk', 'bbl', 'bbm', 'bbn', 'bbo', 'bbp', 'bbq', 'bbr', 'bbs', 'bbt', 'bbu', 'bbv', 'bbw', 'bbx', 'bby', 'bbz', 'bca', 'bcb', 'bcc', 'bcd', 'bce', 'bcf', 'bcg', 'bch', 'bci', 'bcj', 'bck', 'bcl', 'bcm', 'bcn', 'bco', 'bcp', 'bcq', 'bcr', 'bcs', 'bct', 'bcu', 'bcv', 'bcw', 'bcy', 'bcz', 'bda', 'bdb', 'bdc', 'bdd', 'bde', 'bdf', 'bdg', 'bdh', 'bdi', 'bdj', 'bdk', 'bdl', 'bdm', 'bdn', 'bdo', 'bdp', 'bdq', 'bdr', 'bds', 'bdt', 'bdu', 'bdv', 'bdw', 'bdx', 'bdy', 'bdz', 'bea', 'beb', 'bec', 'bed', 'bee', 'bef', 'beg', 'beh', 'bei', 'bej', 'bek', 'bem', 'beo', 'bep', 'beq', 'ber', 'bes', 'bet', 'beu', 'bev', 'bew', 'bex', 'bey', 'bez', 'bfa', 'bfb', 'bfc', 'bfd', 'bfe', 'bff', 'bfg', 'bfh', 'bfi', 'bfj', 'bfk', 'bfl', 'bfm', 'bfn', 'bfo', 'bfp', 'bfq', 'bfr', 'bfs', 'bft', 'bfu', 'bfw', 'bfx', 'bfy', 'bfz', 'bga', 'bgb', 'bgc', 'bgd', 'bge', 'bgf', 'bgg', 'bgi', 'bgj', 'bgk', 'bgl', 'bgm', 'bgn', 'bgo', 'bgp', 'bgq', 'bgr', 'bgs', 'bgt', 'bgu', 'bgv', 'bgw', 'bgx', 'bgy', 'bgz', 'bha', 'bhb', 'bhc', 'bhd', 'bhe', 'bhf', 'bhg', 'bhh', 'bhi', 'bhj', 'bhk', 'bhl', 'bhm', 'bhn', 'bho', 'bhp', 'bhq', 'bhr', 'bhs', 'bht', 'bhu', 'bhv', 'bhw', 'bhx', 'bhy', 'bhz', 'bia', 'bib', 'bic', 'bid', 'bie', 'bif', 'big', 'bij', 'bik', 'bil', 'bim', 'bin', 'bio', 'bip', 'biq', 'bir', 'bit', 'biu', 'biv', 'biw', 'bix', 'biy', 'biz', 'bja', 'bjb', 'bjc', 'bjd', 'bje', 'bjf', 'bjg', 'bjh', 'bji', 'bjj', 'bjk', 'bjl', 'bjm', 'bjn', 'bjo', 'bjp', 'bjq', 'bjr', 'bjs', 'bjt', 'bju', 'bjv', 'bjw', 'bjx', 'bjy', 'bjz', 'bka', 'bkb', 'bkc', 'bkd', 'bkf', 'bkg', 'bkh', 'bki', 'bkj', 'bkk', 'bkl', 'bkm', 'bkn', 'bko', 'bkp', 'bkq', 'bkr', 'bks', 'bkt', 'bku', 'bkv', 'bkw', 'bkx', 'bky', 'bkz', 'bla', 'blb', 'blc', 'bld', 'ble', 'blf', 'blg', 'blh', 'bli', 'blj', 'blk', 'bll', 'blm', 'bln', 'blo', 'blp', 'blq', 'blr', 'bls', 'blt', 'blv', 'blw', 'blx', 'bly', 'blz', 'bma', 'bmb', 'bmc', 'bmd', 'bme', 'bmf', 'bmg', 'bmh', 'bmi', 'bmj', 'bmk', 'bml', 'bmm', 'bmn', 'bmo', 'bmp', 'bmq', 'bmr', 'bms', 'bmt', 'bmu', 'bmv', 'bmw', 'bmx', 'bmy', 'bmz', 'bna', 'bnb', 'bnc', 'bnd', 'bne', 'bnf', 'bng', 'bni', 'bnj', 'bnk', 'bnl', 'bnm', 'bnn', 'bno', 'bnp', 'bnq', 'bnr', 'bns', 'bnt', 'bnu', 'bnv', 'bnw', 'bnx', 'bny', 'bnz', 'boa', 'bob', 'boe', 'bof', 'bog', 'boh', 'boi', 'boj', 'bok', 'bol', 'bom', 'bon', 'boo', 'bop', 'boq', 'bor', 'bot', 'bou', 'bov', 'bow', 'box', 'boy', 'boz', 'bpa', 'bpb', 'bpd', 'bpg', 'bph', 'bpi', 'bpj', 'bpk', 'bpl', 'bpm', 'bpn', 'bpo', 'bpp', 'bpq', 'bpr', 'bps', 'bpt', 'bpu', 'bpv', 'bpw', 'bpx', 'bpy', 'bpz', 'bqa', 'bqb', 'bqc', 'bqd', 'bqf', 'bqg', 'bqh', 'bqi', 'bqj', 'bqk', 'bql', 'bqm', 'bqn', 'bqo', 'bqp', 'bqq', 'bqr', 'bqs', 'bqt', 'bqu', 'bqv', 'bqw', 'bqx', 'bqy', 'bqz', 'bra', 'brb', 'brc', 'brd', 'brf', 'brg', 'brh', 'bri', 'brj', 'brk', 'brl', 'brm', 'brn', 'bro', 'brp', 'brq', 'brr', 'brs', 'brt', 'bru', 'brv', 'brw', 'brx', 'bry', 'brz', 'bsa', 'bsb', 'bsc', 'bse', 'bsf', 'bsg', 'bsh', 'bsi', 'bsj', 'bsk', 'bsl', 'bsm', 'bsn', 'bso', 'bsp', 'bsq', 'bsr', 'bss', 'bst', 'bsu', 'bsv', 'bsw', 'bsx', 'bsy', 'bta', 'btb', 'btc', 'btd', 'bte', 'btf', 'btg', 'bth', 'bti', 'btj', 'btk', 'btl', 'btm', 'btn', 'bto', 'btp', 'btq', 'btr', 'bts', 'btt', 'btu', 'btv', 'btw', 'btx', 'bty', 'btz', 'bua', 'bub', 'buc', 'bud', 'bue', 'buf', 'bug', 'buh', 'bui', 'buj', 'buk', 'bum', 'bun', 'buo', 'bup', 'buq', 'bus', 'but', 'buu', 'buv', 'buw', 'bux', 'buy', 'buz', 'bva', 'bvb', 'bvc', 'bvd', 'bve', 'bvf', 'bvg', 'bvh', 'bvi', 'bvj', 'bvk', 'bvl', 'bvm', 'bvn', 'bvo', 'bvp', 'bvq', 'bvr', 'bvt', 'bvu', 'bvv', 'bvw', 'bvx', 'bvy', 'bvz', 'bwa', 'bwb', 'bwc', 'bwd', 'bwe', 'bwf', 'bwg', 'bwh', 'bwi', 'bwj', 'bwk', 'bwl', 'bwm', 'bwn', 'bwo', 'bwp', 'bwq', 'bwr', 'bws', 'bwt', 'bwu', 'bww', 'bwx', 'bwy', 'bwz', 'bxa', 'bxb', 'bxc', 'bxd', 'bxe', 'bxf', 'bxg', 'bxh', 'bxi', 'bxj', 'bxk', 'bxl', 'bxm', 'bxn', 'bxo', 'bxp', 'bxq', 'bxr', 'bxs', 'bxu', 'bxv', 'bxw', 'bxx', 'bxz', 'bya', 'byb', 'byc', 'byd', 'bye', 'byf', 'byg', 'byh', 'byi', 'byj', 'byk', 'byl', 'bym', 'byn', 'byo', 'byp', 'byq', 'byr', 'bys', 'byt', 'byv', 'byw', 'byx', 'byy', 'byz', 'bza', 'bzb', 'bzc', 'bzd', 'bze', 'bzf', 'bzg', 'bzh', 'bzi', 'bzj', 'bzk', 'bzl', 'bzm', 'bzn', 'bzo', 'bzp', 'bzq', 'bzr', 'bzs', 'bzt', 'bzu', 'bzv', 'bzw', 'bzx', 'bzy', 'bzz', 'caa', 'cab', 'cac', 'cad', 'cae', 'caf', 'cag', 'cah', 'cai', 'caj', 'cak', 'cal', 'cam', 'can', 'cao', 'cap', 'caq', 'car', 'cas', 'cau', 'cav', 'caw', 'cax', 'cay', 'caz', 'cba', 'cbb', 'cbc', 'cbd', 'cbe', 'cbg', 'cbh', 'cbi', 'cbj', 'cbk', 'cbl', 'cbn', 'cbo', 'cbq', 'cbr', 'cbs', 'cbt', 'cbu', 'cbv', 'cbw', 'cby', 'cca', 'ccc', 'ccd', 'cce', 'ccg', 'cch', 'ccj', 'ccl', 'ccm', 'ccn', 'cco', 'ccp', 'ccq', 'ccr', 'ccs', 'cda', 'cdc', 'cdd', 'cde', 'cdf', 'cdg', 'cdh', 'cdi', 'cdj', 'cdm', 'cdn', 'cdo', 'cdr', 'cds', 'cdy', 'cdz', 'cea', 'ceb', 'ceg', 'cek', 'cel', 'cen', 'cet', 'cfa', 'cfd', 'cfg', 'cfm', 'cga', 'cgc', 'cgg', 'cgk', 'chb', 'chc', 'chd', 'chf', 'chg', 'chh', 'chj', 'chk', 'chl', 'chm', 'chn', 'cho', 'chp', 'chq', 'chr', 'cht', 'chw', 'chx', 'chy', 'chz', 'cia', 'cib', 'cic', 'cid', 'cie', 'cih', 'cik', 'cim', 'cin', 'cip', 'cir', 'ciw', 'ciy', 'cja', 'cje', 'cjh', 'cji', 'cjk', 'cjm', 'cjn', 'cjo', 'cjp', 'cjr', 'cjs', 'cjv', 'cjy', 'cka', 'ckb', 'ckh', 'ckl', 'ckn', 'cko', 'ckq', 'ckr', 'cks', 'ckt', 'cku', 'ckv', 'ckx', 'cky', 'ckz', 'cla', 'clc', 'cld', 'cle', 'clh', 'cli', 'clj', 'clk', 'cll', 'clm', 'clo', 'clt', 'clu', 'clw', 'cly', 'cma', 'cmc', 'cme', 'cmg', 'cmi', 'cmk', 'cml', 'cmm', 'cmn', 'cmo', 'cmr', 'cms', 'cmt', 'cna', 'cnb', 'cnc', 'cng', 'cnh', 'cni', 'cnk', 'cnl', 'cno', 'cnr', 'cns', 'cnt', 'cnu', 'cnw', 'cnx', 'coa', 'cob', 'coc', 'cod', 'coe', 'cof', 'cog', 'coh', 'coj', 'cok', 'col', 'com', 'con', 'coo', 'cop', 'coq', 'cot', 'cou', 'cov', 'cow', 'cox', 'coy', 'coz', 'cpa', 'cpb', 'cpc', 'cpe', 'cpf', 'cpg', 'cpi', 'cpn', 'cpo', 'cpp', 'cps', 'cpu', 'cpx', 'cpy', 'cqd', 'cqu', 'cra', 'crb', 'crc', 'crd', 'crf', 'crg', 'crh', 'cri', 'crj', 'crk', 'crl', 'crm', 'crn', 'cro', 'crp', 'crq', 'crr', 'crs', 'crt', 'crv', 'crw', 'crx', 'cry', 'crz', 'csa', 'csb', 'csc', 'csd', 'cse', 'csf', 'csg', 'csh', 'csi', 'csj', 'csk', 'csl', 'csm', 'csn', 'cso', 'csq', 'csr', 'css', 'cst', 'csu', 'csv', 'csw', 'csy', 'csz', 'cta', 'ctc', 'ctd', 'cte', 'ctg', 'cth', 'ctl', 'ctm', 'ctn', 'cto', 'ctp', 'cts', 'ctt', 'ctu', 'ctz', 'cua', 'cub', 'cuc', 'cug', 'cuh', 'cui', 'cuj', 'cuk', 'cul', 'cum', 'cuo', 'cup', 'cuq', 'cur', 'cus', 'cut', 'cuu', 'cuv', 'cuw', 'cux', 'cuy', 'cvg', 'cvn', 'cwa', 'cwb', 'cwd', 'cwe', 'cwg', 'cwt', 'cya', 'cyb', 'cyo', 'czh', 'czk', 'czn', 'czo', 'czt', 'daa', 'dac', 'dad', 'dae', 'daf', 'dag', 'dah', 'dai', 'daj', 'dak', 'dal', 'dam', 'dao', 'dap', 'daq', 'dar', 'das', 'dau', 'dav', 'daw', 'dax', 'day', 'daz', 'dba', 'dbb', 'dbd', 'dbe', 'dbf', 'dbg', 'dbi', 'dbj', 'dbl', 'dbm', 'dbn', 'dbo', 'dbp', 'dbq', 'dbr', 'dbt', 'dbu', 'dbv', 'dbw', 'dby', 'dcc', 'dcr', 'dda', 'ddd', 'dde', 'ddg', 'ddi', 'ddj', 'ddn', 'ddo', 'ddr', 'dds', 'ddw', 'dec', 'ded', 'dee', 'def', 'deg', 'deh', 'dei', 'dek', 'del', 'dem', 'den', 'dep', 'deq', 'der', 'des', 'dev', 'dez', 'dga', 'dgb', 'dgc', 'dgd', 'dge', 'dgg', 'dgh', 'dgi', 'dgk', 'dgl', 'dgn', 'dgo', 'dgr', 'dgs', 'dgt', 'dgu', 'dgw', 'dgx', 'dgz', 'dha', 'dhd', 'dhg', 'dhi', 'dhl', 'dhm', 'dhn', 'dho', 'dhr', 'dhs', 'dhu', 'dhv', 'dhw', 'dhx', 'dia', 'dib', 'dic', 'did', 'dif', 'dig', 'dih', 'dii', 'dij', 'dik', 'dil', 'dim', 'din', 'dio', 'dip', 'diq', 'dir', 'dis', 'dit', 'diu', 'diw', 'dix', 'diy', 'diz', 'dja', 'djb', 'djc', 'djd', 'dje', 'djf', 'dji', 'djj', 'djk', 'djl', 'djm', 'djn', 'djo', 'djr', 'dju', 'djw', 'dka', 'dkk', 'dkl', 'dkr', 'dks', 'dkx', 'dlg', 'dlk', 'dlm', 'dln', 'dma', 'dmb', 'dmc', 'dmd', 'dme', 'dmg', 'dmk', 'dml', 'dmm', 'dmn', 'dmo', 'dmr', 'dms', 'dmu', 'dmv', 'dmw', 'dmx', 'dmy', 'dna', 'dnd', 'dne', 'dng', 'dni', 'dnj', 'dnk', 'dnn', 'dnr', 'dnt', 'dnu', 'dnv', 'dnw', 'dny', 'doa', 'dob', 'doc', 'doe', 'dof', 'doh', 'doi', 'dok', 'dol', 'don', 'doo', 'dop', 'doq', 'dor', 'dos', 'dot', 'dov', 'dow', 'dox', 'doy', 'doz', 'dpp', 'dra', 'drb', 'drc', 'drd', 'dre', 'drg', 'drh', 'dri', 'drl', 'drn', 'dro', 'drq', 'drr', 'drs', 'drt', 'dru', 'drw', 'dry', 'dsb', 'dse', 'dsh', 'dsi', 'dsl', 'dsn', 'dso', 'dsq', 'dta', 'dtb', 'dtd', 'dth', 'dti', 'dtk', 'dtm', 'dtn', 'dto', 'dtp', 'dtr', 'dts', 'dtt', 'dtu', 'dty', 'dua', 'dub', 'duc', 'dud', 'due', 'duf', 'dug', 'duh', 'dui', 'duj', 'duk', 'dul', 'dum', 'dun', 'duo', 'dup', 'duq', 'dur', 'dus', 'duu', 'duv', 'duw', 'dux', 'duy', 'duz', 'dva', 'dwa', 'dwl', 'dwr', 'dws', 'dwu', 'dww', 'dwy', 'dya', 'dyb', 'dyd', 'dyg', 'dyi', 'dym', 'dyn', 'dyo', 'dyu', 'dyy', 'dza', 'dzd', 'dze', 'dzg', 'dzl', 'dzn', 'eaa', 'ebg', 'ebk', 'ebo', 'ebr', 'ebu', 'ecr', 'ecs', 'ecy', 'eee', 'efa', 'efe', 'efi', 'ega', 'egl', 'ego', 'egx', 'egy', 'ehu', 'eip', 'eit', 'eiv', 'eja', 'eka', 'ekc', 'eke', 'ekg', 'eki', 'ekk', 'ekl', 'ekm', 'eko', 'ekp', 'ekr', 'eky', 'ele', 'elh', 'eli', 'elk', 'elm', 'elo', 'elp', 'elu', 'elx', 'ema', 'emb', 'eme', 'emg', 'emi', 'emk', 'emm', 'emn', 'emo', 'emp', 'ems', 'emu', 'emw', 'emx', 'emy', 'ena', 'enb', 'enc', 'end', 'enf', 'enh', 'enl', 'enm', 'enn', 'eno', 'enq', 'enr', 'enu', 'env', 'enw', 'enx', 'eot', 'epi', 'era', 'erg', 'erh', 'eri', 'erk', 'ero', 'err', 'ers', 'ert', 'erw', 'ese', 'esg', 'esh', 'esi', 'esk', 'esl', 'esm', 'esn', 'eso', 'esq', 'ess', 'esu', 'esx', 'esy', 'etb', 'etc', 'eth', 'etn', 'eto', 'etr', 'ets', 'ett', 'etu', 'etx', 'etz', 'euq', 'eve', 'evh', 'evn', 'ewo', 'ext', 'eya', 'eyo', 'eza', 'eze', 'faa', 'fab', 'fad', 'faf', 'fag', 'fah', 'fai', 'faj', 'fak', 'fal', 'fam', 'fan', 'fap', 'far', 'fat', 'fau', 'fax', 'fay', 'faz', 'fbl', 'fcs', 'fer', 'ffi', 'ffm', 'fgr', 'fia', 'fie', 'fil', 'fip', 'fir', 'fit', 'fiu', 'fiw', 'fkk', 'fkv', 'fla', 'flh', 'fli', 'fll', 'fln', 'flr', 'fly', 'fmp', 'fmu', 'fnb', 'fng', 'fni', 'fod', 'foi', 'fom', 'fon', 'for', 'fos', 'fox', 'fpe', 'fqs', 'frc', 'frd', 'frk', 'frm', 'fro', 'frp', 'frq', 'frr', 'frs', 'frt', 'fse', 'fsl', 'fss', 'fub', 'fuc', 'fud', 'fue', 'fuf', 'fuh', 'fui', 'fuj', 'fum', 'fun', 'fuq', 'fur', 'fut', 'fuu', 'fuv', 'fuy', 'fvr', 'fwa', 'fwe', 'gaa', 'gab', 'gac', 'gad', 'gae', 'gaf', 'gag', 'gah', 'gai', 'gaj', 'gak', 'gal', 'gam', 'gan', 'gao', 'gap', 'gaq', 'gar', 'gas', 'gat', 'gau', 'gav', 'gaw', 'gax', 'gay', 'gaz', 'gba', 'gbb', 'gbc', 'gbd', 'gbe', 'gbf', 'gbg', 'gbh', 'gbi', 'gbj', 'gbk', 'gbl', 'gbm', 'gbn', 'gbo', 'gbp', 'gbq', 'gbr', 'gbs', 'gbu', 'gbv', 'gbw', 'gbx', 'gby', 'gbz', 'gcc', 'gcd', 'gce', 'gcf', 'gcl', 'gcn', 'gcr', 'gct', 'gda', 'gdb', 'gdc', 'gdd', 'gde', 'gdf', 'gdg', 'gdh', 'gdi', 'gdj', 'gdk', 'gdl', 'gdm', 'gdn', 'gdo', 'gdq', 'gdr', 'gds', 'gdt', 'gdu', 'gdx', 'gea', 'geb', 'gec', 'ged', 'geg', 'geh', 'gei', 'gej', 'gek', 'gel', 'gem', 'geq', 'ges', 'gev', 'gew', 'gex', 'gey', 'gez', 'gfk', 'gft', 'gfx', 'gga', 'ggb', 'ggd', 'gge', 'ggg', 'ggk', 'ggl', 'ggn', 'ggo', 'ggr', 'ggt', 'ggu', 'ggw', 'gha', 'ghc', 'ghe', 'ghh', 'ghk', 'ghl', 'ghn', 'gho', 'ghr', 'ghs', 'ght', 'gia', 'gib', 'gic', 'gid', 'gie', 'gig', 'gih', 'gil', 'gim', 'gin', 'gio', 'gip', 'giq', 'gir', 'gis', 'git', 'giu', 'giw', 'gix', 'giy', 'giz', 'gji', 'gjk', 'gjm', 'gjn', 'gjr', 'gju', 'gka', 'gkd', 'gke', 'gkn', 'gko', 'gkp', 'gku', 'glc', 'gld', 'glh', 'gli', 'glj', 'glk', 'gll', 'glo', 'glr', 'glu', 'glw', 'gly', 'gma', 'gmb', 'gmd', 'gme', 'gmg', 'gmh', 'gml', 'gmm', 'gmn', 'gmq', 'gmu', 'gmv', 'gmw', 'gmx', 'gmy', 'gmz', 'gna', 'gnb', 'gnc', 'gnd', 'gne', 'gng', 'gnh', 'gni', 'gnj', 'gnk', 'gnl', 'gnm', 'gnn', 'gno', 'gnq', 'gnr', 'gnt', 'gnu', 'gnw', 'gnz', 'goa', 'gob', 'goc', 'god', 'goe', 'gof', 'gog', 'goh', 'goi', 'goj', 'gok', 'gol', 'gom', 'gon', 'goo', 'gop', 'goq', 'gor', 'gos', 'got', 'gou', 'gow', 'gox', 'goy', 'goz', 'gpa', 'gpe', 'gpn', 'gqa', 'gqi', 'gqn', 'gqr', 'gqu', 'gra', 'grb', 'grc', 'grd', 'grg', 'grh', 'gri', 'grj', 'grk', 'grm', 'gro', 'grq', 'grr', 'grs', 'grt', 'gru', 'grv', 'grw', 'grx', 'gry', 'grz', 'gse', 'gsg', 'gsl', 'gsm', 'gsn', 'gso', 'gsp', 'gss', 'gsw', 'gta', 'gti', 'gtu', 'gua', 'gub', 'guc', 'gud', 'gue', 'guf', 'gug', 'guh', 'gui', 'guk', 'gul', 'gum', 'gun', 'guo', 'gup', 'guq', 'gur', 'gus', 'gut', 'guu', 'guv', 'guw', 'gux', 'guz', 'gva', 'gvc', 'gve', 'gvf', 'gvj', 'gvl', 'gvm', 'gvn', 'gvo', 'gvp', 'gvr', 'gvs', 'gvy', 'gwa', 'gwb', 'gwc', 'gwd', 'gwe', 'gwf', 'gwg', 'gwi', 'gwj', 'gwm', 'gwn', 'gwr', 'gwt', 'gwu', 'gww', 'gwx', 'gxx', 'gya', 'gyb', 'gyd', 'gye', 'gyf', 'gyg', 'gyi', 'gyl', 'gym', 'gyn', 'gyo', 'gyr', 'gyy', 'gza', 'gzi', 'gzn', 'haa', 'hab', 'hac', 'had', 'hae', 'haf', 'hag', 'hah', 'hai', 'haj', 'hak', 'hal', 'ham', 'han', 'hao', 'hap', 'haq', 'har', 'has', 'hav', 'haw', 'hax', 'hay', 'haz', 'hba', 'hbb', 'hbn', 'hbo', 'hbu', 'hca', 'hch', 'hdn', 'hds', 'hdy', 'hea', 'hed', 'heg', 'heh', 'hei', 'hem', 'hgm', 'hgw', 'hhi', 'hhr', 'hhy', 'hia', 'hib', 'hid', 'hif', 'hig', 'hih', 'hii', 'hij', 'hik', 'hil', 'him', 'hio', 'hir', 'hit', 'hiw', 'hix', 'hji', 'hka', 'hke', 'hkk', 'hkn', 'hks', 'hla', 'hlb', 'hld', 'hle', 'hlt', 'hlu', 'hma', 'hmb', 'hmc', 'hmd', 'hme', 'hmf', 'hmg', 'hmh', 'hmi', 'hmj', 'hmk', 'hml', 'hmm', 'hmn', 'hmp', 'hmq', 'hmr', 'hms', 'hmt', 'hmu', 'hmv', 'hmw', 'hmx', 'hmy', 'hmz', 'hna', 'hnd', 'hne', 'hnh', 'hni', 'hnj', 'hnn', 'hno', 'hns', 'hnu', 'hoa', 'hob', 'hoc', 'hod', 'hoe', 'hoh', 'hoi', 'hoj', 'hok', 'hol', 'hom', 'hoo', 'hop', 'hor', 'hos', 'hot', 'hov', 'how', 'hoy', 'hoz', 'hpo', 'hps', 'hra', 'hrc', 'hre', 'hrk', 'hrm', 'hro', 'hrp', 'hrr', 'hrt', 'hru', 'hrw', 'hrx', 'hrz', 'hsb', 'hsh', 'hsl', 'hsn', 'hss', 'hti', 'hto', 'hts', 'htu', 'htx', 'hub', 'huc', 'hud', 'hue', 'huf', 'hug', 'huh', 'hui', 'huj', 'huk', 'hul', 'hum', 'huo', 'hup', 'huq', 'hur', 'hus', 'hut', 'huu', 'huv', 'huw', 'hux', 'huy', 'huz', 'hvc', 'hve', 'hvk', 'hvn', 'hvv', 'hwa', 'hwc', 'hwo', 'hya', 'hyw', 'hyx', 'iai', 'ian', 'iap', 'iar', 'iba', 'ibb', 'ibd', 'ibe', 'ibg', 'ibh', 'ibi', 'ibl', 'ibm', 'ibn', 'ibr', 'ibu', 'iby', 'ica', 'ich', 'icl', 'icr', 'ida', 'idb', 'idc', 'idd', 'ide', 'idi', 'idr', 'ids', 'idt', 'idu', 'ifa', 'ifb', 'ife', 'iff', 'ifk', 'ifm', 'ifu', 'ify', 'igb', 'ige', 'igg', 'igl', 'igm', 'ign', 'igo', 'igs', 'igw', 'ihb', 'ihi', 'ihp', 'ihw', 'iin', 'iir', 'ijc', 'ije', 'ijj', 'ijn', 'ijo', 'ijs', 'ike', 'iki', 'ikk', 'ikl', 'iko', 'ikp', 'ikr', 'iks', 'ikt', 'ikv', 'ikw', 'ikx', 'ikz', 'ila', 'ilb', 'ilg', 'ili', 'ilk', 'ill', 'ilm', 'ilo', 'ilp', 'ils', 'ilu', 'ilv', 'ilw', 'ima', 'ime', 'imi', 'iml', 'imn', 'imo', 'imr', 'ims', 'imy', 'inb', 'inc', 'ine', 'ing', 'inh', 'inj', 'inl', 'inm', 'inn', 'ino', 'inp', 'ins', 'int', 'inz', 'ior', 'iou', 'iow', 'ipi', 'ipo', 'iqu', 'iqw', 'ira', 'ire', 'irh', 'iri', 'irk', 'irn', 'iro', 'irr', 'iru', 'irx', 'iry', 'isa', 'isc', 'isd', 'ise', 'isg', 'ish', 'isi', 'isk', 'ism', 'isn', 'iso', 'isr', 'ist', 'isu', 'itb', 'itc', 'itd', 'ite', 'iti', 'itk', 'itl', 'itm', 'ito', 'itr', 'its', 'itt', 'itv', 'itw', 'itx', 'ity', 'itz', 'ium', 'ivb', 'ivv', 'iwk', 'iwm', 'iwo', 'iws', 'ixc', 'ixl', 'iya', 'iyo', 'iyx', 'izh', 'izi', 'izr', 'izz', 'jaa', 'jab', 'jac', 'jad', 'jae', 'jaf', 'jah', 'jaj', 'jak', 'jal', 'jam', 'jan', 'jao', 'jaq', 'jar', 'jas', 'jat', 'jau', 'jax', 'jay', 'jaz', 'jbe', 'jbi', 'jbj', 'jbk', 'jbn', 'jbo', 'jbr', 'jbt', 'jbu', 'jbw', 'jcs', 'jct', 'jda', 'jdg', 'jdt', 'jeb', 'jee', 'jeg', 'jeh', 'jei', 'jek', 'jel', 'jen', 'jer', 'jet', 'jeu', 'jgb', 'jge', 'jgk', 'jgo', 'jhi', 'jhs', 'jia', 'jib', 'jic', 'jid', 'jie', 'jig', 'jih', 'jii', 'jil', 'jim', 'jio', 'jiq', 'jit', 'jiu', 'jiv', 'jiy', 'jje', 'jjr', 'jka', 'jkm', 'jko', 'jkp', 'jkr', 'jku', 'jle', 'jls', 'jma', 'jmb', 'jmc', 'jmd', 'jmi', 'jml', 'jmn', 'jmr', 'jms', 'jmw', 'jmx', 'jna', 'jnd', 'jng', 'jni', 'jnj', 'jnl', 'jns', 'job', 'jod', 'jog', 'jor', 'jos', 'jow', 'jpa', 'jpr', 'jpx', 'jqr', 'jra', 'jrb', 'jrr', 'jrt', 'jru', 'jsl', 'jua', 'jub', 'juc', 'jud', 'juh', 'jui', 'juk', 'jul', 'jum', 'jun', 'juo', 'jup', 'jur', 'jus', 'jut', 'juu', 'juw', 'juy', 'jvd', 'jvn', 'jwi', 'jya', 'jye', 'jyy', 'kaa', 'kab', 'kac', 'kad', 'kae', 'kaf', 'kag', 'kah', 'kai', 'kaj', 'kak', 'kam', 'kao', 'kap', 'kaq', 'kar', 'kav', 'kaw', 'kax', 'kay', 'kba', 'kbb', 'kbc', 'kbd', 'kbe', 'kbf', 'kbg', 'kbh', 'kbi', 'kbj', 'kbk', 'kbl', 'kbm', 'kbn', 'kbo', 'kbp', 'kbq', 'kbr', 'kbs', 'kbt', 'kbu', 'kbv', 'kbw', 'kbx', 'kby', 'kbz', 'kca', 'kcb', 'kcc', 'kcd', 'kce', 'kcf', 'kcg', 'kch', 'kci', 'kcj', 'kck', 'kcl', 'kcm', 'kcn', 'kco', 'kcp', 'kcq', 'kcr', 'kcs', 'kct', 'kcu', 'kcv', 'kcw', 'kcx', 'kcy', 'kcz', 'kda', 'kdc', 'kdd', 'kde', 'kdf', 'kdg', 'kdh', 'kdi', 'kdj', 'kdk', 'kdl', 'kdm', 'kdn', 'kdo', 'kdp', 'kdq', 'kdr', 'kdt', 'kdu', 'kdv', 'kdw', 'kdx', 'kdy', 'kdz', 'kea', 'keb', 'kec', 'ked', 'kee', 'kef', 'keg', 'keh', 'kei', 'kej', 'kek', 'kel', 'kem', 'ken', 'keo', 'kep', 'keq', 'ker', 'kes', 'ket', 'keu', 'kev', 'kew', 'kex', 'key', 'kez', 'kfa', 'kfb', 'kfc', 'kfd', 'kfe', 'kff', 'kfg', 'kfh', 'kfi', 'kfj', 'kfk', 'kfl', 'kfm', 'kfn', 'kfo', 'kfp', 'kfq', 'kfr', 'kfs', 'kft', 'kfu', 'kfv', 'kfw', 'kfx', 'kfy', 'kfz', 'kga', 'kgb', 'kgc', 'kgd', 'kge', 'kgf', 'kgg', 'kgh', 'kgi', 'kgj', 'kgk', 'kgl', 'kgm', 'kgn', 'kgo', 'kgp', 'kgq', 'kgr', 'kgs', 'kgt', 'kgu', 'kgv', 'kgw', 'kgx', 'kgy', 'kha', 'khb', 'khc', 'khd', 'khe', 'khf', 'khg', 'khh', 'khi', 'khj', 'khk', 'khl', 'khn', 'kho', 'khp', 'khq', 'khr', 'khs', 'kht', 'khu', 'khv', 'khw', 'khx', 'khy', 'khz', 'kia', 'kib', 'kic', 'kid', 'kie', 'kif', 'kig', 'kih', 'kii', 'kij', 'kil', 'kim', 'kio', 'kip', 'kiq', 'kis', 'kit', 'kiu', 'kiv', 'kiw', 'kix', 'kiy', 'kiz', 'kja', 'kjb', 'kjc', 'kjd', 'kje', 'kjf', 'kjg', 'kjh', 'kji', 'kjj', 'kjk', 'kjl', 'kjm', 'kjn', 'kjo', 'kjp', 'kjq', 'kjr', 'kjs', 'kjt', 'kju', 'kjv', 'kjx', 'kjy', 'kjz', 'kka', 'kkb', 'kkc', 'kkd', 'kke', 'kkf', 'kkg', 'kkh', 'kki', 'kkj', 'kkk', 'kkl', 'kkm', 'kkn', 'kko', 'kkp', 'kkq', 'kkr', 'kks', 'kkt', 'kku', 'kkv', 'kkw', 'kkx', 'kky', 'kkz', 'kla', 'klb', 'klc', 'kld', 'kle', 'klf', 'klg', 'klh', 'kli', 'klj', 'klk', 'kll', 'klm', 'kln', 'klo', 'klp', 'klq', 'klr', 'kls', 'klt', 'klu', 'klv', 'klw', 'klx', 'kly', 'klz', 'kma', 'kmb', 'kmc', 'kmd', 'kme', 'kmf', 'kmg', 'kmh', 'kmi', 'kmj', 'kmk', 'kml', 'kmm', 'kmn', 'kmo', 'kmp', 'kmq', 'kmr', 'kms', 'kmt', 'kmu', 'kmv', 'kmw', 'kmx', 'kmy', 'kmz', 'kna', 'knb', 'knc', 'knd', 'kne', 'knf', 'kng', 'kni', 'knj', 'knk', 'knl', 'knm', 'knn', 'kno', 'knp', 'knq', 'knr', 'kns', 'knt', 'knu', 'knv', 'knw', 'knx', 'kny', 'knz', 'koa', 'koc', 'kod', 'koe', 'kof', 'kog', 'koh', 'koi', 'koj', 'kok', 'kol', 'koo', 'kop', 'koq', 'kos', 'kot', 'kou', 'kov', 'kow', 'kox', 'koy', 'koz', 'kpa', 'kpb', 'kpc', 'kpd', 'kpe', 'kpf', 'kpg', 'kph', 'kpi', 'kpj', 'kpk', 'kpl', 'kpm', 'kpn', 'kpo', 'kpp', 'kpq', 'kpr', 'kps', 'kpt', 'kpu', 'kpv', 'kpw', 'kpx', 'kpy', 'kpz', 'kqa', 'kqb', 'kqc', 'kqd', 'kqe', 'kqf', 'kqg', 'kqh', 'kqi', 'kqj', 'kqk', 'kql', 'kqm', 'kqn', 'kqo', 'kqp', 'kqq', 'kqr', 'kqs', 'kqt', 'kqu', 'kqv', 'kqw', 'kqx', 'kqy', 'kqz', 'kra', 'krb', 'krc', 'krd', 'kre', 'krf', 'krh', 'kri', 'krj', 'krk', 'krl', 'krm', 'krn', 'kro', 'krp', 'krr', 'krs', 'krt', 'kru', 'krv', 'krw', 'krx', 'kry', 'krz', 'ksa', 'ksb', 'ksc', 'ksd', 'kse', 'ksf', 'ksg', 'ksh', 'ksi', 'ksj', 'ksk', 'ksl', 'ksm', 'ksn', 'kso', 'ksp', 'ksq', 'ksr', 'kss', 'kst', 'ksu', 'ksv', 'ksw', 'ksx', 'ksy', 'ksz', 'kta', 'ktb', 'ktc', 'ktd', 'kte', 'ktf', 'ktg', 'kth', 'kti', 'ktj', 'ktk', 'ktl', 'ktm', 'ktn', 'kto', 'ktp', 'ktq', 'ktr', 'kts', 'ktt', 'ktu', 'ktv', 'ktw', 'ktx', 'kty', 'ktz', 'kub', 'kuc', 'kud', 'kue', 'kuf', 'kug', 'kuh', 'kui', 'kuj', 'kuk', 'kul', 'kum', 'kun', 'kuo', 'kup', 'kuq', 'kus', 'kut', 'kuu', 'kuv', 'kuw', 'kux', 'kuy', 'kuz', 'kva', 'kvb', 'kvc', 'kvd', 'kve', 'kvf', 'kvg', 'kvh', 'kvi', 'kvj', 'kvk', 'kvl', 'kvm', 'kvn', 'kvo', 'kvp', 'kvq', 'kvr', 'kvs', 'kvt', 'kvu', 'kvv', 'kvw', 'kvx', 'kvy', 'kvz', 'kwa', 'kwb', 'kwc', 'kwd', 'kwe', 'kwf', 'kwg', 'kwh', 'kwi', 'kwj', 'kwk', 'kwl', 'kwm', 'kwn', 'kwo', 'kwp', 'kwq', 'kwr', 'kws', 'kwt', 'kwu', 'kwv', 'kww', 'kwx', 'kwy', 'kwz', 'kxa', 'kxb', 'kxc', 'kxd', 'kxe', 'kxf', 'kxh', 'kxi', 'kxj', 'kxk', 'kxl', 'kxm', 'kxn', 'kxo', 'kxp', 'kxq', 'kxr', 'kxs', 'kxt', 'kxu', 'kxv', 'kxw', 'kxx', 'kxy', 'kxz', 'kya', 'kyb', 'kyc', 'kyd', 'kye', 'kyf', 'kyg', 'kyh', 'kyi', 'kyj', 'kyk', 'kyl', 'kym', 'kyn', 'kyo', 'kyp', 'kyq', 'kyr', 'kys', 'kyt', 'kyu', 'kyv', 'kyw', 'kyx', 'kyy', 'kyz', 'kza', 'kzb', 'kzc', 'kzd', 'kze', 'kzf', 'kzg', 'kzh', 'kzi', 'kzj', 'kzk', 'kzl', 'kzm', 'kzn', 'kzo', 'kzp', 'kzq', 'kzr', 'kzs', 'kzt', 'kzu', 'kzv', 'kzw', 'kzx', 'kzy', 'kzz', 'laa', 'lab', 'lac', 'lad', 'lae', 'laf', 'lag', 'lah', 'lai', 'laj', 'lak', 'lal', 'lam', 'lan', 'lap', 'laq', 'lar', 'las', 'lau', 'law', 'lax', 'lay', 'laz', 'lba', 'lbb', 'lbc', 'lbe', 'lbf', 'lbg', 'lbi', 'lbj', 'lbk', 'lbl', 'lbm', 'lbn', 'lbo', 'lbq', 'lbr', 'lbs', 'lbt', 'lbu', 'lbv', 'lbw', 'lbx', 'lby', 'lbz', 'lcc', 'lcd', 'lce', 'lcf', 'lch', 'lcl', 'lcm', 'lcp', 'lcq', 'lcs', 'lda', 'ldb', 'ldd', 'ldg', 'ldh', 'ldi', 'ldj', 'ldk', 'ldl', 'ldm', 'ldn', 'ldo', 'ldp', 'ldq', 'lea', 'leb', 'lec', 'led', 'lee', 'lef', 'leg', 'leh', 'lei', 'lej', 'lek', 'lel', 'lem', 'len', 'leo', 'lep', 'leq', 'ler', 'les', 'let', 'leu', 'lev', 'lew', 'lex', 'ley', 'lez', 'lfa', 'lfn', 'lga', 'lgb', 'lgg', 'lgh', 'lgi', 'lgk', 'lgl', 'lgm', 'lgn', 'lgq', 'lgr', 'lgt', 'lgu', 'lgz', 'lha', 'lhh', 'lhi', 'lhl', 'lhm', 'lhn', 'lhp', 'lhs', 'lht', 'lhu', 'lia', 'lib', 'lic', 'lid', 'lie', 'lif', 'lig', 'lih', 'lii', 'lij', 'lik', 'lil', 'lio', 'lip', 'liq', 'lir', 'lis', 'liu', 'liv', 'liw', 'lix', 'liy', 'liz', 'lja', 'lje', 'lji', 'ljl', 'ljp', 'ljw', 'ljx', 'lka', 'lkb', 'lkc', 'lkd', 'lke', 'lkh', 'lki', 'lkj', 'lkl', 'lkm', 'lkn', 'lko', 'lkr', 'lks', 'lkt', 'lku', 'lky', 'lla', 'llb', 'llc', 'lld', 'lle', 'llf', 'llg', 'llh', 'lli', 'llj', 'llk', 'lll', 'llm', 'lln', 'llo', 'llp', 'llq', 'lls', 'llu', 'llx', 'lma', 'lmb', 'lmc', 'lmd', 'lme', 'lmf', 'lmg', 'lmh', 'lmi', 'lmj', 'lmk', 'lml', 'lmm', 'lmn', 'lmo', 'lmp', 'lmq', 'lmr', 'lmu', 'lmv', 'lmw', 'lmx', 'lmy', 'lmz', 'lna', 'lnb', 'lnd', 'lng', 'lnh', 'lni', 'lnj', 'lnl', 'lnm', 'lnn', 'lno', 'lns', 'lnu', 'lnw', 'lnz', 'loa', 'lob', 'loc', 'loe', 'lof', 'log', 'loh', 'loi', 'loj', 'lok', 'lol', 'lom', 'lon', 'loo', 'lop', 'loq', 'lor', 'los', 'lot', 'lou', 'lov', 'low', 'lox', 'loy', 'loz', 'lpa', 'lpe', 'lpn', 'lpo', 'lpx', 'lra', 'lrc', 'lre', 'lrg', 'lri', 'lrk', 'lrl', 'lrm', 'lrn', 'lro', 'lrr', 'lrt', 'lrv', 'lrz', 'lsa', 'lsd', 'lse', 'lsg', 'lsh', 'lsi', 'lsl', 'lsm', 'lso', 'lsp', 'lsr', 'lss', 'lst', 'lsy', 'ltc', 'ltg', 'lth', 'lti', 'ltn', 'lto', 'lts', 'ltu', 'lua', 'luc', 'lud', 'lue', 'luf', 'lui', 'luj', 'luk', 'lul', 'lum', 'lun', 'luo', 'lup', 'luq', 'lur', 'lus', 'lut', 'luu', 'luv', 'luw', 'luy', 'luz', 'lva', 'lvk', 'lvs', 'lvu', 'lwa', 'lwe', 'lwg', 'lwh', 'lwl', 'lwm', 'lwo', 'lws', 'lwt', 'lwu', 'lww', 'lya', 'lyg', 'lyn', 'lzh', 'lzl', 'lzn', 'lzz', 'maa', 'mab', 'mad', 'mae', 'maf', 'mag', 'mai', 'maj', 'mak', 'mam', 'man', 'map', 'maq', 'mas', 'mat', 'mau', 'mav', 'maw', 'max', 'maz', 'mba', 'mbb', 'mbc', 'mbd', 'mbe', 'mbf', 'mbh', 'mbi', 'mbj', 'mbk', 'mbl', 'mbm', 'mbn', 'mbo', 'mbp', 'mbq', 'mbr', 'mbs', 'mbt', 'mbu', 'mbv', 'mbw', 'mbx', 'mby', 'mbz', 'mca', 'mcb', 'mcc', 'mcd', 'mce', 'mcf', 'mcg', 'mch', 'mci', 'mcj', 'mck', 'mcl', 'mcm', 'mcn', 'mco', 'mcp', 'mcq', 'mcr', 'mcs', 'mct', 'mcu', 'mcv', 'mcw', 'mcx', 'mcy', 'mcz', 'mda', 'mdb', 'mdc', 'mdd', 'mde', 'mdf', 'mdg', 'mdh', 'mdi', 'mdj', 'mdk', 'mdl', 'mdm', 'mdn', 'mdp', 'mdq', 'mdr', 'mds', 'mdt', 'mdu', 'mdv', 'mdw', 'mdx', 'mdy', 'mdz', 'mea', 'meb', 'mec', 'med', 'mee', 'mef', 'meg', 'meh', 'mei', 'mej', 'mek', 'mel', 'mem', 'men', 'meo', 'mep', 'meq', 'mer', 'mes', 'met', 'meu', 'mev', 'mew', 'mey', 'mez', 'mfa', 'mfb', 'mfc', 'mfd', 'mfe', 'mff', 'mfg', 'mfh', 'mfi', 'mfj', 'mfk', 'mfl', 'mfm', 'mfn', 'mfo', 'mfp', 'mfq', 'mfr', 'mfs', 'mft', 'mfu', 'mfv', 'mfw', 'mfx', 'mfy', 'mfz', 'mga', 'mgb', 'mgc', 'mgd', 'mge', 'mgf', 'mgg', 'mgh', 'mgi', 'mgj', 'mgk', 'mgl', 'mgm', 'mgn', 'mgo', 'mgp', 'mgq', 'mgr', 'mgs', 'mgt', 'mgu', 'mgv', 'mgw', 'mgx', 'mgy', 'mgz', 'mha', 'mhb', 'mhc', 'mhd', 'mhe', 'mhf', 'mhg', 'mhh', 'mhi', 'mhj', 'mhk', 'mhl', 'mhm', 'mhn', 'mho', 'mhp', 'mhq', 'mhr', 'mhs', 'mht', 'mhu', 'mhw', 'mhx', 'mhy', 'mhz', 'mia', 'mib', 'mic', 'mid', 'mie', 'mif', 'mig', 'mih', 'mii', 'mij', 'mik', 'mil', 'mim', 'min', 'mio', 'mip', 'miq', 'mir', 'mis', 'mit', 'miu', 'miw', 'mix', 'miy', 'miz', 'mja', 'mjb', 'mjc', 'mjd', 'mje', 'mjg', 'mjh', 'mji', 'mjj', 'mjk', 'mjl', 'mjm', 'mjn', 'mjo', 'mjp', 'mjq', 'mjr', 'mjs', 'mjt', 'mju', 'mjv', 'mjw', 'mjx', 'mjy', 'mjz', 'mka', 'mkb', 'mkc', 'mke', 'mkf', 'mkg', 'mkh', 'mki', 'mkj', 'mkk', 'mkl', 'mkm', 'mkn', 'mko', 'mkp', 'mkq', 'mkr', 'mks', 'mkt', 'mku', 'mkv', 'mkw', 'mkx', 'mky', 'mkz', 'mla', 'mlb', 'mlc', 'mld', 'mle', 'mlf', 'mlh', 'mli', 'mlj', 'mlk', 'mll', 'mlm', 'mln', 'mlo', 'mlp', 'mlq', 'mlr', 'mls', 'mlu', 'mlv', 'mlw', 'mlx', 'mlz', 'mma', 'mmb', 'mmc', 'mmd', 'mme', 'mmf', 'mmg', 'mmh', 'mmi', 'mmj', 'mmk', 'mml', 'mmm', 'mmn', 'mmo', 'mmp', 'mmq', 'mmr', 'mmt', 'mmu', 'mmv', 'mmw', 'mmx', 'mmy', 'mmz', 'mna', 'mnb', 'mnc', 'mnd', 'mne', 'mnf', 'mng', 'mnh', 'mni', 'mnj', 'mnk', 'mnl', 'mnm', 'mnn', 'mno', 'mnp', 'mnq', 'mnr', 'mns', 'mnt', 'mnu', 'mnv', 'mnw', 'mnx', 'mny', 'mnz', 'moa', 'moc', 'mod', 'moe', 'mof', 'mog', 'moh', 'moi', 'moj', 'mok', 'mom', 'moo', 'mop', 'moq', 'mor', 'mos', 'mot', 'mou', 'mov', 'mow', 'mox', 'moy', 'moz', 'mpa', 'mpb', 'mpc', 'mpd', 'mpe', 'mpg', 'mph', 'mpi', 'mpj', 'mpk', 'mpl', 'mpm', 'mpn', 'mpo', 'mpp', 'mpq', 'mpr', 'mps', 'mpt', 'mpu', 'mpv', 'mpw', 'mpx', 'mpy', 'mpz', 'mqa', 'mqb', 'mqc', 'mqe', 'mqf', 'mqg', 'mqh', 'mqi', 'mqj', 'mqk', 'mql', 'mqm', 'mqn', 'mqo', 'mqp', 'mqq', 'mqr', 'mqs', 'mqt', 'mqu', 'mqv', 'mqw', 'mqx', 'mqy', 'mqz', 'mra', 'mrb', 'mrc', 'mrd', 'mre', 'mrf', 'mrg', 'mrh', 'mrj', 'mrk', 'mrl', 'mrm', 'mrn', 'mro', 'mrp', 'mrq', 'mrr', 'mrs', 'mrt', 'mru', 'mrv', 'mrw', 'mrx', 'mry', 'mrz', 'msb', 'msc', 'msd', 'mse', 'msf', 'msg', 'msh', 'msi', 'msj', 'msk', 'msl', 'msm', 'msn', 'mso', 'msp', 'msq', 'msr', 'mss', 'mst', 'msu', 'msv', 'msw', 'msx', 'msy', 'msz', 'mta', 'mtb', 'mtc', 'mtd', 'mte', 'mtf', 'mtg', 'mth', 'mti', 'mtj', 'mtk', 'mtl', 'mtm', 'mtn', 'mto', 'mtp', 'mtq', 'mtr', 'mts', 'mtt', 'mtu', 'mtv', 'mtw', 'mtx', 'mty', 'mua', 'mub', 'muc', 'mud', 'mue', 'mug', 'muh', 'mui', 'muj', 'muk', 'mul', 'mum', 'mun', 'muo', 'mup', 'muq', 'mur', 'mus', 'mut', 'muu', 'muv', 'mux', 'muy', 'muz', 'mva', 'mvb', 'mvd', 'mve', 'mvf', 'mvg', 'mvh', 'mvi', 'mvk', 'mvl', 'mvm', 'mvn', 'mvo', 'mvp', 'mvq', 'mvr', 'mvs', 'mvt', 'mvu', 'mvv', 'mvw', 'mvx', 'mvy', 'mvz', 'mwa', 'mwb', 'mwc', 'mwd', 'mwe', 'mwf', 'mwg', 'mwh', 'mwi', 'mwj', 'mwk', 'mwl', 'mwm', 'mwn', 'mwo', 'mwp', 'mwq', 'mwr', 'mws', 'mwt', 'mwu', 'mwv', 'mww', 'mwx', 'mwy', 'mwz', 'mxa', 'mxb', 'mxc', 'mxd', 'mxe', 'mxf', 'mxg', 'mxh', 'mxi', 'mxj', 'mxk', 'mxl', 'mxm', 'mxn', 'mxo', 'mxp', 'mxq', 'mxr', 'mxs', 'mxt', 'mxu', 'mxv', 'mxw', 'mxx', 'mxy', 'mxz', 'myb', 'myc', 'myd', 'mye', 'myf', 'myg', 'myh', 'myi', 'myj', 'myk', 'myl', 'mym', 'myn', 'myo', 'myp', 'myq', 'myr', 'mys', 'myt', 'myu', 'myv', 'myw', 'myx', 'myy', 'myz', 'mza', 'mzb', 'mzc', 'mzd', 'mze', 'mzg', 'mzh', 'mzi', 'mzj', 'mzk', 'mzl', 'mzm', 'mzn', 'mzo', 'mzp', 'mzq', 'mzr', 'mzs', 'mzt', 'mzu', 'mzv', 'mzw', 'mzx', 'mzy', 'mzz', 'naa', 'nab', 'nac', 'nad', 'nae', 'naf', 'nag', 'nah', 'nai', 'naj', 'nak', 'nal', 'nam', 'nan', 'nao', 'nap', 'naq', 'nar', 'nas', 'nat', 'naw', 'nax', 'nay', 'naz', 'nba', 'nbb', 'nbc', 'nbd', 'nbe', 'nbf', 'nbg', 'nbh', 'nbi', 'nbj', 'nbk', 'nbm', 'nbn', 'nbo', 'nbp', 'nbq', 'nbr', 'nbs', 'nbt', 'nbu', 'nbv', 'nbw', 'nbx', 'nby', 'nca', 'ncb', 'ncc', 'ncd', 'nce', 'ncf', 'ncg', 'nch', 'nci', 'ncj', 'nck', 'ncl', 'ncm', 'ncn', 'nco', 'ncp', 'ncq', 'ncr', 'ncs', 'nct', 'ncu', 'ncx', 'ncz', 'nda', 'ndb', 'ndc', 'ndd', 'ndf', 'ndg', 'ndh', 'ndi', 'ndj', 'ndk', 'ndl', 'ndm', 'ndn', 'ndp', 'ndq', 'ndr', 'nds', 'ndt', 'ndu', 'ndv', 'ndw', 'ndx', 'ndy', 'ndz', 'nea', 'neb', 'nec', 'ned', 'nee', 'nef', 'neg', 'neh', 'nei', 'nej', 'nek', 'nem', 'nen', 'neo', 'neq', 'ner', 'nes', 'net', 'neu', 'nev', 'new', 'nex', 'ney', 'nez', 'nfa', 'nfd', 'nfl', 'nfr', 'nfu', 'nga', 'ngb', 'ngc', 'ngd', 'nge', 'ngf', 'ngg', 'ngh', 'ngi', 'ngj', 'ngk', 'ngl', 'ngm', 'ngn', 'ngo', 'ngp', 'ngq', 'ngr', 'ngs', 'ngt', 'ngu', 'ngv', 'ngw', 'ngx', 'ngy', 'ngz', 'nha', 'nhb', 'nhc', 'nhd', 'nhe', 'nhf', 'nhg', 'nhh', 'nhi', 'nhk', 'nhm', 'nhn', 'nho', 'nhp', 'nhq', 'nhr', 'nht', 'nhu', 'nhv', 'nhw', 'nhx', 'nhy', 'nhz', 'nia', 'nib', 'nic', 'nid', 'nie', 'nif', 'nig', 'nih', 'nii', 'nij', 'nik', 'nil', 'nim', 'nin', 'nio', 'niq', 'nir', 'nis', 'nit', 'niu', 'niv', 'niw', 'nix', 'niy', 'niz', 'nja', 'njb', 'njd', 'njh', 'nji', 'njj', 'njl', 'njm', 'njn', 'njo', 'njr', 'njs', 'njt', 'nju', 'njx', 'njy', 'njz', 'nka', 'nkb', 'nkc', 'nkd', 'nke', 'nkf', 'nkg', 'nkh', 'nki', 'nkj', 'nkk', 'nkm', 'nkn', 'nko', 'nkp', 'nkq', 'nkr', 'nks', 'nkt', 'nku', 'nkv', 'nkw', 'nkx', 'nkz', 'nla', 'nlc', 'nle', 'nlg', 'nli', 'nlj', 'nlk', 'nll', 'nlm', 'nln', 'nlo', 'nlq', 'nlr', 'nlu', 'nlv', 'nlw', 'nlx', 'nly', 'nlz', 'nma', 'nmb', 'nmc', 'nmd', 'nme', 'nmf', 'nmg', 'nmh', 'nmi', 'nmj', 'nmk', 'nml', 'nmm', 'nmn', 'nmo', 'nmp', 'nmq', 'nmr', 'nms', 'nmt', 'nmu', 'nmv', 'nmw', 'nmx', 'nmy', 'nmz', 'nna', 'nnb', 'nnc', 'nnd', 'nne', 'nnf', 'nng', 'nnh', 'nni', 'nnj', 'nnk', 'nnl', 'nnm', 'nnn', 'nnp', 'nnq', 'nnr', 'nns', 'nnt', 'nnu', 'nnv', 'nnw', 'nnx', 'nny', 'nnz', 'noa', 'noc', 'nod', 'noe', 'nof', 'nog', 'noh', 'noi', 'noj', 'nok', 'nol', 'nom', 'non', 'noo', 'nop', 'noq', 'nos', 'not', 'nou', 'nov', 'now', 'noy', 'noz', 'npa', 'npb', 'npg', 'nph', 'npi', 'npl', 'npn', 'npo', 'nps', 'npu', 'npx', 'npy', 'nqg', 'nqk', 'nql', 'nqm', 'nqn', 'nqo', 'nqq', 'nqy', 'nra', 'nrb', 'nrc', 'nre', 'nrf', 'nrg', 'nri', 'nrk', 'nrl', 'nrm', 'nrn', 'nrp', 'nrr', 'nrt', 'nru', 'nrx', 'nrz', 'nsa', 'nsc', 'nsd', 'nse', 'nsf', 'nsg', 'nsh', 'nsi', 'nsk', 'nsl', 'nsm', 'nsn', 'nso', 'nsp', 'nsq', 'nsr', 'nss', 'nst', 'nsu', 'nsv', 'nsw', 'nsx', 'nsy', 'nsz', 'ntd', 'nte', 'ntg', 'nti', 'ntj', 'ntk', 'ntm', 'nto', 'ntp', 'ntr', 'nts', 'ntu', 'ntw', 'ntx', 'nty', 'ntz', 'nua', 'nub', 'nuc', 'nud', 'nue', 'nuf', 'nug', 'nuh', 'nui', 'nuj', 'nuk', 'nul', 'num', 'nun', 'nuo', 'nup', 'nuq', 'nur', 'nus', 'nut', 'nuu', 'nuv', 'nuw', 'nux', 'nuy', 'nuz', 'nvh', 'nvm', 'nvo', 'nwa', 'nwb', 'nwc', 'nwe', 'nwg', 'nwi', 'nwm', 'nwo', 'nwr', 'nwx', 'nwy', 'nxa', 'nxd', 'nxe', 'nxg', 'nxi', 'nxk', 'nxl', 'nxm', 'nxn', 'nxo', 'nxq', 'nxr', 'nxu', 'nxx', 'nyb', 'nyc', 'nyd', 'nye', 'nyf', 'nyg', 'nyh', 'nyi', 'nyj', 'nyk', 'nyl', 'nym', 'nyn', 'nyo', 'nyp', 'nyq', 'nyr', 'nys', 'nyt', 'nyu', 'nyv', 'nyw', 'nyx', 'nyy', 'nza', 'nzb', 'nzd', 'nzi', 'nzk', 'nzm', 'nzs', 'nzu', 'nzy', 'nzz', 'oaa', 'oac', 'oar', 'oav', 'obi', 'obk', 'obl', 'obm', 'obo', 'obr', 'obt', 'obu', 'oca', 'och', 'oco', 'ocu', 'oda', 'odk', 'odt', 'odu', 'ofo', 'ofs', 'ofu', 'ogb', 'ogc', 'oge', 'ogg', 'ogo', 'ogu', 'oht', 'ohu', 'oia', 'oin', 'ojb', 'ojc', 'ojg', 'ojp', 'ojs', 'ojv', 'ojw', 'oka', 'okb', 'okd', 'oke', 'okg', 'okh', 'oki', 'okj', 'okk', 'okl', 'okm', 'okn', 'oko', 'okr', 'oks', 'oku', 'okv', 'okx', 'ola', 'old', 'ole', 'olk', 'olm', 'olo', 'olr', 'olt', 'olu', 'oma', 'omb', 'omc', 'ome', 'omg', 'omi', 'omk', 'oml', 'omn', 'omo', 'omp', 'omq', 'omr', 'omt', 'omu', 'omv', 'omw', 'omx', 'ona', 'onb', 'one', 'ong', 'oni', 'onj', 'onk', 'onn', 'ono', 'onp', 'onr', 'ons', 'ont', 'onu', 'onw', 'onx', 'ood', 'oog', 'oon', 'oor', 'oos', 'opa', 'opk', 'opm', 'opo', 'opt', 'opy', 'ora', 'orc', 'ore', 'org', 'orh', 'orn', 'oro', 'orr', 'ors', 'ort', 'oru', 'orv', 'orw', 'orx', 'ory', 'orz', 'osa', 'osc', 'osi', 'oso', 'osp', 'ost', 'osu', 'osx', 'ota', 'otb', 'otd', 'ote', 'oti', 'otk', 'otl', 'otm', 'otn', 'oto', 'otq', 'otr', 'ots', 'ott', 'otu', 'otw', 'otx', 'oty', 'otz', 'oua', 'oub', 'oue', 'oui', 'oum', 'oun', 'ovd', 'owi', 'owl', 'oyb', 'oyd', 'oym', 'oyy', 'ozm', 'paa', 'pab', 'pac', 'pad', 'pae', 'paf', 'pag', 'pah', 'pai', 'pak', 'pal', 'pam', 'pao', 'pap', 'paq', 'par', 'pas', 'pat', 'pau', 'pav', 'paw', 'pax', 'pay', 'paz', 'pbb', 'pbc', 'pbe', 'pbf', 'pbg', 'pbh', 'pbi', 'pbl', 'pbm', 'pbn', 'pbo', 'pbp', 'pbr', 'pbs', 'pbt', 'pbu', 'pbv', 'pby', 'pbz', 'pca', 'pcb', 'pcc', 'pcd', 'pce', 'pcf', 'pcg', 'pch', 'pci', 'pcj', 'pck', 'pcl', 'pcm', 'pcn', 'pcp', 'pcr', 'pcw', 'pda', 'pdc', 'pdi', 'pdn', 'pdo', 'pdt', 'pdu', 'pea', 'peb', 'ped', 'pee', 'pef', 'peg', 'peh', 'pei', 'pej', 'pek', 'pel', 'pem', 'peo', 'pep', 'peq', 'pes', 'pev', 'pex', 'pey', 'pez', 'pfa', 'pfe', 'pfl', 'pga', 'pgd', 'pgg', 'pgi', 'pgk', 'pgl', 'pgn', 'pgs', 'pgu', 'pgy', 'pgz', 'pha', 'phd', 'phg', 'phh', 'phi', 'phk', 'phl', 'phm', 'phn', 'pho', 'phq', 'phr', 'pht', 'phu', 'phv', 'phw', 'pia', 'pib', 'pic', 'pid', 'pie', 'pif', 'pig', 'pih', 'pii', 'pij', 'pil', 'pim', 'pin', 'pio', 'pip', 'pir', 'pis', 'pit', 'piu', 'piv', 'piw', 'pix', 'piy', 'piz', 'pjt', 'pka', 'pkb', 'pkc', 'pkg', 'pkh', 'pkn', 'pko', 'pkp', 'pkr', 'pks', 'pkt', 'pku', 'pla', 'plb', 'plc', 'pld', 'ple', 'plf', 'plg', 'plh', 'plj', 'plk', 'pll', 'pln', 'plo', 'plp', 'plq', 'plr', 'pls', 'plt', 'plu', 'plv', 'plw', 'ply', 'plz', 'pma', 'pmb', 'pmc', 'pmd', 'pme', 'pmf', 'pmh', 'pmi', 'pmj', 'pmk', 'pml', 'pmm', 'pmn', 'pmo', 'pmq', 'pmr', 'pms', 'pmt', 'pmu', 'pmw', 'pmx', 'pmy', 'pmz', 'pna', 'pnb', 'pnc', 'pne', 'png', 'pnh', 'pni', 'pnj', 'pnk', 'pnl', 'pnm', 'pnn', 'pno', 'pnp', 'pnq', 'pnr', 'pns', 'pnt', 'pnu', 'pnv', 'pnw', 'pnx', 'pny', 'pnz', 'poc', 'pod', 'poe', 'pof', 'pog', 'poh', 'poi', 'pok', 'pom', 'pon', 'poo', 'pop', 'poq', 'pos', 'pot', 'pov', 'pow', 'pox', 'poy', 'poz', 'ppa', 'ppe', 'ppi', 'ppk', 'ppl', 'ppm', 'ppn', 'ppo', 'ppp', 'ppq', 'ppr', 'pps', 'ppt', 'ppu', 'pqa', 'pqe', 'pqm', 'pqw', 'pra', 'prb', 'prc', 'prd', 'pre', 'prf', 'prg', 'prh', 'pri', 'prk', 'prl', 'prm', 'prn', 'pro', 'prp', 'prq', 'prr', 'prs', 'prt', 'pru', 'prw', 'prx', 'pry', 'prz', 'psa', 'psc', 'psd', 'pse', 'psg', 'psh', 'psi', 'psl', 'psm', 'psn', 'pso', 'psp', 'psq', 'psr', 'pss', 'pst', 'psu', 'psw', 'psy', 'pta', 'pth', 'pti', 'ptn', 'pto', 'ptp', 'ptq', 'ptr', 'ptt', 'ptu', 'ptv', 'ptw', 'pty', 'pua', 'pub', 'puc', 'pud', 'pue', 'puf', 'pug', 'pui', 'puj', 'puk', 'pum', 'puo', 'pup', 'puq', 'pur', 'put', 'puu', 'puw', 'pux', 'puy', 'puz', 'pwa', 'pwb', 'pwg', 'pwi', 'pwm', 'pwn', 'pwo', 'pwr', 'pww', 'pxm', 'pye', 'pym', 'pyn', 'pys', 'pyu', 'pyx', 'pyy', 'pzn', 'qaa..qtz', 'qua', 'qub', 'quc', 'qud', 'quf', 'qug', 'quh', 'qui', 'quk', 'qul', 'qum', 'qun', 'qup', 'quq', 'qur', 'qus', 'quv', 'quw', 'qux', 'quy', 'quz', 'qva', 'qvc', 'qve', 'qvh', 'qvi', 'qvj', 'qvl', 'qvm', 'qvn', 'qvo', 'qvp', 'qvs', 'qvw', 'qvy', 'qvz', 'qwa', 'qwc', 'qwe', 'qwh', 'qwm', 'qws', 'qwt', 'qxa', 'qxc', 'qxh', 'qxl', 'qxn', 'qxo', 'qxp', 'qxq', 'qxr', 'qxs', 'qxt', 'qxu', 'qxw', 'qya', 'qyp', 'raa', 'rab', 'rac', 'rad', 'raf', 'rag', 'rah', 'rai', 'raj', 'rak', 'ral', 'ram', 'ran', 'rao', 'rap', 'raq', 'rar', 'ras', 'rat', 'rau', 'rav', 'raw', 'rax', 'ray', 'raz', 'rbb', 'rbk', 'rbl', 'rbp', 'rcf', 'rdb', 'rea', 'reb', 'ree', 'reg', 'rei', 'rej', 'rel', 'rem', 'ren', 'rer', 'res', 'ret', 'rey', 'rga', 'rge', 'rgk', 'rgn', 'rgr', 'rgs', 'rgu', 'rhg', 'rhp', 'ria', 'rie', 'rif', 'ril', 'rim', 'rin', 'rir', 'rit', 'riu', 'rjg', 'rji', 'rjs', 'rka', 'rkb', 'rkh', 'rki', 'rkm', 'rkt', 'rkw', 'rma', 'rmb', 'rmc', 'rmd', 'rme', 'rmf', 'rmg', 'rmh', 'rmi', 'rmk', 'rml', 'rmm', 'rmn', 'rmo', 'rmp', 'rmq', 'rmr', 'rms', 'rmt', 'rmu', 'rmv', 'rmw', 'rmx', 'rmy', 'rmz', 'rna', 'rnd', 'rng', 'rnl', 'rnn', 'rnp', 'rnr', 'rnw', 'roa', 'rob', 'roc', 'rod', 'roe', 'rof', 'rog', 'rol', 'rom', 'roo', 'rop', 'ror', 'rou', 'row', 'rpn', 'rpt', 'rri', 'rro', 'rrt', 'rsb', 'rsi', 'rsl', 'rsm', 'rtc', 'rth', 'rtm', 'rts', 'rtw', 'rub', 'ruc', 'rue', 'ruf', 'rug', 'ruh', 'rui', 'ruk', 'ruo', 'rup', 'ruq', 'rut', 'ruu', 'ruy', 'ruz', 'rwa', 'rwk', 'rwm', 'rwo', 'rwr', 'rxd', 'rxw', 'ryn', 'rys', 'ryu', 'rzh', 'saa', 'sab', 'sac', 'sad', 'sae', 'saf', 'sah', 'sai', 'saj', 'sak', 'sal', 'sam', 'sao', 'sap', 'saq', 'sar', 'sas', 'sat', 'sau', 'sav', 'saw', 'sax', 'say', 'saz', 'sba', 'sbb', 'sbc', 'sbd', 'sbe', 'sbf', 'sbg', 'sbh', 'sbi', 'sbj', 'sbk', 'sbl', 'sbm', 'sbn', 'sbo', 'sbp', 'sbq', 'sbr', 'sbs', 'sbt', 'sbu', 'sbv', 'sbw', 'sbx', 'sby', 'sbz', 'sca', 'scb', 'sce', 'scf', 'scg', 'sch', 'sci', 'sck', 'scl', 'scn', 'sco', 'scp', 'scq', 'scs', 'sct', 'scu', 'scv', 'scw', 'scx', 'sda', 'sdb', 'sdc', 'sde', 'sdf', 'sdg', 'sdh', 'sdj', 'sdk', 'sdl', 'sdm', 'sdn', 'sdo', 'sdp', 'sdr', 'sds', 'sdt', 'sdu', 'sdv', 'sdx', 'sdz', 'sea', 'seb', 'sec', 'sed', 'see', 'sef', 'seg', 'seh', 'sei', 'sej', 'sek', 'sel', 'sem', 'sen', 'seo', 'sep', 'seq', 'ser', 'ses', 'set', 'seu', 'sev', 'sew', 'sey', 'sez', 'sfb', 'sfe', 'sfm', 'sfs', 'sfw', 'sga', 'sgb', 'sgc', 'sgd', 'sge', 'sgg', 'sgh', 'sgi', 'sgj', 'sgk', 'sgl', 'sgm', 'sgn', 'sgo', 'sgp', 'sgr', 'sgs', 'sgt', 'sgu', 'sgw', 'sgx', 'sgy', 'sgz', 'sha', 'shb', 'shc', 'shd', 'she', 'shg', 'shh', 'shi', 'shj', 'shk', 'shl', 'shm', 'shn', 'sho', 'shp', 'shq', 'shr', 'shs', 'sht', 'shu', 'shv', 'shw', 'shx', 'shy', 'shz', 'sia', 'sib', 'sid', 'sie', 'sif', 'sig', 'sih', 'sii', 'sij', 'sik', 'sil', 'sim', 'sio', 'sip', 'siq', 'sir', 'sis', 'sit', 'siu', 'siv', 'siw', 'six', 'siy', 'siz', 'sja', 'sjb', 'sjd', 'sje', 'sjg', 'sjk', 'sjl', 'sjm', 'sjn', 'sjo', 'sjp', 'sjr', 'sjs', 'sjt', 'sju', 'sjw', 'ska', 'skb', 'skc', 'skd', 'ske', 'skf', 'skg', 'skh', 'ski', 'skj', 'skk', 'skm', 'skn', 'sko', 'skp', 'skq', 'skr', 'sks', 'skt', 'sku', 'skv', 'skw', 'skx', 'sky', 'skz', 'sla', 'slc', 'sld', 'sle', 'slf', 'slg', 'slh', 'sli', 'slj', 'sll', 'slm', 'sln', 'slp', 'slq', 'slr', 'sls', 'slt', 'slu', 'slw', 'slx', 'sly', 'slz', 'sma', 'smb', 'smc', 'smd', 'smf', 'smg', 'smh', 'smi', 'smj', 'smk', 'sml', 'smm', 'smn', 'smp', 'smq', 'smr', 'sms', 'smt', 'smu', 'smv', 'smw', 'smx', 'smy', 'smz', 'snb', 'snc', 'sne', 'snf', 'sng', 'snh', 'sni', 'snj', 'snk', 'snl', 'snm', 'snn', 'sno', 'snp', 'snq', 'snr', 'sns', 'snu', 'snv', 'snw', 'snx', 'sny', 'snz', 'soa', 'sob', 'soc', 'sod', 'soe', 'sog', 'soh', 'soi', 'soj', 'sok', 'sol', 'son', 'soo', 'sop', 'soq', 'sor', 'sos', 'sou', 'sov', 'sow', 'sox', 'soy', 'soz', 'spb', 'spc', 'spd', 'spe', 'spg', 'spi', 'spk', 'spl', 'spm', 'spn', 'spo', 'spp', 'spq', 'spr', 'sps', 'spt', 'spu', 'spv', 'spx', 'spy', 'sqa', 'sqh', 'sqj', 'sqk', 'sqm', 'sqn', 'sqo', 'sqq', 'sqr', 'sqs', 'sqt', 'squ', 'sra', 'srb', 'src', 'sre', 'srf', 'srg', 'srh', 'sri', 'srk', 'srl', 'srm', 'srn', 'sro', 'srq', 'srr', 'srs', 'srt', 'sru', 'srv', 'srw', 'srx', 'sry', 'srz', 'ssa', 'ssb', 'ssc', 'ssd', 'sse', 'ssf', 'ssg', 'ssh', 'ssi', 'ssj', 'ssk', 'ssl', 'ssm', 'ssn', 'sso', 'ssp', 'ssq', 'ssr', 'sss', 'sst', 'ssu', 'ssv', 'ssx', 'ssy', 'ssz', 'sta', 'stb', 'std', 'ste', 'stf', 'stg', 'sth', 'sti', 'stj', 'stk', 'stl', 'stm', 'stn', 'sto', 'stp', 'stq', 'str', 'sts', 'stt', 'stu', 'stv', 'stw', 'sty', 'sua', 'sub', 'suc', 'sue', 'sug', 'sui', 'suj', 'suk', 'sul', 'sum', 'suq', 'sur', 'sus', 'sut', 'suv', 'suw', 'sux', 'suy', 'suz', 'sva', 'svb', 'svc', 'sve', 'svk', 'svm', 'svr', 'svs', 'svx', 'swb', 'swc', 'swf', 'swg', 'swh', 'swi', 'swj', 'swk', 'swl', 'swm', 'swn', 'swo', 'swp', 'swq', 'swr', 'sws', 'swt', 'swu', 'swv', 'sww', 'swx', 'swy', 'sxb', 'sxc', 'sxe', 'sxg', 'sxk', 'sxl', 'sxm', 'sxn', 'sxo', 'sxr', 'sxs', 'sxu', 'sxw', 'sya', 'syb', 'syc', 'syd', 'syi', 'syk', 'syl', 'sym', 'syn', 'syo', 'syr', 'sys', 'syw', 'syx', 'syy', 'sza', 'szb', 'szc', 'szd', 'sze', 'szg', 'szl', 'szn', 'szp', 'szs', 'szv', 'szw', 'taa', 'tab', 'tac', 'tad', 'tae', 'taf', 'tag', 'tai', 'taj', 'tak', 'tal', 'tan', 'tao', 'tap', 'taq', 'tar', 'tas', 'tau', 'tav', 'taw', 'tax', 'tay', 'taz', 'tba', 'tbb', 'tbc', 'tbd', 'tbe', 'tbf', 'tbg', 'tbh', 'tbi', 'tbj', 'tbk', 'tbl', 'tbm', 'tbn', 'tbo', 'tbp', 'tbq', 'tbr', 'tbs', 'tbt', 'tbu', 'tbv', 'tbw', 'tbx', 'tby', 'tbz', 'tca', 'tcb', 'tcc', 'tcd', 'tce', 'tcf', 'tcg', 'tch', 'tci', 'tck', 'tcl', 'tcm', 'tcn', 'tco', 'tcp', 'tcq', 'tcs', 'tct', 'tcu', 'tcw', 'tcx', 'tcy', 'tcz', 'tda', 'tdb', 'tdc', 'tdd', 'tde', 'tdf', 'tdg', 'tdh', 'tdi', 'tdj', 'tdk', 'tdl', 'tdm', 'tdn', 'tdo', 'tdq', 'tdr', 'tds', 'tdt', 'tdu', 'tdv', 'tdx', 'tdy', 'tea', 'teb', 'tec', 'ted', 'tee', 'tef', 'teg', 'teh', 'tei', 'tek', 'tem', 'ten', 'teo', 'tep', 'teq', 'ter', 'tes', 'tet', 'teu', 'tev', 'tew', 'tex', 'tey', 'tez', 'tfi', 'tfn', 'tfo', 'tfr', 'tft', 'tga', 'tgb', 'tgc', 'tgd', 'tge', 'tgf', 'tgg', 'tgh', 'tgi', 'tgj', 'tgn', 'tgo', 'tgp', 'tgq', 'tgr', 'tgs', 'tgt', 'tgu', 'tgv', 'tgw', 'tgx', 'tgy', 'tgz', 'thc', 'thd', 'the', 'thf', 'thh', 'thi', 'thk', 'thl', 'thm', 'thn', 'thp', 'thq', 'thr', 'ths', 'tht', 'thu', 'thv', 'thw', 'thx', 'thy', 'thz', 'tia', 'tic', 'tid', 'tie', 'tif', 'tig', 'tih', 'tii', 'tij', 'tik', 'til', 'tim', 'tin', 'tio', 'tip', 'tiq', 'tis', 'tit', 'tiu', 'tiv', 'tiw', 'tix', 'tiy', 'tiz', 'tja', 'tjg', 'tji', 'tjl', 'tjm', 'tjn', 'tjo', 'tjs', 'tju', 'tjw', 'tka', 'tkb', 'tkd', 'tke', 'tkf', 'tkg', 'tkk', 'tkl', 'tkm', 'tkn', 'tkp', 'tkq', 'tkr', 'tks', 'tkt', 'tku', 'tkv', 'tkw', 'tkx', 'tkz', 'tla', 'tlb', 'tlc', 'tld', 'tlf', 'tlg', 'tlh', 'tli', 'tlj', 'tlk', 'tll', 'tlm', 'tln', 'tlo', 'tlp', 'tlq', 'tlr', 'tls', 'tlt', 'tlu', 'tlv', 'tlw', 'tlx', 'tly', 'tma', 'tmb', 'tmc', 'tmd', 'tme', 'tmf', 'tmg', 'tmh', 'tmi', 'tmj', 'tmk', 'tml', 'tmm', 'tmn', 'tmo', 'tmp', 'tmq', 'tmr', 'tms', 'tmt', 'tmu', 'tmv', 'tmw', 'tmy', 'tmz', 'tna', 'tnb', 'tnc', 'tnd', 'tne', 'tnf', 'tng', 'tnh', 'tni', 'tnk', 'tnl', 'tnm', 'tnn', 'tno', 'tnp', 'tnq', 'tnr', 'tns', 'tnt', 'tnu', 'tnv', 'tnw', 'tnx', 'tny', 'tnz', 'tob', 'toc', 'tod', 'toe', 'tof', 'tog', 'toh', 'toi', 'toj', 'tol', 'tom', 'too', 'top', 'toq', 'tor', 'tos', 'tou', 'tov', 'tow', 'tox', 'toy', 'toz', 'tpa', 'tpc', 'tpe', 'tpf', 'tpg', 'tpi', 'tpj', 'tpk', 'tpl', 'tpm', 'tpn', 'tpo', 'tpp', 'tpq', 'tpr', 'tpt', 'tpu', 'tpv', 'tpw', 'tpx', 'tpy', 'tpz', 'tqb', 'tql', 'tqm', 'tqn', 'tqo', 'tqp', 'tqq', 'tqr', 'tqt', 'tqu', 'tqw', 'tra', 'trb', 'trc', 'trd', 'tre', 'trf', 'trg', 'trh', 'tri', 'trj', 'trk', 'trl', 'trm', 'trn', 'tro', 'trp', 'trq', 'trr', 'trs', 'trt', 'tru', 'trv', 'trw', 'trx', 'try', 'trz', 'tsa', 'tsb', 'tsc', 'tsd', 'tse', 'tsf', 'tsg', 'tsh', 'tsi', 'tsj', 'tsk', 'tsl', 'tsm', 'tsp', 'tsq', 'tsr', 'tss', 'tst', 'tsu', 'tsv', 'tsw', 'tsx', 'tsy', 'tsz', 'tta', 'ttb', 'ttc', 'ttd', 'tte', 'ttf', 'ttg', 'tth', 'tti', 'ttj', 'ttk', 'ttl', 'ttm', 'ttn', 'tto', 'ttp', 'ttq', 'ttr', 'tts', 'ttt', 'ttu', 'ttv', 'ttw', 'tty', 'ttz', 'tua', 'tub', 'tuc', 'tud', 'tue', 'tuf', 'tug', 'tuh', 'tui', 'tuj', 'tul', 'tum', 'tun', 'tuo', 'tup', 'tuq', 'tus', 'tut', 'tuu', 'tuv', 'tuw', 'tux', 'tuy', 'tuz', 'tva', 'tvd', 'tve', 'tvk', 'tvl', 'tvm', 'tvn', 'tvo', 'tvs', 'tvt', 'tvu', 'tvw', 'tvy', 'twa', 'twb', 'twc', 'twd', 'twe', 'twf', 'twg', 'twh', 'twl', 'twm', 'twn', 'two', 'twp', 'twq', 'twr', 'twt', 'twu', 'tww', 'twx', 'twy', 'txa', 'txb', 'txc', 'txe', 'txg', 'txh', 'txi', 'txj', 'txm', 'txn', 'txo', 'txq', 'txr', 'txs', 'txt', 'txu', 'txx', 'txy', 'tya', 'tye', 'tyh', 'tyi', 'tyj', 'tyl', 'tyn', 'typ', 'tyr', 'tys', 'tyt', 'tyu', 'tyv', 'tyx', 'tyz', 'tza', 'tzh', 'tzj', 'tzl', 'tzm', 'tzn', 'tzo', 'tzx', 'uam', 'uan', 'uar', 'uba', 'ubi', 'ubl', 'ubr', 'ubu', 'uby', 'uda', 'ude', 'udg', 'udi', 'udj', 'udl', 'udm', 'udu', 'ues', 'ufi', 'uga', 'ugb', 'uge', 'ugn', 'ugo', 'ugy', 'uha', 'uhn', 'uis', 'uiv', 'uji', 'uka', 'ukg', 'ukh', 'ukk', 'ukl', 'ukp', 'ukq', 'uks', 'uku', 'ukw', 'uky', 'ula', 'ulb', 'ulc', 'ule', 'ulf', 'uli', 'ulk', 'ull', 'ulm', 'uln', 'ulu', 'ulw', 'uma', 'umb', 'umc', 'umd', 'umg', 'umi', 'umm', 'umn', 'umo', 'ump', 'umr', 'ums', 'umu', 'una', 'und', 'une', 'ung', 'unk', 'unm', 'unn', 'unp', 'unr', 'unu', 'unx', 'unz', 'uok', 'upi', 'upv', 'ura', 'urb', 'urc', 'ure', 'urf', 'urg', 'urh', 'uri', 'urj', 'urk', 'url', 'urm', 'urn', 'uro', 'urp', 'urr', 'urt', 'uru', 'urv', 'urw', 'urx', 'ury', 'urz', 'usa', 'ush', 'usi', 'usk', 'usp', 'usu', 'uta', 'ute', 'utp', 'utr', 'utu', 'uum', 'uun', 'uur', 'uuu', 'uve', 'uvh', 'uvl', 'uwa', 'uya', 'uzn', 'uzs', 'vaa', 'vae', 'vaf', 'vag', 'vah', 'vai', 'vaj', 'val', 'vam', 'van', 'vao', 'vap', 'var', 'vas', 'vau', 'vav', 'vay', 'vbb', 'vbk', 'vec', 'ved', 'vel', 'vem', 'veo', 'vep', 'ver', 'vgr', 'vgt', 'vic', 'vid', 'vif', 'vig', 'vil', 'vin', 'vis', 'vit', 'viv', 'vka', 'vki', 'vkj', 'vkk', 'vkl', 'vkm', 'vko', 'vkp', 'vkt', 'vku', 'vlp', 'vls', 'vma', 'vmb', 'vmc', 'vmd', 'vme', 'vmf', 'vmg', 'vmh', 'vmi', 'vmj', 'vmk', 'vml', 'vmm', 'vmp', 'vmq', 'vmr', 'vms', 'vmu', 'vmv', 'vmw', 'vmx', 'vmy', 'vmz', 'vnk', 'vnm', 'vnp', 'vor', 'vot', 'vra', 'vro', 'vrs', 'vrt', 'vsi', 'vsl', 'vsv', 'vto', 'vum', 'vun', 'vut', 'vwa', 'waa', 'wab', 'wac', 'wad', 'wae', 'waf', 'wag', 'wah', 'wai', 'waj', 'wak', 'wal', 'wam', 'wan', 'wao', 'wap', 'waq', 'war', 'was', 'wat', 'wau', 'wav', 'waw', 'wax', 'way', 'waz', 'wba', 'wbb', 'wbe', 'wbf', 'wbh', 'wbi', 'wbj', 'wbk', 'wbl', 'wbm', 'wbp', 'wbq', 'wbr', 'wbs', 'wbt', 'wbv', 'wbw', 'wca', 'wci', 'wdd', 'wdg', 'wdj', 'wdk', 'wdu', 'wdy', 'wea', 'wec', 'wed', 'weg', 'weh', 'wei', 'wem', 'wen', 'weo', 'wep', 'wer', 'wes', 'wet', 'weu', 'wew', 'wfg', 'wga', 'wgb', 'wgg', 'wgi', 'wgo', 'wgu', 'wgw', 'wgy', 'wha', 'whg', 'whk', 'whu', 'wib', 'wic', 'wie', 'wif', 'wig', 'wih', 'wii', 'wij', 'wik', 'wil', 'wim', 'win', 'wir', 'wit', 'wiu', 'wiv', 'wiw', 'wiy', 'wja', 'wji', 'wka', 'wkb', 'wkd', 'wkl', 'wku', 'wkw', 'wky', 'wla', 'wlc', 'wle', 'wlg', 'wli', 'wlk', 'wll', 'wlm', 'wlo', 'wlr', 'wls', 'wlu', 'wlv', 'wlw', 'wlx', 'wly', 'wma', 'wmb', 'wmc', 'wmd', 'wme', 'wmh', 'wmi', 'wmm', 'wmn', 'wmo', 'wms', 'wmt', 'wmw', 'wmx', 'wnb', 'wnc', 'wnd', 'wne', 'wng', 'wni', 'wnk', 'wnm', 'wnn', 'wno', 'wnp', 'wnu', 'wnw', 'wny', 'woa', 'wob', 'woc', 'wod', 'woe', 'wof', 'wog', 'woi', 'wok', 'wom', 'won', 'woo', 'wor', 'wos', 'wow', 'woy', 'wpc', 'wra', 'wrb', 'wrd', 'wrg', 'wrh', 'wri', 'wrk', 'wrl', 'wrm', 'wrn', 'wro', 'wrp', 'wrr', 'wrs', 'wru', 'wrv', 'wrw', 'wrx', 'wry', 'wrz', 'wsa', 'wsg', 'wsi', 'wsk', 'wsr', 'wss', 'wsu', 'wsv', 'wtf', 'wth', 'wti', 'wtk', 'wtm', 'wtw', 'wua', 'wub', 'wud', 'wuh', 'wul', 'wum', 'wun', 'wur', 'wut', 'wuu', 'wuv', 'wux', 'wuy', 'wwa', 'wwb', 'wwo', 'wwr', 'www', 'wxa', 'wxw', 'wya', 'wyb', 'wyi', 'wym', 'wyr', 'wyy', 'xaa', 'xab', 'xac', 'xad', 'xae', 'xag', 'xai', 'xaj', 'xak', 'xal', 'xam', 'xan', 'xao', 'xap', 'xaq', 'xar', 'xas', 'xat', 'xau', 'xav', 'xaw', 'xay', 'xba', 'xbb', 'xbc', 'xbd', 'xbe', 'xbg', 'xbi', 'xbj', 'xbm', 'xbn', 'xbo', 'xbp', 'xbr', 'xbw', 'xbx', 'xby', 'xcb', 'xcc', 'xce', 'xcg', 'xch', 'xcl', 'xcm', 'xcn', 'xco', 'xcr', 'xct', 'xcu', 'xcv', 'xcw', 'xcy', 'xda', 'xdc', 'xdk', 'xdm', 'xdo', 'xdy', 'xeb', 'xed', 'xeg', 'xel', 'xem', 'xep', 'xer', 'xes', 'xet', 'xeu', 'xfa', 'xga', 'xgb', 'xgd', 'xgf', 'xgg', 'xgi', 'xgl', 'xgm', 'xgn', 'xgr', 'xgu', 'xgw', 'xha', 'xhc', 'xhd', 'xhe', 'xhr', 'xht', 'xhu', 'xhv', 'xia', 'xib', 'xii', 'xil', 'xin', 'xip', 'xir', 'xis', 'xiv', 'xiy', 'xjb', 'xjt', 'xka', 'xkb', 'xkc', 'xkd', 'xke', 'xkf', 'xkg', 'xkh', 'xki', 'xkj', 'xkk', 'xkl', 'xkn', 'xko', 'xkp', 'xkq', 'xkr', 'xks', 'xkt', 'xku', 'xkv', 'xkw', 'xkx', 'xky', 'xkz', 'xla', 'xlb', 'xlc', 'xld', 'xle', 'xlg', 'xli', 'xln', 'xlo', 'xlp', 'xls', 'xlu', 'xly', 'xma', 'xmb', 'xmc', 'xmd', 'xme', 'xmf', 'xmg', 'xmh', 'xmj', 'xmk', 'xml', 'xmm', 'xmn', 'xmo', 'xmp', 'xmq', 'xmr', 'xms', 'xmt', 'xmu', 'xmv', 'xmw', 'xmx', 'xmy', 'xmz', 'xna', 'xnb', 'xnd', 'xng', 'xnh', 'xni', 'xnk', 'xnn', 'xno', 'xnr', 'xns', 'xnt', 'xnu', 'xny', 'xnz', 'xoc', 'xod', 'xog', 'xoi', 'xok', 'xom', 'xon', 'xoo', 'xop', 'xor', 'xow', 'xpa', 'xpc', 'xpe', 'xpg', 'xpi', 'xpj', 'xpk', 'xpm', 'xpn', 'xpo', 'xpp', 'xpq', 'xpr', 'xps', 'xpt', 'xpu', 'xpy', 'xqa', 'xqt', 'xra', 'xrb', 'xrd', 'xre', 'xrg', 'xri', 'xrm', 'xrn', 'xrq', 'xrr', 'xrt', 'xru', 'xrw', 'xsa', 'xsb', 'xsc', 'xsd', 'xse', 'xsh', 'xsi', 'xsj', 'xsl', 'xsm', 'xsn', 'xso', 'xsp', 'xsq', 'xsr', 'xss', 'xsu', 'xsv', 'xsy', 'xta', 'xtb', 'xtc', 'xtd', 'xte', 'xtg', 'xth', 'xti', 'xtj', 'xtl', 'xtm', 'xtn', 'xto', 'xtp', 'xtq', 'xtr', 'xts', 'xtt', 'xtu', 'xtv', 'xtw', 'xty', 'xtz', 'xua', 'xub', 'xud', 'xug', 'xuj', 'xul', 'xum', 'xun', 'xuo', 'xup', 'xur', 'xut', 'xuu', 'xve', 'xvi', 'xvn', 'xvo', 'xvs', 'xwa', 'xwc', 'xwd', 'xwe', 'xwg', 'xwj', 'xwk', 'xwl', 'xwo', 'xwr', 'xwt', 'xww', 'xxb', 'xxk', 'xxm', 'xxr', 'xxt', 'xya', 'xyb', 'xyj', 'xyk', 'xyl', 'xyt', 'xyy', 'xzh', 'xzm', 'xzp', 'yaa', 'yab', 'yac', 'yad', 'yae', 'yaf', 'yag', 'yah', 'yai', 'yaj', 'yak', 'yal', 'yam', 'yan', 'yao', 'yap', 'yaq', 'yar', 'yas', 'yat', 'yau', 'yav', 'yaw', 'yax', 'yay', 'yaz', 'yba', 'ybb', 'ybd', 'ybe', 'ybh', 'ybi', 'ybj', 'ybk', 'ybl', 'ybm', 'ybn', 'ybo', 'ybx', 'yby', 'ych', 'ycl', 'ycn', 'ycp', 'yda', 'ydd', 'yde', 'ydg', 'ydk', 'yds', 'yea', 'yec', 'yee', 'yei', 'yej', 'yel', 'yen', 'yer', 'yes', 'yet', 'yeu', 'yev', 'yey', 'yga', 'ygi', 'ygl', 'ygm', 'ygp', 'ygr', 'ygs', 'ygu', 'ygw', 'yha', 'yhd', 'yhl', 'yhs', 'yia', 'yif', 'yig', 'yih', 'yii', 'yij', 'yik', 'yil', 'yim', 'yin', 'yip', 'yiq', 'yir', 'yis', 'yit', 'yiu', 'yiv', 'yix', 'yiy', 'yiz', 'yka', 'ykg', 'yki', 'ykk', 'ykl', 'ykm', 'ykn', 'yko', 'ykr', 'ykt', 'yku', 'yky', 'yla', 'ylb', 'yle', 'ylg', 'yli', 'yll', 'ylm', 'yln', 'ylo', 'ylr', 'ylu', 'yly', 'yma', 'ymb', 'ymc', 'ymd', 'yme', 'ymg', 'ymh', 'ymi', 'ymk', 'yml', 'ymm', 'ymn', 'ymo', 'ymp', 'ymq', 'ymr', 'yms', 'ymt', 'ymx', 'ymz', 'yna', 'ynd', 'yne', 'yng', 'ynh', 'ynk', 'ynl', 'ynn', 'yno', 'ynq', 'yns', 'ynu', 'yob', 'yog', 'yoi', 'yok', 'yol', 'yom', 'yon', 'yos', 'yot', 'yox', 'yoy', 'ypa', 'ypb', 'ypg', 'yph', 'ypk', 'ypm', 'ypn', 'ypo', 'ypp', 'ypz', 'yra', 'yrb', 'yre', 'yri', 'yrk', 'yrl', 'yrm', 'yrn', 'yro', 'yrs', 'yrw', 'yry', 'ysc', 'ysd', 'ysg', 'ysl', 'ysn', 'yso', 'ysp', 'ysr', 'yss', 'ysy', 'yta', 'ytl', 'ytp', 'ytw', 'yty', 'yua', 'yub', 'yuc', 'yud', 'yue', 'yuf', 'yug', 'yui', 'yuj', 'yuk', 'yul', 'yum', 'yun', 'yup', 'yuq', 'yur', 'yut', 'yuu', 'yuw', 'yux', 'yuy', 'yuz', 'yva', 'yvt', 'ywa', 'ywg', 'ywl', 'ywn', 'ywq', 'ywr', 'ywt', 'ywu', 'yww', 'yxa', 'yxg', 'yxl', 'yxm', 'yxu', 'yxy', 'yyr', 'yyu', 'yyz', 'yzg', 'yzk', 'zaa', 'zab', 'zac', 'zad', 'zae', 'zaf', 'zag', 'zah', 'zai', 'zaj', 'zak', 'zal', 'zam', 'zao', 'zap', 'zaq', 'zar', 'zas', 'zat', 'zau', 'zav', 'zaw', 'zax', 'zay', 'zaz', 'zbc', 'zbe', 'zbl', 'zbt', 'zbw', 'zca', 'zch', 'zdj', 'zea', 'zeg', 'zeh', 'zen', 'zga', 'zgb', 'zgh', 'zgm', 'zgn', 'zgr', 'zhb', 'zhd', 'zhi', 'zhn', 'zhw', 'zhx', 'zia', 'zib', 'zik', 'zil', 'zim', 'zin', 'zir', 'ziw', 'ziz', 'zka', 'zkb', 'zkd', 'zkg', 'zkh', 'zkk', 'zkn', 'zko', 'zkp', 'zkr', 'zkt', 'zku', 'zkv', 'zkz', 'zle', 'zlj', 'zlm', 'zln', 'zlq', 'zls', 'zlw', 'zma', 'zmb', 'zmc', 'zmd', 'zme', 'zmf', 'zmg', 'zmh', 'zmi', 'zmj', 'zmk', 'zml', 'zmm', 'zmn', 'zmo', 'zmp', 'zmq', 'zmr', 'zms', 'zmt', 'zmu', 'zmv', 'zmw', 'zmx', 'zmy', 'zmz', 'zna', 'znd', 'zne', 'zng', 'znk', 'zns', 'zoc', 'zoh', 'zom', 'zoo', 'zoq', 'zor', 'zos', 'zpa', 'zpb', 'zpc', 'zpd', 'zpe', 'zpf', 'zpg', 'zph', 'zpi', 'zpj', 'zpk', 'zpl', 'zpm', 'zpn', 'zpo', 'zpp', 'zpq', 'zpr', 'zps', 'zpt', 'zpu', 'zpv', 'zpw', 'zpx', 'zpy', 'zpz', 'zqe', 'zra', 'zrg', 'zrn', 'zro', 'zrp', 'zrs', 'zsa', 'zsk', 'zsl', 'zsm', 'zsr', 'zsu', 'zte', 'ztg', 'ztl', 'ztm', 'ztn', 'ztp', 'ztq', 'zts', 'ztt', 'ztu', 'ztx', 'zty', 'zua', 'zuh', 'zum', 'zun', 'zuy', 'zwa', 'zxx', 'zyb', 'zyg', 'zyj', 'zyn', 'zyp', 'zza', 'zzj' ];
+  axe.utils.validLangs = function() {
+    'use strict';
+    return langs;
+  };
+  'use strict';
+  function _toConsumableArray(arr) {
+    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
+  }
+  function _nonIterableSpread() {
+    throw new TypeError('Invalid attempt to spread non-iterable instance');
+  }
+  function _iterableToArray(iter) {
+    if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === '[object Arguments]') {
+      return Array.from(iter);
+    }
+  }
+  function _arrayWithoutHoles(arr) {
+    if (Array.isArray(arr)) {
+      for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) {
+        arr2[i] = arr[i];
+      }
+      return arr2;
+    }
+  }
+  function _extends() {
+    _extends = Object.assign || function(target) {
+      for (var i = 1; i < arguments.length; i++) {
+        var source = arguments[i];
+        for (var key in source) {
+          if (Object.prototype.hasOwnProperty.call(source, key)) {
+            target[key] = source[key];
+          }
+        }
+      }
+      return target;
+    };
+    return _extends.apply(this, arguments);
+  }
+  function _typeof(obj) {
+    if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') {
+      _typeof = function _typeof(obj) {
+        return typeof obj;
+      };
+    } else {
+      _typeof = function _typeof(obj) {
+        return obj && typeof Symbol === 'function' && obj.constructor === Symbol && obj !== Symbol.prototype ? 'symbol' : typeof obj;
+      };
+    }
+    return _typeof(obj);
+  }
   axe._load({
     data: {
       rules: {
@@ -4015,10 +7323,26 @@
           description: 'Ensures ARIA attributes are allowed for an element\'s role',
           help: 'Elements must only use allowed ARIA attributes'
         },
+        'aria-allowed-role': {
+          description: 'Ensures role attribute has an appropriate value for the element',
+          help: 'ARIA role must be appropriate for the element'
+        },
+        'aria-dpub-role-fallback': {
+          description: 'Ensures unsupported DPUB roles are only used on elements with implicit fallback roles',
+          help: 'Unsupported DPUB ARIA roles should be used on elements with implicit fallback roles'
+        },
         'aria-hidden-body': {
           description: 'Ensures aria-hidden=\'true\' is not present on the document body.',
           help: 'aria-hidden=\'true\' must not be present on the document body'
         },
+        'aria-hidden-focus': {
+          description: 'Ensures aria-hidden elements do not contain focusable elements',
+          help: 'ARIA hidden element must not contain focusable elements'
+        },
+        'aria-input-field-name': {
+          description: 'Ensures every ARIA input field has an accessible name',
+          help: 'ARIA input fields have an accessible name'
+        },
         'aria-required-attr': {
           description: 'Ensures elements with ARIA roles have all required ARIA attributes',
           help: 'Required ARIA attributes must be provided'
@@ -4035,6 +7359,10 @@
           description: 'Ensures all elements with a role attribute use a valid value',
           help: 'ARIA roles used must conform to valid values'
         },
+        'aria-toggle-field-name': {
+          description: 'Ensures every ARIA toggle field has an accessible name',
+          help: 'ARIA toggle fields have an accessible name'
+        },
         'aria-valid-attr-value': {
           description: 'Ensures all ARIA attributes have valid values',
           help: 'ARIA attributes must conform to valid values'
@@ -4047,6 +7375,14 @@
           description: 'Ensures <audio> elements have captions',
           help: '<audio> elements must have a captions track'
         },
+        'autocomplete-valid': {
+          description: 'Ensure the autocomplete attribute is correct and suitable for the form field',
+          help: 'autocomplete attribute must be used correctly'
+        },
+        'avoid-inline-spacing': {
+          description: 'Ensure that text spacing set through style attributes can be adjusted with custom stylesheets',
+          help: 'Inline text spacing must be adjustable with custom stylesheets'
+        },
         blink: {
           description: 'Ensures <blink> elements are not used',
           help: '<blink> elements are deprecated and must not be used'
@@ -4060,13 +7396,17 @@
           help: 'Page must have means to bypass repeated blocks'
         },
         checkboxgroup: {
-          description: 'Ensures related <input type="checkbox"> elements have a group and that that group designation is consistent',
+          description: 'Ensures related <input type="checkbox"> elements have a group and that the group designation is consistent',
           help: 'Checkbox inputs with the same name attribute value must be part of a group'
         },
         'color-contrast': {
           description: 'Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds',
           help: 'Elements must have sufficient color contrast'
         },
+        'css-orientation-lock': {
+          description: 'Ensures content is not locked to any specific display orientation, and the content is operable in all display orientations',
+          help: 'CSS Media queries are not used to lock display orientation'
+        },
         'definition-list': {
           description: 'Ensures <dl> elements are structured correctly',
           help: '<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script> or <template> elements'
@@ -4079,6 +7419,14 @@
           description: 'Ensures each HTML document contains a non-empty <title> element',
           help: 'Documents must have <title> element to aid in navigation'
         },
+        'duplicate-id-active': {
+          description: 'Ensures every id attribute value of active elements is unique',
+          help: 'IDs of active elements must be unique'
+        },
+        'duplicate-id-aria': {
+          description: 'Ensures every id attribute value used in ARIA and in labels is unique',
+          help: 'IDs used in ARIA and labels must be unique'
+        },
         'duplicate-id': {
           description: 'Ensures every id attribute value is unique',
           help: 'id attribute value must be unique'
@@ -4087,6 +7435,18 @@
           description: 'Ensures headings have discernible text',
           help: 'Headings must not be empty'
         },
+        'focus-order-semantics': {
+          description: 'Ensures elements in the focus order have an appropriate role',
+          help: 'Elements in the focus order need a role appropriate for interactive content'
+        },
+        'form-field-multiple-labels': {
+          description: 'Ensures form field does not have multiple label elements',
+          help: 'Form field must not have multiple label elements'
+        },
+        'frame-tested': {
+          description: 'Ensures <iframe> and <frame> elements contain the axe-core script',
+          help: 'Frames must be tested with axe-core'
+        },
         'frame-title-unique': {
           description: 'Ensures <iframe> and <frame> elements contain a unique title attribute',
           help: 'Frames must have a unique title attribute'
@@ -4103,10 +7463,6 @@
           description: 'Informs users about hidden content.',
           help: 'Hidden content on the page cannot be analyzed'
         },
-        'href-no-hash': {
-          description: 'Ensures that href values are valid link references to promote only using anchors as links',
-          help: 'Anchors must only be used as links with valid URLs or URL fragments'
-        },
         'html-has-lang': {
           description: 'Ensures every HTML document has a lang attribute',
           help: '<html> element must have a lang attribute'
@@ -4115,18 +7471,30 @@
           description: 'Ensures the lang attribute of the <html> element has a valid value',
           help: '<html> element must have a valid value for the lang attribute'
         },
+        'html-xml-lang-mismatch': {
+          description: 'Ensure that HTML elements with both valid lang and xml:lang attributes agree on the base language of the page',
+          help: 'HTML elements with lang and xml:lang must have the same base language'
+        },
         'image-alt': {
           description: 'Ensures <img> elements have alternate text or a role of none or presentation',
           help: 'Images must have alternate text'
         },
         'image-redundant-alt': {
-          description: 'Ensure button and link text is not repeated as image alternative',
-          help: 'Text of buttons and links should not be repeated in the image alternative'
+          description: 'Ensure image alternative is not repeated as text',
+          help: 'Alternative text of images should not be repeated as text'
+        },
+        'input-button-name': {
+          description: 'Ensures input buttons have discernible text',
+          help: 'Input buttons must have discernible text'
         },
         'input-image-alt': {
           description: 'Ensures <input type="image"> elements have alternate text',
           help: 'Image buttons must have alternate text'
         },
+        'label-content-name-mismatch': {
+          description: 'Ensures that elements labelled through their content must have their visible text as part of their accessible name',
+          help: 'Elements must have their visible text as part of their accessible name'
+        },
         'label-title-only': {
           description: 'Ensures that every form element is not solely labeled using the title or aria-describedby attributes',
           help: 'Form elements should have a visible label'
@@ -4135,6 +7503,38 @@
           description: 'Ensures every form element has a label',
           help: 'Form elements must have labels'
         },
+        'landmark-banner-is-top-level': {
+          description: 'Ensures the banner landmark is at top level',
+          help: 'Banner landmark must not be contained in another landmark'
+        },
+        'landmark-complementary-is-top-level': {
+          description: 'Ensures the complementary landmark or aside is at top level',
+          help: 'Aside must not be contained in another landmark'
+        },
+        'landmark-contentinfo-is-top-level': {
+          description: 'Ensures the contentinfo landmark is at top level',
+          help: 'Contentinfo landmark must not be contained in another landmark'
+        },
+        'landmark-main-is-top-level': {
+          description: 'Ensures the main landmark is at top level',
+          help: 'Main landmark must not be contained in another landmark'
+        },
+        'landmark-no-duplicate-banner': {
+          description: 'Ensures the document has at most one banner landmark',
+          help: 'Document must not have more than one banner landmark'
+        },
+        'landmark-no-duplicate-contentinfo': {
+          description: 'Ensures the document has at most one contentinfo landmark',
+          help: 'Document must not have more than one contentinfo landmark'
+        },
+        'landmark-one-main': {
+          description: 'Ensures the document has only one main landmark and each iframe in the page has at most one main landmark',
+          help: 'Document must have one main landmark'
+        },
+        'landmark-unique': {
+          help: 'Ensures landmarks are unique',
+          description: 'Landmarks must have a unique role or role/label/title (i.e. accessible name) combination'
+        },
         'layout-table': {
           description: 'Ensures presentational <table> elements do not use <th>, <caption> elements or the summary attribute',
           help: 'Layout tables must not use data table elements'
@@ -4179,25 +7579,37 @@
           description: 'Ensure p elements are not used to style headings',
           help: 'Bold, italic text and font-size are not used to style p elements as a heading'
         },
+        'page-has-heading-one': {
+          description: 'Ensure that the page, or at least one of its frames contains a level-one heading',
+          help: 'Page must contain a level-one heading'
+        },
         radiogroup: {
           description: 'Ensures related <input type="radio"> elements have a group and that the group designation is consistent',
           help: 'Radio inputs with the same name attribute value must be part of a group'
         },
         region: {
-          description: 'Ensures all content is contained within a landmark region',
-          help: 'Content should be contained in a landmark region'
+          description: 'Ensures all page content is contained by landmarks',
+          help: 'All page content must be contained by landmarks'
+        },
+        'role-img-alt': {
+          description: 'Ensures [role=\'img\'] elements have alternate text',
+          help: '[role=\'img\'] elements have an alternative text'
         },
         'scope-attr-valid': {
           description: 'Ensures the scope attribute is used correctly on tables',
           help: 'scope attribute should be used correctly'
         },
+        'scrollable-region-focusable': {
+          description: 'Elements that have scrollable content should be accessible by keyboard',
+          help: 'Ensure that scrollable region has keyboard access'
+        },
         'server-side-image-map': {
           description: 'Ensures that server-side image maps are not used',
           help: 'Server-side image maps must not be used'
         },
         'skip-link': {
-          description: 'Ensures the first link on the page is a skip link',
-          help: 'The page should have a skip link as its first link'
+          description: 'Ensure all skip links have a focusable target',
+          help: 'The skip-link target should exist and be focusable'
         },
         tabindex: {
           description: 'Ensures tabindex attribute values are not greater than 0',
@@ -4221,7 +7633,7 @@
         },
         'th-has-data-cells': {
           description: 'Ensure that each table header in a data table refers to data cells',
-          help: 'All th element and elements with role=columnheader/rowheader must data cells which it describes'
+          help: 'All th elements and elements with role=columnheader/rowheader must have data cells they describe'
         },
         'valid-lang': {
           description: 'Ensures lang attributes have valid values',
@@ -4297,7 +7709,7 @@
               return out;
             },
             fail: function anonymous(it) {
-              var out = 'aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty or not visible';
+              var out = 'aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty';
               return out;
             }
           }
@@ -4323,6 +7735,57 @@
             }
           }
         },
+        'aria-unsupported-attr': {
+          impact: 'critical',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'ARIA attribute is supported';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'ARIA attribute is not widely supported in screen readers and assistive technologies: ';
+              var arr1 = it.data;
+              if (arr1) {
+                var value, i1 = -1, l1 = arr1.length - 1;
+                while (i1 < l1) {
+                  value = arr1[i1 += 1];
+                  out += ' ' + value;
+                }
+              }
+              return out;
+            }
+          }
+        },
+        'aria-allowed-role': {
+          impact: 'minor',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'ARIA role is allowed for given element';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'ARIA role' + (it.data && it.data.length > 1 ? 's' : '') + ' ' + it.data.join(', ') + ' ' + (it.data && it.data.length > 1 ? 'are' : ' is') + ' not allowed for given element';
+              return out;
+            },
+            incomplete: function anonymous(it) {
+              var out = 'ARIA role' + (it.data && it.data.length > 1 ? 's' : '') + ' ' + it.data.join(', ') + ' must be removed when the element is made visible, as ' + (it.data && it.data.length > 1 ? 'they are' : 'it is') + ' not allowed for the element';
+              return out;
+            }
+          }
+        },
+        'implicit-role-fallback': {
+          impact: 'moderate',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Element’s implicit ARIA role is an appropriate fallback';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Element’s implicit ARIA role is not a good fallback for the (unsupported) role';
+              return out;
+            }
+          }
+        },
         'aria-hidden-body': {
           impact: 'critical',
           messages: {
@@ -4336,6 +7799,45 @@
             }
           }
         },
+        'focusable-disabled': {
+          impact: 'serious',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'No focusable elements contained within element';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Focusable content should be disabled or be removed from the DOM';
+              return out;
+            }
+          }
+        },
+        'focusable-not-tabbable': {
+          impact: 'serious',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'No focusable elements contained within element';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Focusable content should have tabindex=\'-1\' or be removed from the DOM';
+              return out;
+            }
+          }
+        },
+        'no-implicit-explicit-label': {
+          impact: 'moderate',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'There is no mismatch between a <label> and accessible name';
+              return out;
+            },
+            incomplete: function anonymous(it) {
+              var out = 'Check that the <label> does not need be part of the ARIA ' + it.data + ' field\'s name';
+              return out;
+            }
+          }
+        },
         'aria-required-attr': {
           impact: 'critical',
           messages: {
@@ -4375,6 +7877,18 @@
                 }
               }
               return out;
+            },
+            incomplete: function anonymous(it) {
+              var out = 'Expecting ARIA ' + (it.data && it.data.length > 1 ? 'children' : 'child') + ' role to be added:';
+              var arr1 = it.data;
+              if (arr1) {
+                var value, i1 = -1, l1 = arr1.length - 1;
+                while (i1 < l1) {
+                  value = arr1[i1 += 1];
+                  out += ' ' + value;
+                }
+              }
+              return out;
             }
           }
         },
@@ -4425,6 +7939,40 @@
             }
           }
         },
+        unsupportedrole: {
+          impact: 'critical',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'ARIA role is supported';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'The role used is not widely supported in screen readers and assistive technologies: ';
+              var arr1 = it.data;
+              if (arr1) {
+                var value, i1 = -1, l1 = arr1.length - 1;
+                while (i1 < l1) {
+                  value = arr1[i1 += 1];
+                  out += ' ' + value;
+                }
+              }
+              return out;
+            }
+          }
+        },
+        'has-visible-text': {
+          impact: 'minor',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Element has text that is visible to screen readers';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Element does not have text that is visible to screen readers';
+              return out;
+            }
+          }
+        },
         'aria-valid-attr-value': {
           impact: 'critical',
           messages: {
@@ -4443,6 +7991,40 @@
                 }
               }
               return out;
+            },
+            incomplete: function anonymous(it) {
+              var out = 'ARIA attribute' + (it.data && it.data.length > 1 ? 's' : '') + ' element ID does not exist on the page:';
+              var arr1 = it.data;
+              if (arr1) {
+                var value, i1 = -1, l1 = arr1.length - 1;
+                while (i1 < l1) {
+                  value = arr1[i1 += 1];
+                  out += ' ' + value;
+                }
+              }
+              return out;
+            }
+          }
+        },
+        'aria-errormessage': {
+          impact: 'critical',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Uses a supported aria-errormessage technique';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'aria-errormessage value' + (it.data && it.data.length > 1 ? 's' : '') + ' ';
+              var arr1 = it.data;
+              if (arr1) {
+                var value, i1 = -1, l1 = arr1.length - 1;
+                while (i1 < l1) {
+                  value = arr1[i1 += 1];
+                  out += ' `' + value;
+                }
+              }
+              out += '` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)';
+              return out;
             }
           }
         },
@@ -4474,12 +8056,47 @@
               var out = 'The multimedia element has a captions track';
               return out;
             },
-            fail: function anonymous(it) {
-              var out = 'The multimedia element does not have a captions track';
+            incomplete: function anonymous(it) {
+              var out = 'Check that captions is available for the element';
+              return out;
+            }
+          }
+        },
+        'autocomplete-valid': {
+          impact: 'serious',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'the autocomplete attribute is correctly formatted';
               return out;
             },
-            incomplete: function anonymous(it) {
-              var out = 'A captions track for this element could not be found';
+            fail: function anonymous(it) {
+              var out = 'the autocomplete attribute is incorrectly formatted';
+              return out;
+            }
+          }
+        },
+        'autocomplete-appropriate': {
+          impact: 'serious',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'the autocomplete value is on an appropriate element';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'the autocomplete value is inappropriate for this type of input';
+              return out;
+            }
+          }
+        },
+        'avoid-inline-spacing': {
+          impact: 'serious',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'No inline styles with \'!important\' that affect text spacing has been specified';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Remove \'!important\' from inline style' + (it.data && it.data.length > 1 ? 's' : '') + ' ' + it.data.join(', ') + ', as overriding this is not supported by most browsers';
               return out;
             }
           }
@@ -4497,37 +8114,6 @@
             }
           }
         },
-        'non-empty-if-present': {
-          impact: 'critical',
-          messages: {
-            pass: function anonymous(it) {
-              var out = 'Element ';
-              if (it.data) {
-                out += 'has a non-empty value attribute';
-              } else {
-                out += 'does not have a value attribute';
-              }
-              return out;
-            },
-            fail: function anonymous(it) {
-              var out = 'Element has a value attribute and the value attribute is empty';
-              return out;
-            }
-          }
-        },
-        'non-empty-value': {
-          impact: 'critical',
-          messages: {
-            pass: function anonymous(it) {
-              var out = 'Element has a non-empty value attribute';
-              return out;
-            },
-            fail: function anonymous(it) {
-              var out = 'Element has no value attribute or the value attribute is empty';
-              return out;
-            }
-          }
-        },
         'button-has-visible-text': {
           impact: 'critical',
           messages: {
@@ -4567,19 +8153,6 @@
             }
           }
         },
-        'focusable-no-name': {
-          impact: 'serious',
-          messages: {
-            pass: function anonymous(it) {
-              var out = 'Element is not in tab order or has accessible text';
-              return out;
-            },
-            fail: function anonymous(it) {
-              var out = 'Element is in tab order and does not have accessible text';
-              return out;
-            }
-          }
-        },
         'internal-link-present': {
           impact: 'serious',
           messages: {
@@ -4623,11 +8196,21 @@
           impact: 'critical',
           messages: {
             pass: function anonymous(it) {
-              var out = 'All elements with the name "' + it.data.name + '" reference the same element with aria-labelledby';
+              var out = 'Elements with the name "' + it.data.name + '" have both a shared label, and a unique label, referenced through aria-labelledby';
               return out;
             },
             fail: function anonymous(it) {
-              var out = 'All elements with the name "' + it.data.name + '" do not reference the same element with aria-labelledby';
+              var out = '';
+              var code = it.data && it.data.failureCode;
+              out += 'Elements with the name "' + it.data.name + '" do not all have ';
+              if (code === 'no-shared-label') {
+                out += 'a shared label';
+              } else if (code === 'no-unique-label') {
+                out += 'a unique label';
+              } else {
+                out += 'both a shared label, and a unique label';
+              }
+              out += ', referenced through aria-labelledby';
               return out;
             }
           }
@@ -4667,7 +8250,7 @@
               return out;
             },
             fail: function anonymous(it) {
-              var out = 'Element has insufficient color contrast of ' + it.data.contrastRatio + ' (foreground color: ' + it.data.fgColor + ', background color: ' + it.data.bgColor + ', font size: ' + it.data.fontSize + ', font weight: ' + it.data.fontWeight + ')';
+              var out = 'Element has insufficient color contrast of ' + it.data.contrastRatio + ' (foreground color: ' + it.data.fgColor + ', background color: ' + it.data.bgColor + ', font size: ' + it.data.fontSize + ', font weight: ' + it.data.fontWeight + '). Expected contrast ratio of ' + it.data.expectedContrastRatio;
               return out;
             },
             incomplete: {
@@ -4677,11 +8260,31 @@
               bgOverlap: 'Element\'s background color could not be determined because it is overlapped by another element',
               fgAlpha: 'Element\'s foreground color could not be determined because of alpha transparency',
               elmPartiallyObscured: 'Element\'s background color could not be determined because it\'s partially obscured by another element',
+              elmPartiallyObscuring: 'Element\'s background color could not be determined because it partially overlaps other elements',
+              outsideViewport: 'Element\'s background color could not be determined because it\'s outside the viewport',
               equalRatio: 'Element has a 1:1 contrast ratio with the background',
+              shortTextContent: 'Element content is too short to determine if it is actual text content',
               default: 'Unable to determine contrast ratio'
             }
           }
         },
+        'css-orientation-lock': {
+          impact: 'serious',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Display is operable, and orientation lock does not exist';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'CSS Orientation lock is applied, and makes display inoperable';
+              return out;
+            },
+            incomplete: function anonymous(it) {
+              var out = 'CSS Orientation lock cannot be determined';
+              return out;
+            }
+          }
+        },
         'structured-dlitems': {
           impact: 'serious',
           messages: {
@@ -4734,28 +8337,97 @@
             }
           }
         },
-        'duplicate-id': {
-          impact: 'moderate',
+        'duplicate-id-active': {
+          impact: 'serious',
           messages: {
             pass: function anonymous(it) {
-              var out = 'Document has no elements that share the same id attribute';
+              var out = 'Document has no active elements that share the same id attribute';
               return out;
             },
             fail: function anonymous(it) {
-              var out = 'Document has multiple elements with the same id attribute: ' + it.data;
+              var out = 'Document has active elements with the same id attribute: ' + it.data;
               return out;
             }
           }
         },
-        'has-visible-text': {
-          impact: 'minor',
+        'duplicate-id-aria': {
+          impact: 'critical',
           messages: {
             pass: function anonymous(it) {
-              var out = 'Element has text that is visible to screen readers';
+              var out = 'Document has no elements referenced with ARIA or labels that share the same id attribute';
               return out;
             },
             fail: function anonymous(it) {
-              var out = 'Element does not have text that is visible to screen readers';
+              var out = 'Document has multiple elements referenced with ARIA with the same id attribute: ' + it.data;
+              return out;
+            }
+          }
+        },
+        'duplicate-id': {
+          impact: 'minor',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Document has no static elements that share the same id attribute';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Document has multiple static elements with the same id attribute';
+              return out;
+            }
+          }
+        },
+        'has-widget-role': {
+          impact: 'minor',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Element has a widget role.';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Element does not have a widget role.';
+              return out;
+            }
+          }
+        },
+        'valid-scrollable-semantics': {
+          impact: 'minor',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Element has valid semantics for an element in the focus order.';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Element has invalid semantics for an element in the focus order.';
+              return out;
+            }
+          }
+        },
+        'multiple-label': {
+          impact: 'moderate',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Form field does not have multiple label elements';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Multiple label elements is not widely supported in assistive technologies';
+              return out;
+            }
+          }
+        },
+        'frame-tested': {
+          impact: 'critical',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'The iframe was tested with axe-core';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'The iframe could not be tested with axe-core';
+              return out;
+            },
+            incomplete: function anonymous(it) {
+              var out = 'The iframe still has to be tested with axe-core';
               return out;
             }
           }
@@ -4803,19 +8475,6 @@
             }
           }
         },
-        'href-no-hash': {
-          impact: 'moderate',
-          messages: {
-            pass: function anonymous(it) {
-              var out = 'Anchor does not have an href value of #';
-              return out;
-            },
-            fail: function anonymous(it) {
-              var out = 'Anchor has an href value of #';
-              return out;
-            }
-          }
-        },
         'has-lang': {
           impact: 'serious',
           messages: {
@@ -4842,6 +8501,19 @@
             }
           }
         },
+        'xml-lang-mismatch': {
+          impact: 'moderate',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Lang and xml:lang attributes have the same base language';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Lang and xml:lang attributes do not have the same base language';
+              return out;
+            }
+          }
+        },
         'has-alt': {
           impact: 'critical',
           messages: {
@@ -4855,6 +8527,19 @@
             }
           }
         },
+        'alt-space-value': {
+          impact: 'critical',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Element has a valid alt attribute value';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Element has an alt attribute containing only a space character, which is not ignored by all screen readers';
+              return out;
+            }
+          }
+        },
         'duplicate-img-label': {
           impact: 'minor',
           messages: {
@@ -4868,6 +8553,50 @@
             }
           }
         },
+        'non-empty-if-present': {
+          impact: 'critical',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Element ';
+              if (it.data) {
+                out += 'has a non-empty value attribute';
+              } else {
+                out += 'does not have a value attribute';
+              }
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Element has a value attribute and the value attribute is empty';
+              return out;
+            }
+          }
+        },
+        'non-empty-value': {
+          impact: 'critical',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Element has a non-empty value attribute';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Element has no value attribute or the value attribute is empty';
+              return out;
+            }
+          }
+        },
+        'label-content-name-mismatch': {
+          impact: 'serious',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Element contains visible text as part of it\'s accessible name';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Text inside the element is not included in the accessible name';
+              return out;
+            }
+          }
+        },
         'title-only': {
           impact: 'serious',
           messages: {
@@ -4920,15 +8649,93 @@
             }
           }
         },
-        'multiple-label': {
-          impact: 'serious',
+        'hidden-explicit-label': {
+          impact: 'critical',
           messages: {
             pass: function anonymous(it) {
-              var out = 'Form element does not have multiple <label> elements';
+              var out = 'Form element has a visible explicit <label>';
               return out;
             },
             fail: function anonymous(it) {
-              var out = 'Form element has multiple <label> elements';
+              var out = 'Form element has explicit <label> that is hidden';
+              return out;
+            }
+          }
+        },
+        'landmark-is-top-level': {
+          impact: 'moderate',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'The ' + it.data.role + ' landmark is at the top level.';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'The ' + it.data.role + ' landmark is contained in another landmark.';
+              return out;
+            }
+          }
+        },
+        'page-no-duplicate-banner': {
+          impact: 'moderate',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Document does not have more than one banner landmark';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Document has more than one banner landmark';
+              return out;
+            }
+          }
+        },
+        'page-no-duplicate-contentinfo': {
+          impact: 'moderate',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Document does not have more than one contentinfo landmark';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Document has more than one contentinfo landmark';
+              return out;
+            }
+          }
+        },
+        'page-has-main': {
+          impact: 'moderate',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Document has at least one main landmark';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Document does not have a main landmark';
+              return out;
+            }
+          }
+        },
+        'page-no-duplicate-main': {
+          impact: 'moderate',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Document does not have more than one main landmark';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Document has more than one main landmark';
+              return out;
+            }
+          }
+        },
+        'landmark-is-unique': {
+          impact: 'moderate',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Landmarks must have a unique role or role/label/title (i.e. accessible name) combination';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'The landmark must have a unique aria-label, aria-labelledby, or title to make landmarks distinguishable';
               return out;
             }
           }
@@ -4976,11 +8783,11 @@
           impact: 'serious',
           messages: {
             pass: function anonymous(it) {
-              var out = 'Links can be distinguished from surrounding text in a way that does not rely on color';
+              var out = 'Links can be distinguished from surrounding text in some way other than by color';
               return out;
             },
             fail: function anonymous(it) {
-              var out = 'Links can not be distinguished from surrounding text in a way that does not rely on color';
+              var out = 'Links need to be distinguished from surrounding text in some way other than by color';
               return out;
             },
             incomplete: {
@@ -4993,6 +8800,19 @@
             }
           }
         },
+        'focusable-no-name': {
+          impact: 'serious',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Element is not in tab order or has accessible text';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Element is in tab order and does not have accessible text';
+              return out;
+            }
+          }
+        },
         'only-listitems': {
           impact: 'serious',
           messages: {
@@ -5053,7 +8873,7 @@
               return out;
             },
             fail: function anonymous(it) {
-              var out = '<meta> tag disables zooming on mobile devices';
+              var out = '' + it.data + ' on <meta> tag disables zooming on mobile devices';
               return out;
             }
           }
@@ -5071,15 +8891,28 @@
             }
           }
         },
+        'page-has-heading-one': {
+          impact: 'moderate',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Page has at least one level-one heading';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Page must have a level-one heading';
+              return out;
+            }
+          }
+        },
         region: {
           impact: 'moderate',
           messages: {
             pass: function anonymous(it) {
-              var out = 'Content contained by ARIA landmark';
+              var out = 'All page content is contained by landmarks';
               return out;
             },
             fail: function anonymous(it) {
-              var out = 'Content not contained by an ARIA landmark';
+              var out = 'Some page content is not contained by landmarks';
               return out;
             }
           }
@@ -5110,6 +8943,32 @@
             }
           }
         },
+        'focusable-content': {
+          impact: 'moderate',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Element contains focusable elements';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Element should have focusable content';
+              return out;
+            }
+          }
+        },
+        'focusable-element': {
+          impact: 'moderate',
+          messages: {
+            pass: function anonymous(it) {
+              var out = 'Element is focusable';
+              return out;
+            },
+            fail: function anonymous(it) {
+              var out = 'Element should be focusable';
+              return out;
+            }
+          }
+        },
         exists: {
           impact: 'minor',
           messages: {
@@ -5127,11 +8986,15 @@
           impact: 'moderate',
           messages: {
             pass: function anonymous(it) {
-              var out = 'Valid skip link found';
+              var out = 'Skip link target exists';
+              return out;
+            },
+            incomplete: function anonymous(it) {
+              var out = 'Skip link target should become visible on activation';
               return out;
             },
             fail: function anonymous(it) {
-              var out = 'No valid skip link found';
+              var out = 'No skip link target';
               return out;
             }
           }
@@ -5225,12 +9088,8 @@
               var out = 'The multimedia element has an audio description track';
               return out;
             },
-            fail: function anonymous(it) {
-              var out = 'The multimedia element does not have an audio description track';
-              return out;
-            },
             incomplete: function anonymous(it) {
-              var out = 'An audio description track for this element could not be found';
+              var out = 'Check that audio description is available for the element';
               return out;
             }
           }
@@ -5267,7 +9126,7 @@
         }
       },
       incompleteFallbackMessage: function anonymous(it) {
-        var out = 'aXe couldn\'t tell the reason. Time to break out the element inspector!';
+        var out = 'axe couldn\'t tell the reason. Time to break out the element inspector!';
         return out;
       }
     },
@@ -5275,7 +9134,7 @@
       id: 'accesskeys',
       selector: '[accesskey]',
       excludeHidden: false,
-      tags: [ 'wcag2a', 'wcag211', 'cat.keyboard' ],
+      tags: [ 'best-practice', 'cat.keyboard' ],
       all: [],
       any: [],
       none: [ 'accesskeys' ]
@@ -5289,28 +9148,53 @@
       none: []
     }, {
       id: 'aria-allowed-attr',
-      matches: function matches(node, virtualNode) {
-        var role = node.getAttribute('role');
-        if (!role) {
-          role = axe.commons.aria.implicitRole(node);
-        }
-        var allowed = axe.commons.aria.allowedAttr(role);
-        if (role && allowed) {
-          var aria = /^aria-/;
-          if (node.hasAttributes()) {
-            var attrs = node.attributes;
-            for (var i = 0, l = attrs.length; i < l; i++) {
-              if (aria.test(attrs[i].name)) {
-                return true;
-              }
+      matches: function matches(node, virtualNode, context) {
+        var aria = /^aria-/;
+        if (node.hasAttributes()) {
+          var attrs = axe.utils.getNodeAttributes(node);
+          for (var i = 0, l = attrs.length; i < l; i++) {
+            if (aria.test(attrs[i].name)) {
+              return true;
             }
           }
         }
         return false;
       },
-      tags: [ 'cat.aria', 'wcag2a', 'wcag411', 'wcag412' ],
+      tags: [ 'cat.aria', 'wcag2a', 'wcag412' ],
       all: [],
       any: [ 'aria-allowed-attr' ],
+      none: [ 'aria-unsupported-attr' ]
+    }, {
+      id: 'aria-allowed-role',
+      excludeHidden: false,
+      selector: '[role]',
+      matches: function matches(node, virtualNode, context) {
+        return axe.commons.aria.getRole(node, {
+          noImplicit: true,
+          dpub: true,
+          fallback: true
+        }) !== null;
+      },
+      tags: [ 'cat.aria', 'best-practice' ],
+      all: [],
+      any: [ {
+        options: {
+          allowImplicit: true,
+          ignoredTags: []
+        },
+        id: 'aria-allowed-role'
+      } ],
+      none: []
+    }, {
+      id: 'aria-dpub-role-fallback',
+      selector: '[role]',
+      matches: function matches(node, virtualNode, context) {
+        var role = node.getAttribute('role');
+        return [ 'doc-backlink', 'doc-biblioentry', 'doc-biblioref', 'doc-cover', 'doc-endnote', 'doc-glossref', 'doc-noteref' ].includes(role);
+      },
+      tags: [ 'cat.aria', 'wcag2a', 'wcag131' ],
+      all: [ 'implicit-role-fallback' ],
+      any: [],
       none: []
     }, {
       id: 'aria-hidden-body',
@@ -5321,9 +9205,60 @@
       any: [ 'aria-hidden-body' ],
       none: []
     }, {
+      id: 'aria-hidden-focus',
+      selector: '[aria-hidden="true"]',
+      matches: function matches(node, virtualNode, context) {
+        var getComposedParent = axe.commons.dom.getComposedParent;
+        function shouldMatchElement(el) {
+          if (!el) {
+            return true;
+          }
+          if (el.getAttribute('aria-hidden') === 'true') {
+            return false;
+          }
+          return shouldMatchElement(getComposedParent(el));
+        }
+        return shouldMatchElement(getComposedParent(node));
+      },
+      excludeHidden: false,
+      tags: [ 'cat.name-role-value', 'wcag2a', 'wcag412', 'wcag131' ],
+      all: [ 'focusable-disabled', 'focusable-not-tabbable' ],
+      any: [],
+      none: []
+    }, {
+      id: 'aria-input-field-name',
+      selector: '[role="combobox"], [role="listbox"], [role="searchbox"], [role="slider"], [role="spinbutton"], [role="textbox"]',
+      matches: function matches(node, virtualNode, context) {
+        var aria = axe.commons.aria;
+        var nodeName = node.nodeName.toUpperCase();
+        var role = aria.getRole(node, {
+          noImplicit: true
+        });
+        if (nodeName === 'AREA' && !!node.getAttribute('href')) {
+          return false;
+        }
+        if ([ 'INPUT', 'SELECT', 'TEXTAREA' ].includes(nodeName)) {
+          return false;
+        }
+        if (nodeName === 'IMG' || role === 'img' && nodeName !== 'SVG') {
+          return false;
+        }
+        if (nodeName === 'BUTTON' || role === 'button') {
+          return false;
+        }
+        if (role === 'combobox' && axe.utils.querySelectorAll(virtualNode, 'input:not([type="hidden"])').length) {
+          return false;
+        }
+        return true;
+      },
+      tags: [ 'wcag2a', 'wcag412' ],
+      all: [],
+      any: [ 'aria-label', 'aria-labelledby', 'non-empty-title' ],
+      none: [ 'no-implicit-explicit-label' ]
+    }, {
       id: 'aria-required-attr',
       selector: '[role]',
-      tags: [ 'cat.aria', 'wcag2a', 'wcag411', 'wcag412' ],
+      tags: [ 'cat.aria', 'wcag2a', 'wcag412' ],
       all: [],
       any: [ 'aria-required-attr' ],
       none: []
@@ -5332,7 +9267,12 @@
       selector: '[role]',
       tags: [ 'cat.aria', 'wcag2a', 'wcag131' ],
       all: [],
-      any: [ 'aria-required-children' ],
+      any: [ {
+        options: {
+          reviewEmpty: [ 'doc-bibliography', 'doc-endnotes', 'grid', 'list', 'listbox', 'table', 'tablist', 'tree', 'treegrid', 'rowgroup' ]
+        },
+        id: 'aria-required-children'
+      } ],
       none: []
     }, {
       id: 'aria-required-parent',
@@ -5344,16 +9284,46 @@
     }, {
       id: 'aria-roles',
       selector: '[role]',
-      tags: [ 'cat.aria', 'wcag2a', 'wcag131', 'wcag411', 'wcag412' ],
+      tags: [ 'cat.aria', 'wcag2a', 'wcag412' ],
       all: [],
       any: [],
-      none: [ 'invalidrole', 'abstractrole' ]
+      none: [ 'invalidrole', 'abstractrole', 'unsupportedrole' ]
+    }, {
+      id: 'aria-toggle-field-name',
+      selector: '[role="checkbox"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="radio"], [role="switch"]',
+      matches: function matches(node, virtualNode, context) {
+        var aria = axe.commons.aria;
+        var nodeName = node.nodeName.toUpperCase();
+        var role = aria.getRole(node, {
+          noImplicit: true
+        });
+        if (nodeName === 'AREA' && !!node.getAttribute('href')) {
+          return false;
+        }
+        if ([ 'INPUT', 'SELECT', 'TEXTAREA' ].includes(nodeName)) {
+          return false;
+        }
+        if (nodeName === 'IMG' || role === 'img' && nodeName !== 'SVG') {
+          return false;
+        }
+        if (nodeName === 'BUTTON' || role === 'button') {
+          return false;
+        }
+        if (role === 'combobox' && axe.utils.querySelectorAll(virtualNode, 'input:not([type="hidden"])').length) {
+          return false;
+        }
+        return true;
+      },
+      tags: [ 'wcag2a', 'wcag412' ],
+      all: [],
+      any: [ 'aria-label', 'aria-labelledby', 'non-empty-title', 'has-visible-text' ],
+      none: [ 'no-implicit-explicit-label' ]
     }, {
       id: 'aria-valid-attr-value',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         var aria = /^aria-/;
         if (node.hasAttributes()) {
-          var attrs = node.attributes;
+          var attrs = axe.utils.getNodeAttributes(node);
           for (var i = 0, l = attrs.length; i < l; i++) {
             if (aria.test(attrs[i].name)) {
               return true;
@@ -5362,19 +9332,19 @@
         }
         return false;
       },
-      tags: [ 'cat.aria', 'wcag2a', 'wcag131', 'wcag411', 'wcag412' ],
-      all: [],
-      any: [ {
+      tags: [ 'cat.aria', 'wcag2a', 'wcag412' ],
+      all: [ {
         options: [],
         id: 'aria-valid-attr-value'
-      } ],
+      }, 'aria-errormessage' ],
+      any: [],
       none: []
     }, {
       id: 'aria-valid-attr',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         var aria = /^aria-/;
         if (node.hasAttributes()) {
-          var attrs = node.attributes;
+          var attrs = axe.utils.getNodeAttributes(node);
           for (var i = 0, l = attrs.length; i < l; i++) {
             if (aria.test(attrs[i].name)) {
               return true;
@@ -5383,7 +9353,7 @@
         }
         return false;
       },
-      tags: [ 'cat.aria', 'wcag2a', 'wcag411' ],
+      tags: [ 'cat.aria', 'wcag2a', 'wcag412' ],
       all: [],
       any: [ {
         options: [],
@@ -5393,12 +9363,57 @@
     }, {
       id: 'audio-caption',
       selector: 'audio',
+      enabled: false,
       excludeHidden: false,
-      tags: [ 'cat.time-and-media', 'wcag2a', 'wcag122', 'section508', 'section508.22.a' ],
+      tags: [ 'cat.time-and-media', 'wcag2a', 'wcag121', 'section508', 'section508.22.a' ],
       all: [],
       any: [],
       none: [ 'caption' ]
     }, {
+      id: 'autocomplete-valid',
+      matches: function matches(node, virtualNode, context) {
+        var _axe$commons = axe.commons, text = _axe$commons.text, aria = _axe$commons.aria, dom = _axe$commons.dom;
+        var autocomplete = virtualNode.attr('autocomplete');
+        if (!autocomplete || text.sanitize(autocomplete) === '') {
+          return false;
+        }
+        var nodeName = virtualNode.props.nodeName;
+        if ([ 'textarea', 'input', 'select' ].includes(nodeName) === false) {
+          return false;
+        }
+        var excludedInputTypes = [ 'submit', 'reset', 'button', 'hidden' ];
+        if (nodeName === 'input' && excludedInputTypes.includes(virtualNode.props.type)) {
+          return false;
+        }
+        var ariaDisabled = virtualNode.attr('aria-disabled') || 'false';
+        if (virtualNode.hasAttr('disabled') || ariaDisabled.toLowerCase() === 'true') {
+          return false;
+        }
+        var role = virtualNode.attr('role');
+        var tabIndex = virtualNode.attr('tabindex');
+        if (tabIndex === '-1' && role) {
+          var roleDef = aria.lookupTable.role[role];
+          if (roleDef === undefined || roleDef.type !== 'widget') {
+            return false;
+          }
+        }
+        if (tabIndex === '-1' && virtualNode.actualNode && !dom.isVisible(virtualNode.actualNode, false) && !dom.isVisible(virtualNode.actualNode, true)) {
+          return false;
+        }
+        return true;
+      },
+      tags: [ 'cat.forms', 'wcag21aa', 'wcag135' ],
+      all: [ 'autocomplete-valid', 'autocomplete-appropriate' ],
+      any: [],
+      none: []
+    }, {
+      id: 'avoid-inline-spacing',
+      selector: '[style]',
+      tags: [ 'wcag21aa', 'wcag1412' ],
+      all: [ 'avoid-inline-spacing' ],
+      any: [],
+      none: []
+    }, {
       id: 'blink',
       selector: 'blink',
       excludeHidden: false,
@@ -5408,16 +9423,16 @@
       none: [ 'is-on-screen' ]
     }, {
       id: 'button-name',
-      selector: 'button, [role="button"], input[type="button"], input[type="submit"], input[type="reset"]',
+      selector: 'button, [role="button"]',
       tags: [ 'cat.name-role-value', 'wcag2a', 'wcag412', 'section508', 'section508.22.a' ],
       all: [],
-      any: [ 'non-empty-if-present', 'non-empty-value', 'button-has-visible-text', 'aria-label', 'aria-labelledby', 'role-presentation', 'role-none' ],
-      none: [ 'focusable-no-name' ]
+      any: [ 'button-has-visible-text', 'aria-label', 'aria-labelledby', 'role-presentation', 'role-none', 'non-empty-title' ],
+      none: []
     }, {
       id: 'bypass',
       selector: 'html',
       pageLevel: true,
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         return !!node.querySelector('a[href]');
       },
       tags: [ 'cat.keyboard', 'wcag2a', 'wcag241', 'section508', 'section508.22.o' ],
@@ -5433,9 +9448,9 @@
       none: []
     }, {
       id: 'color-contrast',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         var nodeName = node.nodeName.toUpperCase(), nodeType = node.type;
-        if (node.getAttribute('aria-disabled') === 'true' || axe.commons.dom.findUp(node, '[aria-disabled="true"]')) {
+        if (node.getAttribute('aria-disabled') === 'true' || axe.commons.dom.findUpVirtual(virtualNode, '[aria-disabled="true"]')) {
           return false;
         }
         if (nodeName === 'INPUT') {
@@ -5450,37 +9465,39 @@
         if (nodeName === 'OPTION') {
           return false;
         }
-        if (nodeName === 'BUTTON' && node.disabled || axe.commons.dom.findUp(node, 'button[disabled]')) {
+        if (nodeName === 'BUTTON' && node.disabled || axe.commons.dom.findUpVirtual(virtualNode, 'button[disabled]')) {
           return false;
         }
-        if (nodeName === 'FIELDSET' && node.disabled || axe.commons.dom.findUp(node, 'fieldset[disabled]')) {
+        if (nodeName === 'FIELDSET' && node.disabled || axe.commons.dom.findUpVirtual(virtualNode, 'fieldset[disabled]')) {
           return false;
         }
-        var nodeParentLabel = axe.commons.dom.findUp(node, 'label');
+        var nodeParentLabel = axe.commons.dom.findUpVirtual(virtualNode, 'label');
         if (nodeName === 'LABEL' || nodeParentLabel) {
           var relevantNode = node;
+          var relevantVirtualNode = virtualNode;
           if (nodeParentLabel) {
             relevantNode = nodeParentLabel;
+            relevantVirtualNode = axe.utils.getNodeFromTree(nodeParentLabel);
           }
           var doc = axe.commons.dom.getRootNode(relevantNode);
           var candidate = relevantNode.htmlFor && doc.getElementById(relevantNode.htmlFor);
           if (candidate && candidate.disabled) {
             return false;
           }
-          var candidate = axe.utils.querySelectorAll(virtualNode, 'input:not([type="hidden"]):not([type="image"])' + ':not([type="button"]):not([type="submit"]):not([type="reset"]), select, textarea');
+          var candidate = axe.utils.querySelectorAll(relevantVirtualNode, 'input:not([type="hidden"]):not([type="image"])' + ':not([type="button"]):not([type="submit"]):not([type="reset"]), select, textarea');
           if (candidate.length && candidate[0].actualNode.disabled) {
             return false;
           }
         }
         if (node.getAttribute('id')) {
-          var id = axe.commons.utils.escapeSelector(node.getAttribute('id'));
+          var id = axe.utils.escapeSelector(node.getAttribute('id'));
           var _doc = axe.commons.dom.getRootNode(node);
           var candidate = _doc.querySelector('[aria-labelledby~=' + id + ']');
           if (candidate && candidate.disabled) {
             return false;
           }
         }
-        if (axe.commons.text.visible(virtualNode, false, true) === '') {
+        if (axe.commons.text.visibleVirtual(virtualNode, false, true) === '') {
           return false;
         }
         var range = document.createRange(), childNodes = virtualNode.children, length = childNodes.length, child, index;
@@ -5508,9 +9525,17 @@
       any: [ 'color-contrast' ],
       none: []
     }, {
+      id: 'css-orientation-lock',
+      selector: 'html',
+      tags: [ 'cat.structure', 'wcag134', 'wcag21aa', 'experimental' ],
+      all: [ 'css-orientation-lock' ],
+      any: [],
+      none: [],
+      preload: true
+    }, {
       id: 'definition-list',
       selector: 'dl',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         return !node.getAttribute('role');
       },
       tags: [ 'cat.structure', 'wcag2a', 'wcag131' ],
@@ -5520,7 +9545,7 @@
     }, {
       id: 'dlitem',
       selector: 'dd, dt',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         return !node.getAttribute('role');
       },
       tags: [ 'cat.structure', 'wcag2a', 'wcag131' ],
@@ -5530,7 +9555,7 @@
     }, {
       id: 'document-title',
       selector: 'html',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         return node.ownerDocument.defaultView.self === node.ownerDocument.defaultView.top;
       },
       tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag242' ],
@@ -5538,8 +9563,43 @@
       any: [ 'doc-has-title' ],
       none: []
     }, {
+      id: 'duplicate-id-active',
+      selector: '[id]',
+      matches: function matches(node, virtualNode, context) {
+        var _axe$commons2 = axe.commons, dom = _axe$commons2.dom, aria = _axe$commons2.aria;
+        var id = node.getAttribute('id').trim();
+        var idSelector = '*[id="'.concat(axe.utils.escapeSelector(id), '"]');
+        var idMatchingElms = Array.from(dom.getRootNode(node).querySelectorAll(idSelector));
+        return idMatchingElms.some(dom.isFocusable) && !aria.isAccessibleRef(node);
+      },
+      excludeHidden: false,
+      tags: [ 'cat.parsing', 'wcag2a', 'wcag411' ],
+      all: [],
+      any: [ 'duplicate-id-active' ],
+      none: []
+    }, {
+      id: 'duplicate-id-aria',
+      selector: '[id]',
+      matches: function matches(node, virtualNode, context) {
+        return axe.commons.aria.isAccessibleRef(node);
+      },
+      excludeHidden: false,
+      tags: [ 'cat.parsing', 'wcag2a', 'wcag411' ],
+      all: [],
+      any: [ 'duplicate-id-aria' ],
+      none: []
+    }, {
       id: 'duplicate-id',
       selector: '[id]',
+      matches: function matches(node, virtualNode, context) {
+        var _axe$commons3 = axe.commons, dom = _axe$commons3.dom, aria = _axe$commons3.aria;
+        var id = node.getAttribute('id').trim();
+        var idSelector = '*[id="'.concat(axe.utils.escapeSelector(id), '"]');
+        var idMatchingElms = Array.from(dom.getRootNode(node).querySelectorAll(idSelector));
+        return idMatchingElms.every(function(elm) {
+          return !dom.isFocusable(elm);
+        }) && !aria.isAccessibleRef(node);
+      },
       excludeHidden: false,
       tags: [ 'cat.parsing', 'wcag2a', 'wcag411' ],
       all: [],
@@ -5548,15 +9608,67 @@
     }, {
       id: 'empty-heading',
       selector: 'h1, h2, h3, h4, h5, h6, [role="heading"]',
-      enabled: true,
+      matches: function matches(node, virtualNode, context) {
+        var explicitRoles;
+        if (node.hasAttribute('role')) {
+          explicitRoles = node.getAttribute('role').split(/\s+/i).filter(axe.commons.aria.isValidRole);
+        }
+        if (explicitRoles && explicitRoles.length > 0) {
+          return explicitRoles.includes('heading');
+        } else {
+          return axe.commons.aria.implicitRole(node) === 'heading';
+        }
+      },
       tags: [ 'cat.name-role-value', 'best-practice' ],
       all: [],
-      any: [ 'has-visible-text', 'role-presentation', 'role-none' ],
+      any: [ 'has-visible-text' ],
+      none: []
+    }, {
+      id: 'focus-order-semantics',
+      selector: 'div, h1, h2, h3, h4, h5, h6, [role=heading], p, span',
+      matches: function matches(node, virtualNode, context) {
+        return axe.commons.dom.insertedIntoFocusOrder(node);
+      },
+      tags: [ 'cat.keyboard', 'best-practice', 'experimental' ],
+      all: [],
+      any: [ {
+        options: [],
+        id: 'has-widget-role'
+      }, {
+        options: [],
+        id: 'valid-scrollable-semantics'
+      } ],
+      none: []
+    }, {
+      id: 'form-field-multiple-labels',
+      selector: 'input, select, textarea',
+      matches: function matches(node, virtualNode, context) {
+        if (node.nodeName.toLowerCase() !== 'input' || node.hasAttribute('type') === false) {
+          return true;
+        }
+        var type = node.getAttribute('type').toLowerCase();
+        return [ 'hidden', 'image', 'button', 'submit', 'reset' ].includes(type) === false;
+      },
+      tags: [ 'cat.forms', 'wcag2a', 'wcag332' ],
+      all: [],
+      any: [],
+      none: [ 'multiple-label' ]
+    }, {
+      id: 'frame-tested',
+      selector: 'frame, iframe',
+      tags: [ 'cat.structure', 'review-item', 'best-practice' ],
+      all: [ {
+        options: {
+          isViolation: false
+        },
+        id: 'frame-tested'
+      } ],
+      any: [],
       none: []
     }, {
       id: 'frame-title-unique',
       selector: 'frame[title], iframe[title]',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         var title = node.getAttribute('title');
         return !!(title ? axe.commons.text.sanitize(title).trim() : '');
       },
@@ -5567,14 +9679,24 @@
     }, {
       id: 'frame-title',
       selector: 'frame, iframe',
-      tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag241', 'section508', 'section508.22.i' ],
+      tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag241', 'wcag412', 'section508', 'section508.22.i' ],
       all: [],
       any: [ 'aria-label', 'aria-labelledby', 'non-empty-title', 'role-presentation', 'role-none' ],
       none: []
     }, {
       id: 'heading-order',
-      selector: 'h1,h2,h3,h4,h5,h6,[role=heading]',
-      enabled: false,
+      selector: 'h1, h2, h3, h4, h5, h6, [role=heading]',
+      matches: function matches(node, virtualNode, context) {
+        var explicitRoles;
+        if (node.hasAttribute('role')) {
+          explicitRoles = node.getAttribute('role').split(/\s+/i).filter(axe.commons.aria.isValidRole);
+        }
+        if (explicitRoles && explicitRoles.length > 0) {
+          return explicitRoles.includes('heading');
+        } else {
+          return axe.commons.aria.implicitRole(node) === 'heading';
+        }
+      },
       tags: [ 'cat.semantics', 'best-practice' ],
       all: [],
       any: [ 'heading-order' ],
@@ -5583,48 +9705,62 @@
       id: 'hidden-content',
       selector: '*',
       excludeHidden: false,
-      tags: [ 'experimental', 'review-item' ],
+      tags: [ 'cat.structure', 'experimental', 'review-item', 'best-practice' ],
       all: [],
       any: [ 'hidden-content' ],
-      none: [],
-      enabled: false
-    }, {
-      id: 'href-no-hash',
-      selector: 'a[href]',
-      enabled: false,
-      tags: [ 'cat.semantics', 'best-practice' ],
-      all: [],
-      any: [ 'href-no-hash' ],
       none: []
     }, {
       id: 'html-has-lang',
       selector: 'html',
+      matches: function matches(node, virtualNode, context) {
+        return node.ownerDocument.defaultView.self === node.ownerDocument.defaultView.top;
+      },
       tags: [ 'cat.language', 'wcag2a', 'wcag311' ],
       all: [],
       any: [ 'has-lang' ],
       none: []
     }, {
       id: 'html-lang-valid',
-      selector: 'html[lang]',
+      selector: 'html[lang], html[xml\\:lang]',
       tags: [ 'cat.language', 'wcag2a', 'wcag311' ],
       all: [],
       any: [],
       none: [ 'valid-lang' ]
     }, {
+      id: 'html-xml-lang-mismatch',
+      selector: 'html[lang][xml\\:lang]',
+      matches: function matches(node, virtualNode, context) {
+        var getBaseLang = axe.utils.getBaseLang;
+        var primaryLangValue = getBaseLang(node.getAttribute('lang'));
+        var primaryXmlLangValue = getBaseLang(node.getAttribute('xml:lang'));
+        return axe.utils.validLangs().includes(primaryLangValue) && axe.utils.validLangs().includes(primaryXmlLangValue);
+      },
+      tags: [ 'cat.language', 'wcag2a', 'wcag311' ],
+      all: [ 'xml-lang-mismatch' ],
+      any: [],
+      none: []
+    }, {
       id: 'image-alt',
-      selector: 'img, [role=\'img\']',
+      selector: 'img',
       tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ],
       all: [],
       any: [ 'has-alt', 'aria-label', 'aria-labelledby', 'non-empty-title', 'role-presentation', 'role-none' ],
-      none: []
+      none: [ 'alt-space-value' ]
     }, {
       id: 'image-redundant-alt',
-      selector: 'button, [role="button"], a[href], p, li, td, th',
+      selector: 'img',
       tags: [ 'cat.text-alternatives', 'best-practice' ],
       all: [],
       any: [],
       none: [ 'duplicate-img-label' ]
     }, {
+      id: 'input-button-name',
+      selector: 'input[type="button"], input[type="submit"], input[type="reset"]',
+      tags: [ 'cat.name-role-value', 'wcag2a', 'wcag412', 'section508', 'section508.22.a' ],
+      all: [],
+      any: [ 'non-empty-if-present', 'non-empty-value', 'aria-label', 'aria-labelledby', 'role-presentation', 'role-none', 'non-empty-title' ],
+      none: []
+    }, {
       id: 'input-image-alt',
       selector: 'input[type="image"]',
       tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ],
@@ -5632,19 +9768,43 @@
       any: [ 'non-empty-alt', 'aria-label', 'aria-labelledby', 'non-empty-title' ],
       none: []
     }, {
-      id: 'label-title-only',
-      selector: 'input, select, textarea',
-      matches: function matches(node, virtualNode) {
-        if (node.nodeName.toLowerCase() !== 'input') {
-          return true;
+      id: 'label-content-name-mismatch',
+      matches: function matches(node, virtualNode, context) {
+        var _axe$commons4 = axe.commons, aria = _axe$commons4.aria, text = _axe$commons4.text;
+        var role = aria.getRole(node);
+        if (!role) {
+          return false;
         }
-        var t = node.getAttribute('type').toLowerCase();
-        if (t === 'hidden' || t === 'image' || t === 'button' || t === 'submit' || t === 'reset') {
+        var isWidgetType = aria.lookupTable.rolesOfType.widget.includes(role);
+        if (!isWidgetType) {
+          return false;
+        }
+        var rolesWithNameFromContents = aria.getRolesWithNameFromContents();
+        if (!rolesWithNameFromContents.includes(role)) {
+          return false;
+        }
+        if (!text.sanitize(aria.arialabelText(node)) && !text.sanitize(aria.arialabelledbyText(node))) {
+          return false;
+        }
+        if (!text.sanitize(text.visibleVirtual(virtualNode))) {
           return false;
         }
         return true;
       },
-      enabled: false,
+      tags: [ 'wcag21a', 'wcag253', 'experimental' ],
+      all: [],
+      any: [ 'label-content-name-mismatch' ],
+      none: []
+    }, {
+      id: 'label-title-only',
+      selector: 'input, select, textarea',
+      matches: function matches(node, virtualNode, context) {
+        if (node.nodeName.toLowerCase() !== 'input' || node.hasAttribute('type') === false) {
+          return true;
+        }
+        var type = node.getAttribute('type').toLowerCase();
+        return [ 'hidden', 'image', 'button', 'submit', 'reset' ].includes(type) === false;
+      },
       tags: [ 'cat.forms', 'best-practice' ],
       all: [],
       any: [],
@@ -5652,25 +9812,133 @@
     }, {
       id: 'label',
       selector: 'input, select, textarea',
-      matches: function matches(node, virtualNode) {
-        if (node.nodeName.toLowerCase() !== 'input') {
+      matches: function matches(node, virtualNode, context) {
+        if (node.nodeName.toLowerCase() !== 'input' || node.hasAttribute('type') === false) {
           return true;
         }
-        var t = node.getAttribute('type').toLowerCase();
-        if (t === 'hidden' || t === 'image' || t === 'button' || t === 'submit' || t === 'reset') {
-          return false;
-        }
-        return true;
+        var type = node.getAttribute('type').toLowerCase();
+        return [ 'hidden', 'image', 'button', 'submit', 'reset' ].includes(type) === false;
       },
       tags: [ 'cat.forms', 'wcag2a', 'wcag332', 'wcag131', 'section508', 'section508.22.n' ],
       all: [],
       any: [ 'aria-label', 'aria-labelledby', 'implicit-label', 'explicit-label', 'non-empty-title' ],
-      none: [ 'help-same-as-label', 'multiple-label' ]
+      none: [ 'help-same-as-label', 'hidden-explicit-label' ]
+    }, {
+      id: 'landmark-banner-is-top-level',
+      selector: 'header:not([role]), [role=banner]',
+      matches: function matches(node, virtualNode, context) {
+        var nativeScopeFilter = 'article, aside, main, nav, section';
+        return node.hasAttribute('role') || !axe.commons.dom.findUpVirtual(virtualNode, nativeScopeFilter);
+      },
+      tags: [ 'cat.semantics', 'best-practice' ],
+      all: [],
+      any: [ 'landmark-is-top-level' ],
+      none: []
+    }, {
+      id: 'landmark-complementary-is-top-level',
+      selector: 'aside:not([role]), [role=complementary]',
+      tags: [ 'cat.semantics', 'best-practice' ],
+      all: [],
+      any: [ 'landmark-is-top-level' ],
+      none: []
+    }, {
+      id: 'landmark-contentinfo-is-top-level',
+      selector: 'footer:not([role]), [role=contentinfo]',
+      matches: function matches(node, virtualNode, context) {
+        var nativeScopeFilter = 'article, aside, main, nav, section';
+        return node.hasAttribute('role') || !axe.commons.dom.findUpVirtual(virtualNode, nativeScopeFilter);
+      },
+      tags: [ 'cat.semantics', 'best-practice' ],
+      all: [],
+      any: [ 'landmark-is-top-level' ],
+      none: []
+    }, {
+      id: 'landmark-main-is-top-level',
+      selector: 'main:not([role]), [role=main]',
+      tags: [ 'cat.semantics', 'best-practice' ],
+      all: [],
+      any: [ 'landmark-is-top-level' ],
+      none: []
+    }, {
+      id: 'landmark-no-duplicate-banner',
+      selector: 'html',
+      tags: [ 'cat.semantics', 'best-practice' ],
+      all: [],
+      any: [ {
+        options: {
+          selector: 'header:not([role]), [role=banner]',
+          nativeScopeFilter: 'article, aside, main, nav, section'
+        },
+        id: 'page-no-duplicate-banner'
+      } ],
+      none: []
+    }, {
+      id: 'landmark-no-duplicate-contentinfo',
+      selector: 'html',
+      tags: [ 'cat.semantics', 'best-practice' ],
+      all: [],
+      any: [ {
+        options: {
+          selector: 'footer:not([role]), [role=contentinfo]',
+          nativeScopeFilter: 'article, aside, main, nav, section'
+        },
+        id: 'page-no-duplicate-contentinfo'
+      } ],
+      none: []
+    }, {
+      id: 'landmark-one-main',
+      selector: 'html',
+      tags: [ 'cat.semantics', 'best-practice' ],
+      all: [ {
+        options: {
+          selector: 'main:not([role]), [role=\'main\']'
+        },
+        id: 'page-has-main'
+      }, {
+        options: {
+          selector: 'main:not([role]), [role=\'main\']'
+        },
+        id: 'page-no-duplicate-main'
+      } ],
+      any: [],
+      none: []
+    }, {
+      id: 'landmark-unique',
+      selector: '[role=banner], [role=complementary], [role=contentinfo], [role=main], [role=navigation], [role=region], [role=search], [role=form], form, footer, header, aside, main, nav, section',
+      tags: [ 'cat.semantics', 'best-practice' ],
+      matches: function matches(node, virtualNode, context) {
+        var excludedParentsForHeaderFooterLandmarks = [ 'article', 'aside', 'main', 'nav', 'section' ].join(',');
+        function isHeaderFooterLandmark(headerFooterElement) {
+          return !axe.commons.dom.findUpVirtual(headerFooterElement, excludedParentsForHeaderFooterLandmarks);
+        }
+        function isLandmarkVirtual(virtualNode) {
+          var actualNode = virtualNode.actualNode;
+          var landmarkRoles = axe.commons.aria.getRolesByType('landmark');
+          var role = axe.commons.aria.getRole(actualNode);
+          if (!role) {
+            return false;
+          }
+          var nodeName = actualNode.nodeName.toUpperCase();
+          if (nodeName === 'HEADER' || nodeName === 'FOOTER') {
+            return isHeaderFooterLandmark(virtualNode);
+          }
+          if (nodeName === 'SECTION' || nodeName === 'FORM') {
+            var accessibleText = axe.commons.text.accessibleTextVirtual(virtualNode);
+            return !!accessibleText;
+          }
+          return landmarkRoles.indexOf(role) >= 0 || role === 'region';
+        }
+        return isLandmarkVirtual(virtualNode) && axe.commons.dom.isVisible(node, true);
+      },
+      all: [],
+      any: [ 'landmark-is-unique' ],
+      none: []
     }, {
       id: 'layout-table',
       selector: 'table',
-      matches: function matches(node, virtualNode) {
-        return !axe.commons.table.isDataTable(node);
+      matches: function matches(node, virtualNode, context) {
+        var role = (node.getAttribute('role') || '').toLowerCase();
+        return !((role === 'presentation' || role === 'none') && !axe.commons.dom.isFocusable(node)) && !axe.commons.table.isDataTable(node);
       },
       tags: [ 'cat.semantics', 'wcag2a', 'wcag131' ],
       all: [],
@@ -5678,8 +9946,8 @@
       none: [ 'has-th', 'has-caption', 'has-summary' ]
     }, {
       id: 'link-in-text-block',
-      selector: 'a[href], *[role=link]',
-      matches: function matches(node, virtualNode) {
+      selector: 'a[href], [role=link]',
+      matches: function matches(node, virtualNode, context) {
         var text = axe.commons.text.sanitize(node.textContent);
         var role = node.getAttribute('role');
         if (role && role !== 'link') {
@@ -5701,17 +9969,17 @@
     }, {
       id: 'link-name',
       selector: 'a[href], [role=link][href]',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         return node.getAttribute('role') !== 'button';
       },
-      tags: [ 'cat.name-role-value', 'wcag2a', 'wcag111', 'wcag412', 'wcag244', 'section508', 'section508.22.a' ],
+      tags: [ 'cat.name-role-value', 'wcag2a', 'wcag412', 'wcag244', 'section508', 'section508.22.a' ],
       all: [],
       any: [ 'has-visible-text', 'aria-label', 'aria-labelledby', 'role-presentation', 'role-none' ],
       none: [ 'focusable-no-name' ]
     }, {
       id: 'list',
       selector: 'ul, ol',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         return !node.getAttribute('role');
       },
       tags: [ 'cat.structure', 'wcag2a', 'wcag131' ],
@@ -5721,7 +9989,7 @@
     }, {
       id: 'listitem',
       selector: 'li',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         return !node.getAttribute('role');
       },
       tags: [ 'cat.structure', 'wcag2a', 'wcag131' ],
@@ -5776,12 +10044,12 @@
       selector: 'object',
       tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ],
       all: [],
-      any: [ 'has-visible-text', 'aria-label', 'aria-labelledby', 'non-empty-title' ],
+      any: [ 'has-visible-text', 'aria-label', 'aria-labelledby', 'non-empty-title', 'role-presentation', 'role-none' ],
       none: []
     }, {
       id: 'p-as-heading',
       selector: 'p',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         var children = Array.from(node.parentNode.childNodes);
         var nodeText = node.textContent.trim();
         var isSentence = /[.!?:;](?![.!?:;])/g;
@@ -5814,6 +10082,18 @@
       any: [],
       none: []
     }, {
+      id: 'page-has-heading-one',
+      selector: 'html',
+      tags: [ 'cat.semantics', 'best-practice' ],
+      all: [ {
+        options: {
+          selector: 'h1:not([role]), [role="heading"][aria-level="1"]'
+        },
+        id: 'page-has-heading-one'
+      } ],
+      any: [],
+      none: []
+    }, {
       id: 'radiogroup',
       selector: 'input[type=radio][name]',
       tags: [ 'cat.forms', 'best-practice' ],
@@ -5824,20 +10104,46 @@
       id: 'region',
       selector: 'html',
       pageLevel: true,
-      enabled: false,
       tags: [ 'cat.keyboard', 'best-practice' ],
       all: [],
       any: [ 'region' ],
       none: []
     }, {
+      id: 'role-img-alt',
+      selector: '[role=\'img\']:not(svg):not(img):not(area):not(input):not(object)',
+      tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag111', 'section508', 'section508.22.a' ],
+      all: [],
+      any: [ 'aria-label', 'aria-labelledby', 'non-empty-title' ],
+      none: []
+    }, {
       id: 'scope-attr-valid',
       selector: 'td[scope], th[scope]',
-      enabled: true,
       tags: [ 'cat.tables', 'best-practice' ],
       all: [ 'html5-scope', 'scope-value' ],
       any: [],
       none: []
     }, {
+      id: 'scrollable-region-focusable',
+      matches: function matches(node, virtualNode, context) {
+        var querySelectorAll = axe.utils.querySelectorAll;
+        var hasContentVirtual = axe.commons.dom.hasContentVirtual;
+        if (!!axe.utils.getScroll(node, 13) === false) {
+          return false;
+        }
+        var nodeAndDescendents = querySelectorAll(virtualNode, '*');
+        var hasVisibleChildren = nodeAndDescendents.some(function(elm) {
+          return hasContentVirtual(elm, true, true);
+        });
+        if (!hasVisibleChildren) {
+          return false;
+        }
+        return true;
+      },
+      tags: [ 'wcag2a', 'wcag211' ],
+      all: [],
+      any: [ 'focusable-content', 'focusable-element' ],
+      none: []
+    }, {
       id: 'server-side-image-map',
       selector: 'img[ismap]',
       tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag211', 'section508', 'section508.22.f' ],
@@ -5846,9 +10152,10 @@
       none: [ 'exists' ]
     }, {
       id: 'skip-link',
-      selector: 'a[href]',
-      pageLevel: true,
-      enabled: false,
+      selector: 'a[href^="#"], a[href^="/#"]',
+      matches: function matches(node, virtualNode, context) {
+        return axe.commons.dom.isSkipLink(node);
+      },
       tags: [ 'cat.keyboard', 'best-practice' ],
       all: [],
       any: [ 'skip-link' ],
@@ -5870,7 +10177,7 @@
     }, {
       id: 'table-fake-caption',
       selector: 'table',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         return axe.commons.table.isDataTable(node);
       },
       tags: [ 'cat.tables', 'experimental', 'wcag2a', 'wcag131', 'section508', 'section508.22.g' ],
@@ -5880,7 +10187,7 @@
     }, {
       id: 'td-has-header',
       selector: 'table',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         if (axe.commons.table.isDataTable(node)) {
           var tableArray = axe.commons.table.toArray(node);
           return tableArray.length >= 3 && tableArray[0].length >= 3 && tableArray[1].length >= 3 && tableArray[2].length >= 3;
@@ -5901,7 +10208,7 @@
     }, {
       id: 'th-has-data-cells',
       selector: 'table',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         return axe.commons.table.isDataTable(node);
       },
       tags: [ 'cat.tables', 'wcag2a', 'wcag131', 'section508', 'section508.22.g' ],
@@ -5911,7 +10218,7 @@
     }, {
       id: 'valid-lang',
       selector: '[lang], [xml\\:lang]',
-      matches: function matches(node, virtualNode) {
+      matches: function matches(node, virtualNode, context) {
         return node.nodeName.toLowerCase() !== 'html';
       },
       tags: [ 'cat.language', 'wcag2aa', 'wcag312' ],
@@ -5922,7 +10229,7 @@
       id: 'video-caption',
       selector: 'video',
       excludeHidden: false,
-      tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag122', 'wcag123', 'section508', 'section508.22.a' ],
+      tags: [ 'cat.text-alternatives', 'wcag2a', 'wcag122', 'section508', 'section508.22.a' ],
       all: [],
       any: [],
       none: [ 'caption' ]
@@ -5937,23 +10244,27 @@
     } ],
     checks: [ {
       id: 'abstractrole',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         return axe.commons.aria.getRoleType(node.getAttribute('role')) === 'abstract';
       }
     }, {
       id: 'aria-allowed-attr',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        options = options || {};
         var invalid = [];
-        var attr, attrName, allowed, role = node.getAttribute('role'), attrs = node.attributes;
+        var attr, attrName, allowed, role = node.getAttribute('role'), attrs = axe.utils.getNodeAttributes(node);
         if (!role) {
           role = axe.commons.aria.implicitRole(node);
         }
         allowed = axe.commons.aria.allowedAttr(role);
+        if (Array.isArray(options[role])) {
+          allowed = axe.utils.uniqueArray(options[role].concat(allowed));
+        }
         if (role && allowed) {
           for (var i = 0, l = attrs.length; i < l; i++) {
             attr = attrs[i];
             attrName = attr.name;
-            if (axe.commons.aria.validateAttr(attrName) && allowed.indexOf(attrName) === -1) {
+            if (axe.commons.aria.validateAttr(attrName) && !allowed.includes(attrName)) {
               invalid.push(attrName + '="' + attr.nodeValue + '"');
             }
           }
@@ -5965,25 +10276,130 @@
         return true;
       }
     }, {
+      id: 'aria-allowed-role',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var dom = axe.commons.dom;
+        var _ref = options || {}, _ref$allowImplicit = _ref.allowImplicit, allowImplicit = _ref$allowImplicit === void 0 ? true : _ref$allowImplicit, _ref$ignoredTags = _ref.ignoredTags, ignoredTags = _ref$ignoredTags === void 0 ? [] : _ref$ignoredTags;
+        var tagName = node.nodeName.toUpperCase();
+        if (ignoredTags.map(function(t) {
+          return t.toUpperCase();
+        }).includes(tagName)) {
+          return true;
+        }
+        var unallowedRoles = axe.commons.aria.getElementUnallowedRoles(node, allowImplicit);
+        if (unallowedRoles.length) {
+          this.data(unallowedRoles);
+          if (!dom.isVisible(node, true)) {
+            return undefined;
+          }
+          return false;
+        }
+        return true;
+      },
+      options: {
+        allowImplicit: true,
+        ignoredTags: []
+      }
+    }, {
       id: 'aria-hidden-body',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         return node.getAttribute('aria-hidden') !== 'true';
       }
     }, {
+      id: 'aria-errormessage',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var _axe$commons5 = axe.commons, aria = _axe$commons5.aria, dom = _axe$commons5.dom;
+        options = Array.isArray(options) ? options : [];
+        var attr = node.getAttribute('aria-errormessage');
+        var hasAttr = node.hasAttribute('aria-errormessage');
+        var doc = dom.getRootNode(node);
+        function validateAttrValue(attr) {
+          if (attr.trim() === '') {
+            return aria.lookupTable.attributes['aria-errormessage'].allowEmpty;
+          }
+          var idref = attr && doc.getElementById(attr);
+          if (idref) {
+            return idref.getAttribute('role') === 'alert' || idref.getAttribute('aria-live') === 'assertive' || axe.utils.tokenList(node.getAttribute('aria-describedby') || '').indexOf(attr) > -1;
+          }
+        }
+        if (options.indexOf(attr) === -1 && hasAttr) {
+          if (!validateAttrValue(attr)) {
+            this.data(axe.utils.tokenList(attr));
+            return false;
+          }
+        }
+        return true;
+      }
+    }, {
+      id: 'has-widget-role',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var role = node.getAttribute('role');
+        if (role === null) {
+          return false;
+        }
+        var roleType = axe.commons.aria.getRoleType(role);
+        return roleType === 'widget' || roleType === 'composite';
+      },
+      options: []
+    }, {
+      id: 'implicit-role-fallback',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var role = node.getAttribute('role');
+        if (role === null || !axe.commons.aria.isValidRole(role)) {
+          return true;
+        }
+        var roleType = axe.commons.aria.getRoleType(role);
+        return axe.commons.aria.implicitRole(node) === roleType;
+      }
+    }, {
       id: 'invalidrole',
-      evaluate: function evaluate(node, options, virtualNode) {
-        return !axe.commons.aria.isValidRole(node.getAttribute('role'));
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        return !axe.commons.aria.isValidRole(node.getAttribute('role'), {
+          allowAbstract: true
+        });
+      }
+    }, {
+      id: 'no-implicit-explicit-label',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var _axe$commons6 = axe.commons, aria = _axe$commons6.aria, text = _axe$commons6.text;
+        var role = aria.getRole(node, {
+          noImplicit: true
+        });
+        this.data(role);
+        var labelText = text.sanitize(text.labelText(virtualNode)).toLowerCase();
+        var accText = text.sanitize(text.accessibleText(node)).toLowerCase();
+        if (!accText && !labelText) {
+          return false;
+        }
+        if (!accText && labelText) {
+          return undefined;
+        }
+        if (!accText.includes(labelText)) {
+          return undefined;
+        }
+        return false;
       }
     }, {
       id: 'aria-required-attr',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        options = options || {};
         var missing = [];
+        var _axe$commons$forms = axe.commons.forms, isNativeTextbox = _axe$commons$forms.isNativeTextbox, isNativeSelect = _axe$commons$forms.isNativeSelect, isAriaTextbox = _axe$commons$forms.isAriaTextbox, isAriaListbox = _axe$commons$forms.isAriaListbox, isAriaCombobox = _axe$commons$forms.isAriaCombobox, isAriaRange = _axe$commons$forms.isAriaRange;
+        var preChecks = {
+          'aria-valuenow': function ariaValuenow() {
+            return !(isNativeTextbox(node) || isNativeSelect(node) || isAriaTextbox(node) || isAriaListbox(node) || isAriaCombobox(node) || isAriaRange(node) && node.hasAttribute('aria-valuenow'));
+          }
+        };
         if (node.hasAttributes()) {
-          var attr, role = node.getAttribute('role'), required = axe.commons.aria.requiredAttr(role);
+          var role = node.getAttribute('role');
+          var required = axe.commons.aria.requiredAttr(role);
+          if (Array.isArray(options[role])) {
+            required = axe.utils.uniqueArray(options[role], required);
+          }
           if (role && required) {
             for (var i = 0, l = required.length; i < l; i++) {
-              attr = required[i];
-              if (!node.getAttribute(attr)) {
+              var attr = required[i];
+              if (!node.getAttribute(attr) && (preChecks[attr] ? preChecks[attr]() : true)) {
                 missing.push(attr);
               }
             }
@@ -5997,8 +10413,12 @@
       }
     }, {
       id: 'aria-required-children',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var requiredOwned = axe.commons.aria.requiredOwned, implicitNodes = axe.commons.aria.implicitNodes, matchesSelector = axe.commons.utils.matchesSelector, idrefs = axe.commons.dom.idrefs;
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var requiredOwned = axe.commons.aria.requiredOwned;
+        var implicitNodes = axe.commons.aria.implicitNodes;
+        var matchesSelector = axe.utils.matchesSelector;
+        var idrefs = axe.commons.dom.idrefs;
+        var reviewEmpty = options && Array.isArray(options.reviewEmpty) ? options.reviewEmpty : [];
         function owns(node, virtualTree, role, ariaOwned) {
           if (node === null) {
             return false;
@@ -6016,27 +10436,39 @@
             if (nodes[index] === null) {
               continue;
             }
-            var virtualTree = axe.utils.getNodeFromTree(axe._tree[0], nodes[index]);
+            var virtualTree = axe.utils.getNodeFromTree(nodes[index]);
             if (owns(nodes[index], virtualTree, role, true)) {
               return true;
             }
           }
           return false;
         }
-        function missingRequiredChildren(node, childRoles, all) {
-          var i, l = childRoles.length, missing = [], ownedElements = idrefs(node, 'aria-owns');
-          for (i = 0; i < l; i++) {
-            var r = childRoles[i];
-            if (owns(node, virtualNode, r) || ariaOwns(ownedElements, r)) {
+        function missingRequiredChildren(node, childRoles, all, role) {
+          var index, length = childRoles.length, missing = [], ownedElements = idrefs(node, 'aria-owns');
+          for (index = 0; index < length; index++) {
+            var childRole = childRoles[index];
+            if (owns(node, virtualNode, childRole) || ariaOwns(ownedElements, childRole)) {
               if (!all) {
                 return null;
               }
             } else {
               if (all) {
-                missing.push(r);
+                missing.push(childRole);
               }
             }
           }
+          if (role === 'combobox') {
+            var textboxIndex = missing.indexOf('textbox');
+            var textTypeInputs = [ 'text', 'search', 'email', 'url', 'tel' ];
+            if (textboxIndex >= 0 && node.nodeName.toUpperCase() === 'INPUT' && textTypeInputs.includes(node.type)) {
+              missing.splice(textboxIndex, 1);
+            }
+            var listboxIndex = missing.indexOf('listbox');
+            var expanded = node.getAttribute('aria-expanded');
+            if (listboxIndex >= 0 && (!expanded || expanded === 'false')) {
+              missing.splice(listboxIndex, 1);
+            }
+          }
           if (missing.length) {
             return missing;
           }
@@ -6056,22 +10488,29 @@
           var all = true;
           childRoles = required.all;
         }
-        var missing = missingRequiredChildren(node, childRoles, all);
+        var missing = missingRequiredChildren(node, childRoles, all, role);
         if (!missing) {
           return true;
         }
         this.data(missing);
-        return false;
+        if (reviewEmpty.includes(role) && node.children.length === 0 && idrefs(node, 'aria-owns').length === 0) {
+          return undefined;
+        } else {
+          return false;
+        }
+      },
+      options: {
+        reviewEmpty: [ 'doc-bibliography', 'doc-endnotes', 'grid', 'list', 'listbox', 'table', 'tablist', 'tree', 'treegrid', 'rowgroup' ]
       }
     }, {
       id: 'aria-required-parent',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         function getSelector(role) {
           var impliedNative = axe.commons.aria.implicitNodes(role) || [];
           return impliedNative.concat('[role="' + role + '"]').join(',');
         }
-        function getMissingContext(element, requiredContext, includeElement) {
-          var index, length, role = element.getAttribute('role'), missing = [];
+        function getMissingContext(virtualNode, requiredContext, includeElement) {
+          var index, length, role = virtualNode.actualNode.getAttribute('role'), missing = [];
           if (!requiredContext) {
             requiredContext = axe.commons.aria.requiredContext(role);
           }
@@ -6079,10 +10518,10 @@
             return null;
           }
           for (index = 0, length = requiredContext.length; index < length; index++) {
-            if (includeElement && axe.utils.matchesSelector(element, getSelector(requiredContext[index]))) {
+            if (includeElement && axe.utils.matchesSelector(virtualNode.actualNode, getSelector(requiredContext[index]))) {
               return null;
             }
-            if (axe.commons.dom.findUp(element, getSelector(requiredContext[index]))) {
+            if (axe.commons.dom.findUpVirtual(virtualNode, getSelector(requiredContext[index]))) {
               return null;
             } else {
               missing.push(requiredContext[index]);
@@ -6094,9 +10533,9 @@
           var owners = [], o = null;
           while (element) {
             if (element.getAttribute('id')) {
-              var id = axe.commons.utils.escapeSelector(element.getAttribute('id'));
+              var id = axe.utils.escapeSelector(element.getAttribute('id'));
               var doc = axe.commons.dom.getRootNode(element);
-              o = doc.querySelector('[aria-owns~=' + id + ']');
+              o = doc.querySelector('[aria-owns~='.concat(id, ']'));
               if (o) {
                 owners.push(o);
               }
@@ -6105,14 +10544,14 @@
           }
           return owners.length ? owners : null;
         }
-        var missingParents = getMissingContext(node);
+        var missingParents = getMissingContext(virtualNode);
         if (!missingParents) {
           return true;
         }
         var owners = getAriaOwners(node);
         if (owners) {
           for (var i = 0, l = owners.length; i < l; i++) {
-            missingParents = getMissingContext(owners[i], missingParents, true);
+            missingParents = getMissingContext(axe.utils.getNodeFromTree(owners[i]), missingParents, true);
             if (!missingParents) {
               return true;
             }
@@ -6122,17 +10561,77 @@
         return false;
       }
     }, {
-      id: 'aria-valid-attr-value',
-      evaluate: function evaluate(node, options, virtualNode) {
-        options = Array.isArray(options) ? options : [];
-        var invalid = [], aria = /^aria-/;
-        var attr, attrName, attrs = node.attributes;
-        for (var i = 0, l = attrs.length; i < l; i++) {
-          attr = attrs[i];
-          attrName = attr.name;
-          if (options.indexOf(attrName) === -1 && aria.test(attrName) && !axe.commons.aria.validateAttrValue(node, attrName)) {
-            invalid.push(attrName + '="' + attr.nodeValue + '"');
+      id: 'aria-unsupported-attr',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var nodeName = node.nodeName.toUpperCase();
+        var lookupTable = axe.commons.aria.lookupTable;
+        var role = axe.commons.aria.getRole(node);
+        var unsupportedAttrs = Array.from(axe.utils.getNodeAttributes(node)).filter(function(_ref2) {
+          var name = _ref2.name;
+          var attribute = lookupTable.attributes[name];
+          if (!axe.commons.aria.validateAttr(name)) {
+            return false;
           }
+          var unsupported = attribute.unsupported;
+          if (_typeof(unsupported) !== 'object') {
+            return !!unsupported;
+          }
+          var isException = axe.commons.matches(node, unsupported.exceptions);
+          if (!Object.keys(lookupTable.evaluateRoleForElement).includes(nodeName)) {
+            return !isException;
+          }
+          return !lookupTable.evaluateRoleForElement[nodeName]({
+            node: node,
+            role: role,
+            out: isException
+          });
+        }).map(function(candidate) {
+          return candidate.name.toString();
+        });
+        if (unsupportedAttrs.length) {
+          this.data(unsupportedAttrs);
+          return true;
+        }
+        return false;
+      }
+    }, {
+      id: 'unsupportedrole',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        return axe.commons.aria.isUnsupportedRole(axe.commons.aria.getRole(node));
+      }
+    }, {
+      id: 'aria-valid-attr-value',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        options = Array.isArray(options) ? options : [];
+        var needsReview = [];
+        var invalid = [];
+        var aria = /^aria-/;
+        var attrs = axe.utils.getNodeAttributes(node);
+        var skipAttrs = [ 'aria-errormessage' ];
+        var preChecks = {
+          'aria-controls': function ariaControls() {
+            return node.getAttribute('aria-expanded') !== 'false' && node.getAttribute('aria-selected') !== 'false';
+          },
+          'aria-owns': function ariaOwns() {
+            return node.getAttribute('aria-expanded') !== 'false';
+          },
+          'aria-describedby': function ariaDescribedby() {
+            if (!axe.commons.aria.validateAttrValue(node, 'aria-describedby')) {
+              needsReview.push('aria-describedby="'.concat(node.getAttribute('aria-describedby'), '"'));
+            }
+            return;
+          }
+        };
+        for (var i = 0, l = attrs.length; i < l; i++) {
+          var attr = attrs[i];
+          var attrName = attr.name;
+          if (!skipAttrs.includes(attrName) && options.indexOf(attrName) === -1 && aria.test(attrName) && (preChecks[attrName] ? preChecks[attrName]() : true) && !axe.commons.aria.validateAttrValue(node, attrName)) {
+            invalid.push(''.concat(attrName, '="').concat(attr.nodeValue, '"'));
+          }
+        }
+        if (needsReview.length) {
+          this.data(needsReview);
+          return undefined;
         }
         if (invalid.length) {
           this.data(invalid);
@@ -6143,10 +10642,10 @@
       options: []
     }, {
       id: 'aria-valid-attr',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         options = Array.isArray(options) ? options : [];
         var invalid = [], aria = /^aria-/;
-        var attr, attrs = node.attributes;
+        var attr, attrs = axe.utils.getNodeAttributes(node);
         for (var i = 0, l = attrs.length; i < l; i++) {
           attr = attrs[i].name;
           if (options.indexOf(attr) === -1 && aria.test(attr) && !axe.commons.aria.validateAttr(attr)) {
@@ -6161,51 +10660,95 @@
       },
       options: []
     }, {
+      id: 'valid-scrollable-semantics',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var VALID_TAG_NAMES_FOR_SCROLLABLE_REGIONS = {
+          ARTICLE: true,
+          ASIDE: true,
+          NAV: true,
+          SECTION: true
+        };
+        var VALID_ROLES_FOR_SCROLLABLE_REGIONS = {
+          application: true,
+          banner: false,
+          complementary: true,
+          contentinfo: true,
+          form: true,
+          main: true,
+          navigation: true,
+          region: true,
+          search: false
+        };
+        function validScrollableTagName(node) {
+          var nodeName = node.nodeName.toUpperCase();
+          return VALID_TAG_NAMES_FOR_SCROLLABLE_REGIONS[nodeName] || false;
+        }
+        function validScrollableRole(node) {
+          var role = node.getAttribute('role');
+          if (!role) {
+            return false;
+          }
+          return VALID_ROLES_FOR_SCROLLABLE_REGIONS[role.toLowerCase()] || false;
+        }
+        function validScrollableSemantics(node) {
+          return validScrollableRole(node) || validScrollableTagName(node);
+        }
+        return validScrollableSemantics(node);
+      },
+      options: []
+    }, {
       id: 'color-contrast',
-      evaluate: function evaluate(node, options, virtualNode) {
-        if (!axe.commons.dom.isVisible(node, false)) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var _axe$commons7 = axe.commons, dom = _axe$commons7.dom, color = _axe$commons7.color, text = _axe$commons7.text;
+        if (!dom.isVisible(node, false)) {
           return true;
         }
         var noScroll = !!(options || {}).noScroll;
-        var bgNodes = [], bgColor = axe.commons.color.getBackgroundColor(node, bgNodes, noScroll), fgColor = axe.commons.color.getForegroundColor(node, noScroll);
+        var bgNodes = [];
+        var bgColor = color.getBackgroundColor(node, bgNodes, noScroll);
+        var fgColor = color.getForegroundColor(node, noScroll);
         var nodeStyle = window.getComputedStyle(node);
         var fontSize = parseFloat(nodeStyle.getPropertyValue('font-size'));
         var fontWeight = nodeStyle.getPropertyValue('font-weight');
         var bold = [ 'bold', 'bolder', '600', '700', '800', '900' ].indexOf(fontWeight) !== -1;
-        var cr = axe.commons.color.hasValidContrastRatio(bgColor, fgColor, fontSize, bold);
+        var cr = color.hasValidContrastRatio(bgColor, fgColor, fontSize, bold);
         var truncatedResult = Math.floor(cr.contrastRatio * 100) / 100;
         var missing;
         if (bgColor === null) {
-          missing = axe.commons.color.incompleteData.get('bgColor');
+          missing = color.incompleteData.get('bgColor');
         }
-        var equalRatio = false;
-        if (truncatedResult === 1) {
-          equalRatio = true;
-          missing = axe.commons.color.incompleteData.set('bgColor', 'equalRatio');
+        var equalRatio = truncatedResult === 1;
+        var shortTextContent = text.visibleVirtual(virtualNode, false, true).length === 1;
+        if (equalRatio) {
+          missing = color.incompleteData.set('bgColor', 'equalRatio');
+        } else if (shortTextContent) {
+          missing = 'shortTextContent';
         }
         var data = {
           fgColor: fgColor ? fgColor.toHexString() : undefined,
           bgColor: bgColor ? bgColor.toHexString() : undefined,
           contrastRatio: cr ? truncatedResult : undefined,
-          fontSize: (fontSize * 72 / 96).toFixed(1) + 'pt',
+          fontSize: ''.concat((fontSize * 72 / 96).toFixed(1), 'pt (').concat(fontSize, 'px)'),
           fontWeight: bold ? 'bold' : 'normal',
-          missingData: missing
+          missingData: missing,
+          expectedContrastRatio: cr.expectedContrastRatio + ':1'
         };
         this.data(data);
-        if (fgColor === null || bgColor === null || equalRatio) {
+        if (fgColor === null || bgColor === null || equalRatio || shortTextContent && !cr.isValid) {
           missing = null;
-          axe.commons.color.incompleteData.clear();
+          color.incompleteData.clear();
           this.relatedNodes(bgNodes);
           return undefined;
-        } else if (!cr.isValid) {
+        }
+        if (!cr.isValid) {
           this.relatedNodes(bgNodes);
         }
         return cr.isValid;
       }
     }, {
       id: 'link-in-text-block',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var _axe$commons = axe.commons, color = _axe$commons.color, dom = _axe$commons.dom;
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var _axe$commons8 = axe.commons, color = _axe$commons8.color, dom = _axe$commons8.dom;
         function getContrast(color1, color2) {
           var c1lum = color1.getRelativeLuminance();
           var c2lum = color2.getRelativeLuminance();
@@ -6247,7 +10790,7 @@
           nodeColor = color.getBackgroundColor(node);
           parentColor = color.getBackgroundColor(parentBlock);
           if (!nodeColor || !parentColor || getContrast(nodeColor, parentColor) >= 3) {
-            var reason = void 0;
+            var reason;
             if (!nodeColor || !parentColor) {
               reason = axe.commons.color.incompleteData.get('bgColor');
             } else {
@@ -6264,11 +10807,67 @@
         return false;
       }
     }, {
+      id: 'autocomplete-appropriate',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        if (virtualNode.props.nodeName !== 'input') {
+          return true;
+        }
+        var number = [ 'text', 'search', 'number' ];
+        var url = [ 'text', 'search', 'url' ];
+        var allowedTypesMap = {
+          bday: [ 'text', 'search', 'date' ],
+          email: [ 'text', 'search', 'email' ],
+          'cc-exp': [ 'text', 'search', 'month' ],
+          'street-address': [ 'text' ],
+          tel: [ 'text', 'search', 'tel' ],
+          'cc-exp-month': number,
+          'cc-exp-year': number,
+          'transaction-amount': number,
+          'bday-day': number,
+          'bday-month': number,
+          'bday-year': number,
+          'new-password': [ 'text', 'search', 'password' ],
+          'current-password': [ 'text', 'search', 'password' ],
+          url: url,
+          photo: url,
+          impp: url
+        };
+        if (_typeof(options) === 'object') {
+          Object.keys(options).forEach(function(key) {
+            if (!allowedTypesMap[key]) {
+              allowedTypesMap[key] = [];
+            }
+            allowedTypesMap[key] = allowedTypesMap[key].concat(options[key]);
+          });
+        }
+        var autocomplete = virtualNode.attr('autocomplete');
+        var autocompleteTerms = autocomplete.split(/\s+/g).map(function(term) {
+          return term.toLowerCase();
+        });
+        var purposeTerm = autocompleteTerms[autocompleteTerms.length - 1];
+        if (axe.commons.text.autocomplete.stateTerms.includes(purposeTerm)) {
+          return true;
+        }
+        var allowedTypes = allowedTypesMap[purposeTerm];
+        var type = virtualNode.hasAttr('type') ? axe.commons.text.sanitize(virtualNode.attr('type')).toLowerCase() : 'text';
+        type = axe.utils.validInputTypes().includes(type) ? type : 'text';
+        if (typeof allowedTypes === 'undefined') {
+          return type === 'text';
+        }
+        return allowedTypes.includes(type);
+      }
+    }, {
+      id: 'autocomplete-valid',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var autocomplete = virtualNode.attr('autocomplete') || '';
+        return axe.commons.text.isValidAutocomplete(autocomplete, options);
+      }
+    }, {
       id: 'fieldset',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var failureCode, self = this;
         function getUnrelatedElements(parent, name) {
-          return axe.commons.utils.toArray(parent.querySelectorAll('select,textarea,button,input:not([name="' + name + '"]):not([type="hidden"])'));
+          return axe.utils.toArray(parent.querySelectorAll('select,textarea,button,input:not([name="' + name + '"]):not([type="hidden"])'));
         }
         function checkFieldset(group, name) {
           var firstNode = group.firstElementChild;
@@ -6309,22 +10908,22 @@
           return true;
         }
         function spliceCurrentNode(nodes, current) {
-          return axe.commons.utils.toArray(nodes).filter(function(candidate) {
+          return axe.utils.toArray(nodes).filter(function(candidate) {
             return candidate !== current;
           });
         }
-        function runCheck(element) {
-          var name = axe.commons.utils.escapeSelector(node.name);
-          var root = axe.commons.dom.getRootNode(node);
-          var matchingNodes = root.querySelectorAll('input[type="' + axe.commons.utils.escapeSelector(node.type) + '"][name="' + name + '"]');
+        function runCheck(virtualNode) {
+          var name = axe.utils.escapeSelector(virtualNode.actualNode.name);
+          var root = axe.commons.dom.getRootNode(virtualNode.actualNode);
+          var matchingNodes = root.querySelectorAll('input[type="' + axe.utils.escapeSelector(virtualNode.actualNode.type) + '"][name="' + name + '"]');
           if (matchingNodes.length < 2) {
             return true;
           }
-          var fieldset = axe.commons.dom.findUp(element, 'fieldset');
-          var group = axe.commons.dom.findUp(element, '[role="group"]' + (node.type === 'radio' ? ',[role="radiogroup"]' : ''));
+          var fieldset = axe.commons.dom.findUpVirtual(virtualNode, 'fieldset');
+          var group = axe.commons.dom.findUpVirtual(virtualNode, '[role="group"]' + (virtualNode.actualNode.type === 'radio' ? ',[role="radiogroup"]' : ''));
           if (!group && !fieldset) {
             failureCode = 'no-group';
-            self.relatedNodes(spliceCurrentNode(matchingNodes, element));
+            self.relatedNodes(spliceCurrentNode(matchingNodes, virtualNode.actualNode));
             return false;
           } else if (fieldset) {
             return checkFieldset(fieldset, name);
@@ -6336,7 +10935,7 @@
           name: node.getAttribute('name'),
           type: node.getAttribute('type')
         };
-        var result = runCheck(node);
+        var result = runCheck(virtualNode);
         if (!result) {
           data.failureCode = failureCode;
         }
@@ -6369,27 +10968,58 @@
       }
     }, {
       id: 'group-labelledby',
-      evaluate: function evaluate(node, options, virtualNode) {
-        this.data({
-          name: node.getAttribute('name'),
-          type: node.getAttribute('type')
-        });
-        var doc = axe.commons.dom.getRootNode(node);
-        var matchingNodes = doc.querySelectorAll('input[type="' + axe.commons.utils.escapeSelector(node.type) + '"][name="' + axe.commons.utils.escapeSelector(node.name) + '"]');
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var _axe$commons9 = axe.commons, dom = _axe$commons9.dom, text = _axe$commons9.text;
+        var type = axe.utils.escapeSelector(node.type);
+        var name = axe.utils.escapeSelector(node.name);
+        var doc = dom.getRootNode(node);
+        var data = {
+          name: node.name,
+          type: node.type
+        };
+        var matchingNodes = Array.from(doc.querySelectorAll('input[type="'.concat(type, '"][name="').concat(name, '"]')));
         if (matchingNodes.length <= 1) {
+          this.data(data);
           return true;
         }
-        return [].map.call(matchingNodes, function(m) {
-          var l = m.getAttribute('aria-labelledby');
-          return l ? l.split(/\s+/) : [];
-        }).reduce(function(prev, curr) {
-          return prev.filter(function(n) {
-            return curr.includes(n);
+        var sharedLabels = dom.idrefs(node, 'aria-labelledby').filter(function(label) {
+          return !!label;
+        });
+        var uniqueLabels = sharedLabels.slice();
+        matchingNodes.forEach(function(groupItem) {
+          if (groupItem === node) {
+            return;
+          }
+          var labels = dom.idrefs(groupItem, 'aria-labelledby').filter(function(newLabel) {
+            return newLabel;
           });
-        }).filter(function(n) {
-          var labelNode = doc.getElementById(n);
-          return labelNode && axe.commons.text.accessibleText(labelNode);
-        }).length !== 0;
+          sharedLabels = sharedLabels.filter(function(sharedLabel) {
+            return labels.includes(sharedLabel);
+          });
+          uniqueLabels = uniqueLabels.filter(function(uniqueLabel) {
+            return !labels.includes(uniqueLabel);
+          });
+        });
+        var accessibleTextOptions = {
+          inLabelledByContext: true
+        };
+        uniqueLabels = uniqueLabels.filter(function(labelNode) {
+          return text.accessibleText(labelNode, accessibleTextOptions);
+        });
+        sharedLabels = sharedLabels.filter(function(labelNode) {
+          return text.accessibleText(labelNode, accessibleTextOptions);
+        });
+        if (uniqueLabels.length > 0 && sharedLabels.length > 0) {
+          this.data(data);
+          return true;
+        }
+        if (uniqueLabels.length > 0 && sharedLabels.length === 0) {
+          data.failureCode = 'no-shared-label';
+        } else if (uniqueLabels.length === 0 && sharedLabels.length > 0) {
+          data.failureCode = 'no-unique-label';
+        }
+        this.data(data);
+        return false;
       },
       after: function after(results, options) {
         var seen = {};
@@ -6407,7 +11037,7 @@
       }
     }, {
       id: 'accesskeys',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         if (axe.commons.dom.isVisible(node, false)) {
           this.data(node.getAttribute('accesskey'));
           this.relatedNodes([ node ]);
@@ -6434,51 +11064,256 @@
         });
       }
     }, {
-      id: 'focusable-no-name',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var tabIndex = node.getAttribute('tabindex'), isFocusable = axe.commons.dom.isFocusable(node) && tabIndex > -1;
-        if (!isFocusable) {
+      id: 'focusable-content',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var tabbableElements = virtualNode.tabbableElements;
+        if (!tabbableElements) {
           return false;
         }
-        return !axe.commons.text.accessibleText(node);
+        var tabbableContentElements = tabbableElements.filter(function(el) {
+          return el !== virtualNode;
+        });
+        return tabbableContentElements.length > 0;
+      }
+    }, {
+      id: 'focusable-disabled',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var elementsThatCanBeDisabled = [ 'BUTTON', 'FIELDSET', 'INPUT', 'SELECT', 'TEXTAREA' ];
+        var tabbableElements = virtualNode.tabbableElements;
+        if (!tabbableElements || !tabbableElements.length) {
+          return true;
+        }
+        var relatedNodes = tabbableElements.reduce(function(out, _ref3) {
+          var el = _ref3.actualNode;
+          var nodeName = el.nodeName.toUpperCase();
+          if (elementsThatCanBeDisabled.includes(nodeName)) {
+            out.push(el);
+          }
+          return out;
+        }, []);
+        this.relatedNodes(relatedNodes);
+        return relatedNodes.length === 0;
+      }
+    }, {
+      id: 'focusable-element',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var isFocusable = virtualNode.isFocusable;
+        var tabIndex = parseInt(virtualNode.actualNode.getAttribute('tabindex'), 10);
+        tabIndex = !isNaN(tabIndex) ? tabIndex : null;
+        return tabIndex ? isFocusable && tabIndex >= 0 : isFocusable;
+      }
+    }, {
+      id: 'focusable-no-name',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var tabIndex = node.getAttribute('tabindex'), inFocusOrder = axe.commons.dom.isFocusable(node) && tabIndex > -1;
+        if (!inFocusOrder) {
+          return false;
+        }
+        return !axe.commons.text.accessibleTextVirtual(virtualNode);
+      }
+    }, {
+      id: 'focusable-not-tabbable',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var elementsThatCanBeDisabled = [ 'BUTTON', 'FIELDSET', 'INPUT', 'SELECT', 'TEXTAREA' ];
+        var tabbableElements = virtualNode.tabbableElements;
+        if (!tabbableElements || !tabbableElements.length) {
+          return true;
+        }
+        var relatedNodes = tabbableElements.reduce(function(out, _ref4) {
+          var el = _ref4.actualNode;
+          var nodeName = el.nodeName.toUpperCase();
+          if (!elementsThatCanBeDisabled.includes(nodeName)) {
+            out.push(el);
+          }
+          return out;
+        }, []);
+        this.relatedNodes(relatedNodes);
+        return relatedNodes.length === 0;
+      }
+    }, {
+      id: 'landmark-is-top-level',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var landmarks = axe.commons.aria.getRolesByType('landmark');
+        var parent = axe.commons.dom.getComposedParent(node);
+        this.data({
+          role: node.getAttribute('role') || axe.commons.aria.implicitRole(node)
+        });
+        while (parent) {
+          var role = parent.getAttribute('role');
+          if (!role && parent.nodeName.toUpperCase() !== 'FORM') {
+            role = axe.commons.aria.implicitRole(parent);
+          }
+          if (role && landmarks.includes(role)) {
+            return false;
+          }
+          parent = axe.commons.dom.getComposedParent(parent);
+        }
+        return true;
+      }
+    }, {
+      id: 'page-has-heading-one',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        if (!options || !options.selector || typeof options.selector !== 'string') {
+          throw new TypeError('visible-in-page requires options.selector to be a string');
+        }
+        var matchingElms = axe.utils.querySelectorAll(virtualNode, options.selector);
+        this.relatedNodes(matchingElms.map(function(vNode) {
+          return vNode.actualNode;
+        }));
+        return matchingElms.length > 0;
+      },
+      after: function after(results, options) {
+        var elmUsedAnywhere = results.some(function(frameResult) {
+          return frameResult.result === true;
+        });
+        if (elmUsedAnywhere) {
+          results.forEach(function(result) {
+            result.result = true;
+          });
+        }
+        return results;
+      },
+      options: {
+        selector: 'h1:not([role]), [role="heading"][aria-level="1"]'
+      }
+    }, {
+      id: 'page-has-main',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        if (!options || !options.selector || typeof options.selector !== 'string') {
+          throw new TypeError('visible-in-page requires options.selector to be a string');
+        }
+        var matchingElms = axe.utils.querySelectorAll(virtualNode, options.selector);
+        this.relatedNodes(matchingElms.map(function(vNode) {
+          return vNode.actualNode;
+        }));
+        return matchingElms.length > 0;
+      },
+      after: function after(results, options) {
+        var elmUsedAnywhere = results.some(function(frameResult) {
+          return frameResult.result === true;
+        });
+        if (elmUsedAnywhere) {
+          results.forEach(function(result) {
+            result.result = true;
+          });
+        }
+        return results;
+      },
+      options: {
+        selector: 'main:not([role]), [role=\'main\']'
+      }
+    }, {
+      id: 'page-no-duplicate-banner',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        if (!options || !options.selector || typeof options.selector !== 'string') {
+          throw new TypeError('visible-in-page requires options.selector to be a string');
+        }
+        var elms = axe.utils.querySelectorAll(virtualNode, options.selector);
+        if (typeof options.nativeScopeFilter === 'string') {
+          elms = elms.filter(function(elm) {
+            return elm.actualNode.hasAttribute('role') || !axe.commons.dom.findUpVirtual(elm, options.nativeScopeFilter);
+          });
+        }
+        this.relatedNodes(elms.map(function(elm) {
+          return elm.actualNode;
+        }));
+        return elms.length <= 1;
+      },
+      options: {
+        selector: 'header:not([role]), [role=banner]',
+        nativeScopeFilter: 'article, aside, main, nav, section'
+      }
+    }, {
+      id: 'page-no-duplicate-contentinfo',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        if (!options || !options.selector || typeof options.selector !== 'string') {
+          throw new TypeError('visible-in-page requires options.selector to be a string');
+        }
+        var elms = axe.utils.querySelectorAll(virtualNode, options.selector);
+        if (typeof options.nativeScopeFilter === 'string') {
+          elms = elms.filter(function(elm) {
+            return elm.actualNode.hasAttribute('role') || !axe.commons.dom.findUpVirtual(elm, options.nativeScopeFilter);
+          });
+        }
+        this.relatedNodes(elms.map(function(elm) {
+          return elm.actualNode;
+        }));
+        return elms.length <= 1;
+      },
+      options: {
+        selector: 'footer:not([role]), [role=contentinfo]',
+        nativeScopeFilter: 'article, aside, main, nav, section'
+      }
+    }, {
+      id: 'page-no-duplicate-main',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        if (!options || !options.selector || typeof options.selector !== 'string') {
+          throw new TypeError('visible-in-page requires options.selector to be a string');
+        }
+        var elms = axe.utils.querySelectorAll(virtualNode, options.selector);
+        if (typeof options.nativeScopeFilter === 'string') {
+          elms = elms.filter(function(elm) {
+            return elm.actualNode.hasAttribute('role') || !axe.commons.dom.findUpVirtual(elm, options.nativeScopeFilter);
+          });
+        }
+        this.relatedNodes(elms.map(function(elm) {
+          return elm.actualNode;
+        }));
+        return elms.length <= 1;
+      },
+      options: {
+        selector: 'main:not([role]), [role=\'main\']'
       }
     }, {
       id: 'tabindex',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         return node.tabIndex <= 0;
       }
     }, {
+      id: 'alt-space-value',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var validAttrValue = /^\s+$/.test(node.getAttribute('alt'));
+        return node.hasAttribute('alt') && validAttrValue;
+      }
+    }, {
       id: 'duplicate-img-label',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var text = axe.commons.text.visible(virtualNode, true).toLowerCase();
-        if (text === '') {
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var _axe$commons10 = axe.commons, aria = _axe$commons10.aria, text = _axe$commons10.text, dom = _axe$commons10.dom;
+        if ([ 'none', 'presentation' ].includes(aria.getRole(node))) {
           return false;
         }
-        var images = axe.utils.querySelectorAll(virtualNode, 'img').filter(function(_ref) {
-          var actualNode = _ref.actualNode;
-          return axe.commons.dom.isVisible(actualNode) && ![ 'none', 'presentation' ].includes(actualNode.getAttribute('role'));
-        });
-        return images.some(function(img) {
-          return text === axe.commons.text.accessibleText(img).toLowerCase();
-        });
+        var parent = dom.findUpVirtual(virtualNode, 'button, [role="button"], a[href], p, li, td, th');
+        if (!parent) {
+          return false;
+        }
+        var parentVNode = axe.utils.getNodeFromTree(parent);
+        var visibleText = text.visibleVirtual(parentVNode, true).toLowerCase();
+        if (visibleText === '') {
+          return false;
+        }
+        return visibleText === text.accessibleTextVirtual(virtualNode).toLowerCase();
       }
     }, {
       id: 'explicit-label',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         if (node.getAttribute('id')) {
           var root = axe.commons.dom.getRootNode(node);
-          var id = axe.commons.utils.escapeSelector(node.getAttribute('id'));
-          var label = root.querySelector('label[for="' + id + '"]');
+          var id = axe.utils.escapeSelector(node.getAttribute('id'));
+          var label = root.querySelector('label[for="'.concat(id, '"]'));
           if (label) {
-            return !!axe.commons.text.accessibleText(label);
+            if (!axe.commons.dom.isVisible(label)) {
+              return true;
+            } else {
+              return !!axe.commons.text.accessibleText(label);
+            }
           }
         }
         return false;
       }
     }, {
       id: 'help-same-as-label',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var labelText = axe.commons.text.label(virtualNode), check = node.getAttribute('title');
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var labelText = axe.commons.text.labelVirtual(virtualNode), check = node.getAttribute('title');
         if (!labelText) {
           return false;
         }
@@ -6495,61 +11330,149 @@
       },
       enabled: false
     }, {
-      id: 'implicit-label',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var label = axe.commons.dom.findUp(node, 'label');
-        if (label) {
-          return !!axe.commons.text.accessibleText(label);
+      id: 'hidden-explicit-label',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        if (node.getAttribute('id')) {
+          var root = axe.commons.dom.getRootNode(node);
+          var id = axe.utils.escapeSelector(node.getAttribute('id'));
+          var label = root.querySelector('label[for="'.concat(id, '"]'));
+          if (label && !axe.commons.dom.isVisible(label, true)) {
+            var name = axe.commons.text.accessibleTextVirtual(virtualNode).trim();
+            var isNameEmpty = name === '';
+            return isNameEmpty;
+          }
         }
         return false;
       }
     }, {
+      id: 'implicit-label',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var _axe$commons11 = axe.commons, dom = _axe$commons11.dom, text = _axe$commons11.text;
+        var label = dom.findUpVirtual(virtualNode, 'label');
+        if (label) {
+          return !!text.accessibleText(label, {
+            inControlContext: true
+          });
+        }
+        return false;
+      }
+    }, {
+      id: 'label-content-name-mismatch',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var text = axe.commons.text;
+        var accText = text.accessibleText(node).toLowerCase();
+        if (text.isHumanInterpretable(accText) < 1) {
+          return undefined;
+        }
+        var visibleText = text.sanitize(text.visibleVirtual(virtualNode)).toLowerCase();
+        if (text.isHumanInterpretable(visibleText) < 1) {
+          if (isStringContained(visibleText, accText)) {
+            return true;
+          }
+          return undefined;
+        }
+        return isStringContained(visibleText, accText);
+        function isStringContained(compare, compareWith) {
+          var curatedCompareWith = curateString(compareWith);
+          var curatedCompare = curateString(compare);
+          if (!curatedCompareWith || !curatedCompare) {
+            return false;
+          }
+          return curatedCompareWith.includes(curatedCompare);
+        }
+        function curateString(str) {
+          var noUnicodeStr = text.removeUnicode(str, {
+            emoji: true,
+            nonBmp: true,
+            punctuations: true
+          });
+          return text.sanitize(noUnicodeStr);
+        }
+      }
+    }, {
       id: 'multiple-label',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var id = axe.commons.utils.escapeSelector(node.getAttribute('id'));
-        var labels = Array.from(document.querySelectorAll('label[for="' + id + '"]'));
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var id = axe.utils.escapeSelector(node.getAttribute('id'));
         var parent = node.parentNode;
+        var root = axe.commons.dom.getRootNode(node);
+        root = root.documentElement || root;
+        var labels = Array.from(root.querySelectorAll('label[for="'.concat(id, '"]')));
         if (labels.length) {
-          labels = labels.filter(function(label, index) {
-            if (index === 0 && !axe.commons.dom.isVisible(label, true) || axe.commons.dom.isVisible(label, true)) {
-              return label;
-            }
+          labels = labels.filter(function(label) {
+            return axe.commons.dom.isVisible(label);
           });
         }
         while (parent) {
-          if (parent.tagName === 'LABEL' && labels.indexOf(parent) === -1) {
+          if (parent.nodeName.toUpperCase() === 'LABEL' && labels.indexOf(parent) === -1) {
             labels.push(parent);
           }
           parent = parent.parentNode;
         }
         this.relatedNodes(labels);
-        return labels.length > 1;
+        if (labels.length > 1) {
+          var ATVisibleLabels = labels.filter(function(label) {
+            return axe.commons.dom.isVisible(label, true);
+          });
+          if (ATVisibleLabels.length > 1) {
+            return true;
+          }
+          var labelledby = axe.commons.dom.idrefs(node, 'aria-labelledby');
+          return !labelledby.includes(ATVisibleLabels[0]);
+        }
+        return false;
       }
     }, {
       id: 'title-only',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var labelText = axe.commons.text.label(virtualNode);
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var labelText = axe.commons.text.labelVirtual(virtualNode);
         return !labelText && !!(node.getAttribute('title') || node.getAttribute('aria-describedby'));
       }
     }, {
+      id: 'landmark-is-unique',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var role = axe.commons.aria.getRole(node);
+        var accessibleText = axe.commons.text.accessibleTextVirtual(virtualNode);
+        accessibleText = accessibleText ? accessibleText.toLowerCase() : null;
+        this.data({
+          role: role,
+          accessibleText: accessibleText
+        });
+        this.relatedNodes([ node ]);
+        return true;
+      },
+      after: function after(results, options) {
+        var uniqueLandmarks = [];
+        return results.filter(function(currentResult) {
+          var findMatch = function findMatch(someResult) {
+            return currentResult.data.role === someResult.data.role && currentResult.data.accessibleText === someResult.data.accessibleText;
+          };
+          var matchedResult = uniqueLandmarks.find(findMatch);
+          if (matchedResult) {
+            matchedResult.result = false;
+            matchedResult.relatedNodes.push(currentResult.relatedNodes[0]);
+            return false;
+          }
+          uniqueLandmarks.push(currentResult);
+          currentResult.relatedNodes = [];
+          return true;
+        });
+      }
+    }, {
       id: 'has-lang',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         return !!(node.getAttribute('lang') || node.getAttribute('xml:lang') || '').trim();
       }
     }, {
       id: 'valid-lang',
-      evaluate: function evaluate(node, options, virtualNode) {
-        function getBaseLang(lang) {
-          return lang.trim().split('-')[0].toLowerCase();
-        }
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var langs, invalid;
-        langs = (options ? options : axe.commons.utils.validLangs()).map(getBaseLang);
+        langs = (options ? options : axe.utils.validLangs()).map(axe.utils.getBaseLang);
         invalid = [ 'lang', 'xml:lang' ].reduce(function(invalid, langAttr) {
           var langVal = node.getAttribute(langAttr);
           if (typeof langVal !== 'string') {
             return invalid;
           }
-          var baselangVal = getBaseLang(langVal);
+          var baselangVal = axe.utils.getBaseLang(langVal);
           if (baselangVal !== '' && langs.indexOf(baselangVal) === -1) {
             invalid.push(langAttr + '="' + node.getAttribute(langAttr) + '"');
           }
@@ -6562,65 +11485,146 @@
         return false;
       }
     }, {
-      id: 'dlitem',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var parent = axe.commons.dom.getComposedParent(node);
-        return parent.nodeName.toUpperCase() === 'DL';
+      id: 'xml-lang-mismatch',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var getBaseLang = axe.utils.getBaseLang;
+        var primaryLangValue = getBaseLang(node.getAttribute('lang'));
+        var primaryXmlLangValue = getBaseLang(node.getAttribute('xml:lang'));
+        return primaryLangValue === primaryXmlLangValue;
       }
     }, {
-      id: 'has-listitem',
-      evaluate: function evaluate(node, options, virtualNode) {
-        return virtualNode.children.every(function(_ref2) {
-          var actualNode = _ref2.actualNode;
-          return actualNode.nodeName.toUpperCase() !== 'LI';
+      id: 'dlitem',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var parent = axe.commons.dom.getComposedParent(node);
+        var parentTagName = parent.nodeName.toUpperCase();
+        var parentRole = axe.commons.aria.getRole(parent, {
+          noImplicit: true
         });
+        if (parentTagName === 'DIV' && [ 'presentation', 'none', null ].includes(parentRole)) {
+          parent = axe.commons.dom.getComposedParent(parent);
+          parentTagName = parent.nodeName.toUpperCase();
+          parentRole = axe.commons.aria.getRole(parent, {
+            noImplicit: true
+          });
+        }
+        if (parentTagName !== 'DL') {
+          return false;
+        }
+        if (!parentRole || parentRole === 'list') {
+          return true;
+        }
+        return false;
       }
     }, {
       id: 'listitem',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var parent = axe.commons.dom.getComposedParent(node);
-        return [ 'UL', 'OL' ].includes(parent.nodeName.toUpperCase()) || (parent.getAttribute('role') || '').toLowerCase() === 'list';
+        if (!parent) {
+          return undefined;
+        }
+        var parentTagName = parent.nodeName.toUpperCase();
+        var parentRole = (parent.getAttribute('role') || '').toLowerCase();
+        if (parentRole === 'list') {
+          return true;
+        }
+        if (parentRole && axe.commons.aria.isValidRole(parentRole)) {
+          return false;
+        }
+        return [ 'UL', 'OL' ].includes(parentTagName);
       }
     }, {
       id: 'only-dlitems',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var bad = [], permitted = [ 'STYLE', 'META', 'LINK', 'MAP', 'AREA', 'SCRIPT', 'DATALIST', 'TEMPLATE' ], hasNonEmptyTextNode = false;
-        virtualNode.children.forEach(function(_ref3) {
-          var actualNode = _ref3.actualNode;
-          var nodeName = actualNode.nodeName.toUpperCase();
-          if (actualNode.nodeType === 1 && nodeName !== 'DT' && nodeName !== 'DD' && permitted.indexOf(nodeName) === -1) {
-            bad.push(actualNode);
-          } else if (actualNode.nodeType === 3 && actualNode.nodeValue.trim() !== '') {
-            hasNonEmptyTextNode = true;
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var _axe$commons12 = axe.commons, dom = _axe$commons12.dom, aria = _axe$commons12.aria;
+        var ALLOWED_ROLES = [ 'definition', 'term', 'list' ];
+        var base = {
+          badNodes: [],
+          hasNonEmptyTextNode: false
+        };
+        var content = virtualNode.children.reduce(function(content, child) {
+          var actualNode = child.actualNode;
+          if (actualNode.nodeName.toUpperCase() === 'DIV' && aria.getRole(actualNode) === null) {
+            return content.concat(child.children);
           }
-        });
-        if (bad.length) {
-          this.relatedNodes(bad);
+          return content.concat(child);
+        }, []);
+        var result = content.reduce(function(out, childNode) {
+          var actualNode = childNode.actualNode;
+          var tagName = actualNode.nodeName.toUpperCase();
+          if (actualNode.nodeType === 1 && dom.isVisible(actualNode, true, false)) {
+            var explicitRole = aria.getRole(actualNode, {
+              noImplicit: true
+            });
+            if (tagName !== 'DT' && tagName !== 'DD' || explicitRole) {
+              if (!ALLOWED_ROLES.includes(explicitRole)) {
+                out.badNodes.push(actualNode);
+              }
+            }
+          } else if (actualNode.nodeType === 3 && actualNode.nodeValue.trim() !== '') {
+            out.hasNonEmptyTextNode = true;
+          }
+          return out;
+        }, base);
+        if (result.badNodes.length) {
+          this.relatedNodes(result.badNodes);
         }
-        var retVal = !!bad.length || hasNonEmptyTextNode;
-        return retVal;
+        return !!result.badNodes.length || result.hasNonEmptyTextNode;
       }
     }, {
       id: 'only-listitems',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var bad = [], permitted = [ 'STYLE', 'META', 'LINK', 'MAP', 'AREA', 'SCRIPT', 'DATALIST', 'TEMPLATE' ], hasNonEmptyTextNode = false;
-        virtualNode.children.forEach(function(_ref4) {
-          var actualNode = _ref4.actualNode;
-          var nodeName = actualNode.nodeName.toUpperCase();
-          if (actualNode.nodeType === 1 && nodeName !== 'LI' && permitted.indexOf(nodeName) === -1) {
-            bad.push(actualNode);
-          } else if (actualNode.nodeType === 3 && actualNode.nodeValue.trim() !== '') {
-            hasNonEmptyTextNode = true;
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var dom = axe.commons.dom;
+        var getIsListItemRole = function getIsListItemRole(role, tagName) {
+          return role === 'listitem' || tagName === 'LI' && !role;
+        };
+        var getHasListItem = function getHasListItem(hasListItem, tagName, isListItemRole) {
+          return hasListItem || tagName === 'LI' && isListItemRole || isListItemRole;
+        };
+        var base = {
+          badNodes: [],
+          isEmpty: true,
+          hasNonEmptyTextNode: false,
+          hasListItem: false,
+          liItemsWithRole: 0
+        };
+        var out = virtualNode.children.reduce(function(out, _ref5) {
+          var actualNode = _ref5.actualNode;
+          var tagName = actualNode.nodeName.toUpperCase();
+          if (actualNode.nodeType === 1 && dom.isVisible(actualNode, true, false)) {
+            var role = (actualNode.getAttribute('role') || '').toLowerCase();
+            var isListItemRole = getIsListItemRole(role, tagName);
+            out.hasListItem = getHasListItem(out.hasListItem, tagName, isListItemRole);
+            if (isListItemRole) {
+              out.isEmpty = false;
+            }
+            if (tagName === 'LI' && !isListItemRole) {
+              out.liItemsWithRole++;
+            }
+            if (tagName !== 'LI' && !isListItemRole) {
+              out.badNodes.push(actualNode);
+            }
           }
+          if (actualNode.nodeType === 3) {
+            if (actualNode.nodeValue.trim() !== '') {
+              out.hasNonEmptyTextNode = true;
+            }
+          }
+          return out;
+        }, base);
+        var virtualNodeChildrenOfTypeLi = virtualNode.children.filter(function(_ref6) {
+          var actualNode = _ref6.actualNode;
+          return actualNode.nodeName.toUpperCase() === 'LI';
         });
-        if (bad.length) {
-          this.relatedNodes(bad);
+        var allLiItemsHaveRole = out.liItemsWithRole > 0 && virtualNodeChildrenOfTypeLi.length === out.liItemsWithRole;
+        if (out.badNodes.length) {
+          this.relatedNodes(out.badNodes);
         }
-        return !!bad.length || hasNonEmptyTextNode;
+        var isInvalidListItem = !(out.hasListItem || out.isEmpty && !allLiItemsHaveRole);
+        return isInvalidListItem || !!out.badNodes.length || out.hasNonEmptyTextNode;
       }
     }, {
       id: 'structured-dlitems',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var children = virtualNode.children;
         if (!children || !children.length) {
           return false;
@@ -6642,35 +11646,128 @@
       }
     }, {
       id: 'caption',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var tracks = axe.utils.querySelectorAll(virtualNode, 'track');
-        if (tracks.length) {
-          return !tracks.some(function(_ref5) {
-            var actualNode = _ref5.actualNode;
-            return (actualNode.getAttribute('kind') || '').toLowerCase() === 'captions';
-          });
-        }
-        return undefined;
+        var hasCaptions = tracks.some(function(_ref7) {
+          var actualNode = _ref7.actualNode;
+          return (actualNode.getAttribute('kind') || '').toLowerCase() === 'captions';
+        });
+        return hasCaptions ? false : undefined;
       }
     }, {
       id: 'description',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var tracks = axe.utils.querySelectorAll(virtualNode, 'track');
-        if (tracks.length) {
-          var out = !tracks.some(function(_ref6) {
-            var actualNode = _ref6.actualNode;
-            return (actualNode.getAttribute('kind') || '').toLowerCase() === 'descriptions';
-          });
-          axe.log(tracks.map(function(t) {
-            return t.actualNode.getAttribute('kind');
-          }), out);
-          return out;
+        var hasDescriptions = tracks.some(function(_ref8) {
+          var actualNode = _ref8.actualNode;
+          return (actualNode.getAttribute('kind') || '').toLowerCase() === 'descriptions';
+        });
+        return hasDescriptions ? false : undefined;
+      }
+    }, {
+      id: 'frame-tested',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var resolve = this.async();
+        var _Object$assign = Object.assign({
+          isViolation: false,
+          timeout: 500
+        }, options), isViolation = _Object$assign.isViolation, timeout = _Object$assign.timeout;
+        var timer = setTimeout(function() {
+          timer = setTimeout(function() {
+            timer = null;
+            resolve(isViolation ? false : undefined);
+          }, 0);
+        }, timeout);
+        axe.utils.respondable(node.contentWindow, 'axe.ping', null, undefined, function() {
+          if (timer !== null) {
+            clearTimeout(timer);
+            resolve(true);
+          }
+        });
+      },
+      options: {
+        isViolation: false
+      }
+    }, {
+      id: 'css-orientation-lock',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var _ref9 = context || {}, _ref9$cssom = _ref9.cssom, cssom = _ref9$cssom === void 0 ? undefined : _ref9$cssom;
+        if (!cssom || !cssom.length) {
+          return undefined;
         }
-        return undefined;
+        var rulesGroupByDocumentFragment = cssom.reduce(function(out, _ref10) {
+          var sheet = _ref10.sheet, root = _ref10.root, shadowId = _ref10.shadowId;
+          var key = shadowId ? shadowId : 'topDocument';
+          if (!out[key]) {
+            out[key] = {
+              root: root,
+              rules: []
+            };
+          }
+          if (!sheet || !sheet.cssRules) {
+            return out;
+          }
+          var rules = Array.from(sheet.cssRules);
+          out[key].rules = out[key].rules.concat(rules);
+          return out;
+        }, {});
+        var isLocked = false;
+        var relatedElements = [];
+        Object.keys(rulesGroupByDocumentFragment).forEach(function(key) {
+          var _rulesGroupByDocument = rulesGroupByDocumentFragment[key], root = _rulesGroupByDocument.root, rules = _rulesGroupByDocument.rules;
+          var mediaRules = rules.filter(function(r) {
+            return r.type === 4;
+          });
+          if (!mediaRules || !mediaRules.length) {
+            return;
+          }
+          var orientationRules = mediaRules.filter(function(r) {
+            var cssText = r.cssText;
+            return /orientation:\s*landscape/i.test(cssText) || /orientation:\s*portrait/i.test(cssText);
+          });
+          if (!orientationRules || !orientationRules.length) {
+            return;
+          }
+          orientationRules.forEach(function(r) {
+            if (!r.cssRules.length) {
+              return;
+            }
+            Array.from(r.cssRules).forEach(function(cssRule) {
+              if (!cssRule.selectorText) {
+                return;
+              }
+              if (cssRule.style.length <= 0) {
+                return;
+              }
+              var transformStyleValue = cssRule.style.transform || cssRule.style.webkitTransform || cssRule.style.msTransform || false;
+              if (!transformStyleValue) {
+                return;
+              }
+              var rotate = transformStyleValue.match(/rotate\(([^)]+)deg\)/);
+              var deg = parseInt(rotate && rotate[1] || 0);
+              var locked = deg % 90 === 0 && deg % 180 !== 0;
+              if (locked && cssRule.selectorText.toUpperCase() !== 'HTML') {
+                var selector = cssRule.selectorText;
+                var elms = Array.from(root.querySelectorAll(selector));
+                if (elms && elms.length) {
+                  relatedElements = relatedElements.concat(elms);
+                }
+              }
+              isLocked = locked;
+            });
+          });
+        });
+        if (!isLocked) {
+          return true;
+        }
+        if (relatedElements.length) {
+          this.relatedNodes(relatedElements);
+        }
+        return false;
       }
     }, {
       id: 'meta-viewport-large',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         options = options || {};
         var params, content = node.getAttribute('content') || '', parsedParams = content.split(/[;,]/), result = {}, minimum = options.scaleMinimum || 2, lowerBound = options.lowerBound || false;
         for (var i = 0, l = parsedParams.length; i < l; i++) {
@@ -6684,9 +11781,11 @@
           return true;
         }
         if (!lowerBound && result['user-scalable'] === 'no') {
+          this.data('user-scalable=no');
           return false;
         }
         if (result['maximum-scale'] && parseFloat(result['maximum-scale']) < minimum) {
+          this.data('maximum-scale');
           return false;
         }
         return true;
@@ -6697,7 +11796,7 @@
       }
     }, {
       id: 'meta-viewport',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         options = options || {};
         var params, content = node.getAttribute('content') || '', parsedParams = content.split(/[;,]/), result = {}, minimum = options.scaleMinimum || 2, lowerBound = options.lowerBound || false;
         for (var i = 0, l = parsedParams.length; i < l; i++) {
@@ -6711,9 +11810,11 @@
           return true;
         }
         if (!lowerBound && result['user-scalable'] === 'no') {
+          this.data('user-scalable=no');
           return false;
         }
         if (result['maximum-scale'] && parseFloat(result['maximum-scale']) < minimum) {
+          this.data('maximum-scale');
           return false;
         }
         return true;
@@ -6723,18 +11824,18 @@
       }
     }, {
       id: 'header-present',
-      evaluate: function evaluate(node, options, virtualNode) {
-        return !!node.querySelector('h1, h2, h3, h4, h5, h6, [role="heading"]');
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        return !!axe.utils.querySelectorAll(virtualNode, 'h1, h2, h3, h4, h5, h6, [role="heading"]')[0];
       }
     }, {
       id: 'heading-order',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var ariaHeadingLevel = node.getAttribute('aria-level');
         if (ariaHeadingLevel !== null) {
           this.data(parseInt(ariaHeadingLevel, 10));
           return true;
         }
-        var headingLevel = node.tagName.match(/H(\d)/);
+        var headingLevel = node.nodeName.toUpperCase().match(/H(\d)/);
         if (headingLevel) {
           this.data(parseInt(headingLevel[1], 10));
           return true;
@@ -6755,33 +11856,27 @@
         return results;
       }
     }, {
-      id: 'href-no-hash',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var href = node.getAttribute('href');
-        if (href === '#') {
-          return false;
-        }
-        return true;
-      }
-    }, {
       id: 'internal-link-present',
-      evaluate: function evaluate(node, options, virtualNode) {
-        return !!node.querySelector('a[href^="#"]');
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var links = axe.utils.querySelectorAll(virtualNode, 'a[href]');
+        return links.some(function(vLink) {
+          return /^#[^/!]/.test(vLink.actualNode.getAttribute('href'));
+        });
       }
     }, {
       id: 'landmark',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         return axe.utils.querySelectorAll(virtualNode, 'main, [role="main"]').length > 0;
       }
     }, {
       id: 'meta-refresh',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var content = node.getAttribute('content') || '', parsedParams = content.split(/[;,]/);
         return content === '' || parsedParams[0] === '0';
       }
     }, {
       id: 'p-as-heading',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var siblings = Array.from(node.parentNode.children);
         var currentIndex = siblings.indexOf(node);
         options = options || {};
@@ -6846,7 +11941,7 @@
         if (!nextStyle || !isHeaderStyle(currStyle, nextStyle, margins)) {
           return true;
         }
-        var blockquote = axe.commons.dom.findUp(node, 'blockquote');
+        var blockquote = axe.commons.dom.findUpVirtual(virtualNode, 'blockquote');
         if (blockquote && blockquote.nodeName.toUpperCase() === 'BLOCKQUOTE') {
           return undefined;
         }
@@ -6871,42 +11966,45 @@
       }
     }, {
       id: 'region',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var _axe$commons2 = axe.commons, dom = _axe$commons2.dom, aria = _axe$commons2.aria;
-        function getSkiplink(virtualNode) {
-          var firstLink = axe.utils.querySelectorAll(virtualNode, 'a[href]')[0];
-          if (firstLink && axe.commons.dom.getElementByReference(firstLink.actualNode, 'href')) {
-            return firstLink.actualNode;
-          }
-        }
-        var skipLink = getSkiplink(virtualNode);
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var _axe$commons13 = axe.commons, dom = _axe$commons13.dom, aria = _axe$commons13.aria;
         var landmarkRoles = aria.getRolesByType('landmark');
         var implicitLandmarks = landmarkRoles.reduce(function(arr, role) {
           return arr.concat(aria.implicitNodes(role));
         }, []).filter(function(r) {
           return r !== null;
-        }).map(function(r) {
-          return r.toUpperCase();
         });
-        function isSkipLink(node) {
-          return skipLink && skipLink === node;
-        }
-        function isLandmark(node) {
-          if (node.hasAttribute('role')) {
-            return landmarkRoles.includes(node.getAttribute('role').toLowerCase());
-          } else {
-            return implicitLandmarks.includes(node.nodeName.toUpperCase());
+        function isRegion(virtualNode) {
+          var node = virtualNode.actualNode;
+          var explicitRole = axe.commons.aria.getRole(node, {
+            noImplicit: true
+          });
+          var ariaLive = (node.getAttribute('aria-live') || '').toLowerCase().trim();
+          if (explicitRole) {
+            return explicitRole === 'dialog' || landmarkRoles.includes(explicitRole);
           }
+          if ([ 'assertive', 'polite' ].includes(ariaLive)) {
+            return true;
+          }
+          return implicitLandmarks.some(function(implicitSelector) {
+            var matches = axe.utils.matchesSelector(node, implicitSelector);
+            if (node.nodeName.toUpperCase() === 'FORM') {
+              var titleAttr = node.getAttribute('title');
+              var title = titleAttr && titleAttr.trim() !== '' ? axe.commons.text.sanitize(titleAttr) : null;
+              return matches && (!!aria.labelVirtual(virtualNode) || !!title);
+            }
+            return matches;
+          });
         }
         function findRegionlessElms(virtualNode) {
           var node = virtualNode.actualNode;
-          if (isLandmark(node) || isSkipLink(node) || !dom.isVisible(node, true)) {
+          if (isRegion(virtualNode) || dom.isSkipLink(virtualNode.actualNode) && dom.getElementByReference(virtualNode.actualNode, 'href') || !dom.isVisible(node, true)) {
             return [];
           } else if (dom.hasContent(node, true)) {
             return [ node ];
           } else {
-            return virtualNode.children.filter(function(_ref7) {
-              var actualNode = _ref7.actualNode;
+            return virtualNode.children.filter(function(_ref11) {
+              var actualNode = _ref11.actualNode;
               return actualNode.nodeType === 1;
             }).map(findRegionlessElms).reduce(function(a, b) {
               return a.concat(b);
@@ -6922,15 +12020,16 @@
       }
     }, {
       id: 'skip-link',
-      evaluate: function evaluate(node, options, virtualNode) {
-        return axe.commons.dom.isFocusable(axe.commons.dom.getElementByReference(node, 'href'));
-      },
-      after: function after(results, options) {
-        return [ results[0] ];
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var target = axe.commons.dom.getElementByReference(node, 'href');
+        if (target) {
+          return axe.commons.dom.isVisible(target, true) || undefined;
+        }
+        return false;
       }
     }, {
       id: 'unique-frame-title',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var title = axe.commons.text.sanitize(node.title).trim().toLowerCase();
         this.data(title);
         return true;
@@ -6946,58 +12045,21 @@
         return results;
       }
     }, {
-      id: 'aria-label',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var label = node.getAttribute('aria-label');
-        return !!(label ? axe.commons.text.sanitize(label).trim() : '');
-      }
-    }, {
-      id: 'aria-labelledby',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var getIdRefs = axe.commons.dom.idrefs;
-        return getIdRefs(node, 'aria-labelledby').some(function(elm) {
-          return elm && axe.commons.text.accessibleText(elm, true);
-        });
-      }
-    }, {
-      id: 'button-has-visible-text',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var nodeName = node.nodeName.toUpperCase();
-        var role = node.getAttribute('role');
-        var label = void 0;
-        if (nodeName === 'BUTTON' || role === 'button' && nodeName !== 'INPUT') {
-          label = axe.commons.text.accessibleText(node);
-          this.data(label);
-          return !!label;
-        } else {
-          return false;
-        }
-      }
-    }, {
-      id: 'doc-has-title',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var title = document.title;
-        return !!(title ? axe.commons.text.sanitize(title).trim() : '');
-      }
-    }, {
-      id: 'duplicate-id',
-      evaluate: function evaluate(node, options, virtualNode) {
-        if (!node.getAttribute('id').trim()) {
+      id: 'duplicate-id-active',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var id = node.getAttribute('id').trim();
+        if (!id) {
           return true;
         }
-        var id = axe.commons.utils.escapeSelector(node.getAttribute('id'));
-        var matchingNodes = document.querySelectorAll('[id="' + id + '"]');
-        var related = [];
-        for (var i = 0; i < matchingNodes.length; i++) {
-          if (matchingNodes[i] !== node) {
-            related.push(matchingNodes[i]);
-          }
+        var root = axe.commons.dom.getRootNode(node);
+        var matchingNodes = Array.from(root.querySelectorAll('[id="'.concat(axe.utils.escapeSelector(id), '"]'))).filter(function(foundNode) {
+          return foundNode !== node;
+        });
+        if (matchingNodes.length) {
+          this.relatedNodes(matchingNodes);
         }
-        if (related.length) {
-          this.relatedNodes(related);
-        }
-        this.data(node.getAttribute('id'));
-        return matchingNodes.length <= 1;
+        this.data(id);
+        return matchingNodes.length === 0;
       },
       after: function after(results, options) {
         var uniqueIds = [];
@@ -7010,69 +12072,170 @@
         });
       }
     }, {
+      id: 'duplicate-id-aria',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var id = node.getAttribute('id').trim();
+        if (!id) {
+          return true;
+        }
+        var root = axe.commons.dom.getRootNode(node);
+        var matchingNodes = Array.from(root.querySelectorAll('[id="'.concat(axe.utils.escapeSelector(id), '"]'))).filter(function(foundNode) {
+          return foundNode !== node;
+        });
+        if (matchingNodes.length) {
+          this.relatedNodes(matchingNodes);
+        }
+        this.data(id);
+        return matchingNodes.length === 0;
+      },
+      after: function after(results, options) {
+        var uniqueIds = [];
+        return results.filter(function(r) {
+          if (uniqueIds.indexOf(r.data) === -1) {
+            uniqueIds.push(r.data);
+            return true;
+          }
+          return false;
+        });
+      }
+    }, {
+      id: 'duplicate-id',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var id = node.getAttribute('id').trim();
+        if (!id) {
+          return true;
+        }
+        var root = axe.commons.dom.getRootNode(node);
+        var matchingNodes = Array.from(root.querySelectorAll('[id="'.concat(axe.utils.escapeSelector(id), '"]'))).filter(function(foundNode) {
+          return foundNode !== node;
+        });
+        if (matchingNodes.length) {
+          this.relatedNodes(matchingNodes);
+        }
+        this.data(id);
+        return matchingNodes.length === 0;
+      },
+      after: function after(results, options) {
+        var uniqueIds = [];
+        return results.filter(function(r) {
+          if (uniqueIds.indexOf(r.data) === -1) {
+            uniqueIds.push(r.data);
+            return true;
+          }
+          return false;
+        });
+      }
+    }, {
+      id: 'aria-label',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var _axe$commons14 = axe.commons, text = _axe$commons14.text, aria = _axe$commons14.aria;
+        return !!text.sanitize(aria.arialabelText(node));
+      }
+    }, {
+      id: 'aria-labelledby',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var _axe$commons15 = axe.commons, text = _axe$commons15.text, aria = _axe$commons15.aria;
+        return !!text.sanitize(aria.arialabelledbyText(node));
+      }
+    }, {
+      id: 'avoid-inline-spacing',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var inlineSpacingCssProperties = [ 'line-height', 'letter-spacing', 'word-spacing' ];
+        var overriddenProperties = inlineSpacingCssProperties.filter(function(property) {
+          if (node.style.getPropertyPriority(property) === 'important') {
+            return property;
+          }
+        });
+        if (overriddenProperties.length > 0) {
+          this.data(overriddenProperties);
+          return false;
+        }
+        return true;
+      }
+    }, {
+      id: 'button-has-visible-text',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var nodeName = node.nodeName.toUpperCase();
+        var role = node.getAttribute('role');
+        var label;
+        if (nodeName === 'BUTTON' || role === 'button' && nodeName !== 'INPUT') {
+          label = axe.commons.text.accessibleTextVirtual(virtualNode);
+          this.data(label);
+          return !!label;
+        } else {
+          return false;
+        }
+      }
+    }, {
+      id: 'doc-has-title',
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var title = document.title;
+        return !!(title ? axe.commons.text.sanitize(title).trim() : '');
+      }
+    }, {
       id: 'exists',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         return true;
       }
     }, {
       id: 'has-alt',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var nn = node.nodeName.toLowerCase();
         return node.hasAttribute('alt') && (nn === 'img' || nn === 'input' || nn === 'area');
       }
     }, {
       id: 'has-visible-text',
-      evaluate: function evaluate(node, options, virtualNode) {
-        return axe.commons.text.accessibleText(node).length > 0;
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        return axe.commons.text.accessibleTextVirtual(virtualNode).length > 0;
       }
     }, {
       id: 'is-on-screen',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         return axe.commons.dom.isVisible(node, false) && !axe.commons.dom.isOffscreen(node);
       }
     }, {
       id: 'non-empty-alt',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var label = node.getAttribute('alt');
         return !!(label ? axe.commons.text.sanitize(label).trim() : '');
       }
     }, {
       id: 'non-empty-if-present',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var nodeName = node.nodeName.toUpperCase();
         var type = (node.getAttribute('type') || '').toLowerCase();
         var label = node.getAttribute('value');
         this.data(label);
-        if (nodeName === 'INPUT' && [ 'submit', 'reset' ].indexOf(type) !== -1) {
+        if (nodeName === 'INPUT' && [ 'submit', 'reset' ].includes(type)) {
           return label === null;
         }
         return false;
       }
     }, {
       id: 'non-empty-title',
-      evaluate: function evaluate(node, options, virtualNode) {
-        var title = node.getAttribute('title');
-        return !!(title ? axe.commons.text.sanitize(title).trim() : '');
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        var text = axe.commons.text;
+        return !!text.sanitize(text.titleText(node));
       }
     }, {
       id: 'non-empty-value',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var label = node.getAttribute('value');
         return !!(label ? axe.commons.text.sanitize(label).trim() : '');
       }
     }, {
       id: 'role-none',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         return node.getAttribute('role') === 'none';
       }
     }, {
       id: 'role-presentation',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         return node.getAttribute('role') === 'presentation';
       }
     }, {
       id: 'caption-faked',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var table = axe.commons.table.toGrid(node);
         var firstRow = table[0];
         if (table.length <= 1 || firstRow.length <= 1 || node.rows.length <= 1) {
@@ -7084,17 +12247,17 @@
       }
     }, {
       id: 'has-caption',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         return !!node.caption;
       }
     }, {
       id: 'has-summary',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         return !!node.summary;
       }
     }, {
       id: 'has-th',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var row, cell, badCells = [];
         for (var rowIndex = 0, rowLength = node.rows.length; rowIndex < rowLength; rowIndex++) {
           row = node.rows[rowIndex];
@@ -7113,7 +12276,7 @@
       }
     }, {
       id: 'html5-scope',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         if (!axe.commons.dom.isHTML5(document)) {
           return true;
         }
@@ -7121,12 +12284,12 @@
       }
     }, {
       id: 'same-caption-summary',
-      evaluate: function evaluate(node, options, virtualNode) {
-        return !!(node.summary && node.caption) && node.summary === axe.commons.text.accessibleText(node.caption);
+      evaluate: function evaluate(node, options, virtualNode, context) {
+        return !!(node.summary && node.caption) && node.summary.toLowerCase() === axe.commons.text.accessibleText(node.caption).toLowerCase();
       }
     }, {
       id: 'scope-value',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         options = options || {};
         var value = node.getAttribute('scope').toLowerCase();
         var validVals = [ 'row', 'col', 'rowgroup', 'colgroup' ] || options.values;
@@ -7134,16 +12297,15 @@
       }
     }, {
       id: 'td-has-header',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var tableUtils = axe.commons.table;
         var badCells = [];
         var cells = tableUtils.getAllCells(node);
         cells.forEach(function(cell) {
           if (axe.commons.dom.hasContent(cell) && tableUtils.isDataCell(cell) && !axe.commons.aria.label(cell)) {
-            var hasHeaders = tableUtils.getHeaders(cell);
-            hasHeaders = hasHeaders.reduce(function(hasHeaders, header) {
-              return hasHeaders || header !== null && !!axe.commons.dom.hasContent(header);
-            }, false);
+            var hasHeaders = tableUtils.getHeaders(cell).some(function(header) {
+              return header !== null && !!axe.commons.dom.hasContent(header);
+            });
             if (!hasHeaders) {
               badCells.push(cell);
             }
@@ -7157,7 +12319,7 @@
       }
     }, {
       id: 'td-headers-attr',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var cells = [];
         for (var rowIndex = 0, rowLength = node.rows.length; rowIndex < rowLength; rowIndex++) {
           var row = node.rows[rowIndex];
@@ -7202,7 +12364,7 @@
       }
     }, {
       id: 'th-has-data-cells',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var tableUtils = axe.commons.table;
         var cells = tableUtils.getAllCells(node);
         var checkResult = this;
@@ -7224,34 +12386,35 @@
           return cell.nodeName.toUpperCase() === 'TH' || [ 'rowheader', 'columnheader' ].indexOf(cell.getAttribute('role')) !== -1;
         });
         var tableGrid = tableUtils.toGrid(node);
-        var out = headers.reduce(function(res, header) {
+        var out = true;
+        headers.forEach(function(header) {
           if (header.getAttribute('id') && reffedHeaders.includes(header.getAttribute('id'))) {
-            return !res ? res : true;
+            return;
           }
-          var hasCell = false;
           var pos = tableUtils.getCellPosition(header, tableGrid);
+          var hasCell = false;
           if (tableUtils.isColumnHeader(header)) {
-            hasCell = tableUtils.traverse('down', pos, tableGrid).reduce(function(out, cell) {
-              return out || axe.commons.dom.hasContent(cell) && !tableUtils.isColumnHeader(cell);
-            }, false);
+            hasCell = tableUtils.traverse('down', pos, tableGrid).find(function(cell) {
+              return !tableUtils.isColumnHeader(cell);
+            });
           }
           if (!hasCell && tableUtils.isRowHeader(header)) {
-            hasCell = tableUtils.traverse('right', pos, tableGrid).reduce(function(out, cell) {
-              return out || axe.commons.dom.hasContent(cell) && !tableUtils.isRowHeader(cell);
-            }, false);
+            hasCell = tableUtils.traverse('right', pos, tableGrid).find(function(cell) {
+              return !tableUtils.isRowHeader(cell);
+            });
           }
           if (!hasCell) {
             checkResult.relatedNodes(header);
           }
-          return res && hasCell;
-        }, true);
+          out = out && hasCell;
+        });
         return out ? true : undefined;
       }
     }, {
       id: 'hidden-content',
-      evaluate: function evaluate(node, options, virtualNode) {
+      evaluate: function evaluate(node, options, virtualNode, context) {
         var whitelist = [ 'SCRIPT', 'HEAD', 'TITLE', 'NOSCRIPT', 'STYLE', 'TEMPLATE' ];
-        if (!whitelist.includes(node.tagName.toUpperCase()) && axe.commons.dom.hasContent(virtualNode)) {
+        if (!whitelist.includes(node.nodeName.toUpperCase()) && axe.commons.dom.hasContentVirtual(virtualNode)) {
           var styles = window.getComputedStyle(node);
           if (styles.getPropertyValue('display') === 'none') {
             return undefined;
@@ -7268,946 +12431,2040 @@
     } ],
     commons: function() {
       var commons = {};
-      var aria = commons.aria = {}, lookupTables = aria._lut = {};
-      lookupTables.attributes = {
+      var aria = commons.aria = {};
+      var lookupTable = aria.lookupTable = {};
+      var isNull = function isNull(value) {
+        return value === null;
+      };
+      var isNotNull = function isNotNull(value) {
+        return value !== null;
+      };
+      lookupTable.attributes = {
         'aria-activedescendant': {
-          type: 'idref'
+          type: 'idref',
+          allowEmpty: true,
+          unsupported: false
         },
         'aria-atomic': {
           type: 'boolean',
-          values: [ 'true', 'false' ]
+          values: [ 'true', 'false' ],
+          unsupported: false
         },
         'aria-autocomplete': {
           type: 'nmtoken',
-          values: [ 'inline', 'list', 'both', 'none' ]
+          values: [ 'inline', 'list', 'both', 'none' ],
+          unsupported: false
         },
         'aria-busy': {
           type: 'boolean',
-          values: [ 'true', 'false' ]
+          values: [ 'true', 'false' ],
+          unsupported: false
         },
         'aria-checked': {
           type: 'nmtoken',
-          values: [ 'true', 'false', 'mixed', 'undefined' ]
+          values: [ 'true', 'false', 'mixed', 'undefined' ],
+          unsupported: false
         },
         'aria-colcount': {
-          type: 'int'
+          type: 'int',
+          unsupported: false
         },
         'aria-colindex': {
-          type: 'int'
+          type: 'int',
+          unsupported: false
         },
         'aria-colspan': {
-          type: 'int'
+          type: 'int',
+          unsupported: false
         },
         'aria-controls': {
-          type: 'idrefs'
+          type: 'idrefs',
+          allowEmpty: true,
+          unsupported: false
         },
         'aria-current': {
           type: 'nmtoken',
-          values: [ 'page', 'step', 'location', 'date', 'time', 'true', 'false' ]
+          allowEmpty: true,
+          values: [ 'page', 'step', 'location', 'date', 'time', 'true', 'false' ],
+          unsupported: false
         },
         'aria-describedby': {
-          type: 'idrefs'
+          type: 'idrefs',
+          allowEmpty: true,
+          unsupported: false
+        },
+        'aria-describedat': {
+          unsupported: true,
+          unstandardized: true
+        },
+        'aria-details': {
+          unsupported: true
         },
         'aria-disabled': {
           type: 'boolean',
-          values: [ 'true', 'false' ]
+          values: [ 'true', 'false' ],
+          unsupported: false
         },
         'aria-dropeffect': {
           type: 'nmtokens',
-          values: [ 'copy', 'move', 'reference', 'execute', 'popup', 'none' ]
+          values: [ 'copy', 'move', 'reference', 'execute', 'popup', 'none' ],
+          unsupported: false
+        },
+        'aria-errormessage': {
+          type: 'idref',
+          allowEmpty: true,
+          unsupported: false
         },
         'aria-expanded': {
           type: 'nmtoken',
-          values: [ 'true', 'false', 'undefined' ]
+          values: [ 'true', 'false', 'undefined' ],
+          unsupported: false
         },
         'aria-flowto': {
-          type: 'idrefs'
+          type: 'idrefs',
+          allowEmpty: true,
+          unsupported: false
         },
         'aria-grabbed': {
           type: 'nmtoken',
-          values: [ 'true', 'false', 'undefined' ]
+          values: [ 'true', 'false', 'undefined' ],
+          unsupported: false
         },
         'aria-haspopup': {
-          type: 'boolean',
-          values: [ 'true', 'false' ]
+          type: 'nmtoken',
+          allowEmpty: true,
+          values: [ 'true', 'false', 'menu', 'listbox', 'tree', 'grid', 'dialog' ],
+          unsupported: false
         },
         'aria-hidden': {
           type: 'boolean',
-          values: [ 'true', 'false' ]
+          values: [ 'true', 'false' ],
+          unsupported: false
         },
         'aria-invalid': {
           type: 'nmtoken',
-          values: [ 'true', 'false', 'spelling', 'grammar' ]
+          allowEmpty: true,
+          values: [ 'true', 'false', 'spelling', 'grammar' ],
+          unsupported: false
+        },
+        'aria-keyshortcuts': {
+          type: 'string',
+          allowEmpty: true,
+          unsupported: false
         },
         'aria-label': {
-          type: 'string'
+          type: 'string',
+          allowEmpty: true,
+          unsupported: false
         },
         'aria-labelledby': {
-          type: 'idrefs'
+          type: 'idrefs',
+          allowEmpty: true,
+          unsupported: false
         },
         'aria-level': {
-          type: 'int'
+          type: 'int',
+          unsupported: false
         },
         'aria-live': {
           type: 'nmtoken',
-          values: [ 'off', 'polite', 'assertive' ]
+          values: [ 'off', 'polite', 'assertive' ],
+          unsupported: false
+        },
+        'aria-modal': {
+          type: 'boolean',
+          values: [ 'true', 'false' ],
+          unsupported: false
         },
         'aria-multiline': {
           type: 'boolean',
-          values: [ 'true', 'false' ]
+          values: [ 'true', 'false' ],
+          unsupported: false
         },
         'aria-multiselectable': {
           type: 'boolean',
-          values: [ 'true', 'false' ]
+          values: [ 'true', 'false' ],
+          unsupported: false
         },
         'aria-orientation': {
           type: 'nmtoken',
-          values: [ 'horizontal', 'vertical' ]
+          values: [ 'horizontal', 'vertical' ],
+          unsupported: false
         },
         'aria-owns': {
-          type: 'idrefs'
+          type: 'idrefs',
+          allowEmpty: true,
+          unsupported: false
+        },
+        'aria-placeholder': {
+          type: 'string',
+          allowEmpty: true,
+          unsupported: false
         },
         'aria-posinset': {
-          type: 'int'
+          type: 'int',
+          unsupported: false
         },
         'aria-pressed': {
           type: 'nmtoken',
-          values: [ 'true', 'false', 'mixed', 'undefined' ]
+          values: [ 'true', 'false', 'mixed', 'undefined' ],
+          unsupported: false
         },
         'aria-readonly': {
           type: 'boolean',
-          values: [ 'true', 'false' ]
+          values: [ 'true', 'false' ],
+          unsupported: false
         },
         'aria-relevant': {
           type: 'nmtokens',
-          values: [ 'additions', 'removals', 'text', 'all' ]
+          values: [ 'additions', 'removals', 'text', 'all' ],
+          unsupported: false
         },
         'aria-required': {
           type: 'boolean',
-          values: [ 'true', 'false' ]
+          values: [ 'true', 'false' ],
+          unsupported: false
+        },
+        'aria-roledescription': {
+          type: 'string',
+          allowEmpty: true,
+          unsupported: {
+            exceptions: [ 'button', {
+              nodeName: 'input',
+              properties: {
+                type: [ 'button', 'checkbox', 'image', 'radio', 'reset', 'submit' ]
+              }
+            }, 'img', 'select', 'summary' ]
+          }
         },
         'aria-rowcount': {
-          type: 'int'
+          type: 'int',
+          unsupported: false
         },
         'aria-rowindex': {
-          type: 'int'
+          type: 'int',
+          unsupported: false
         },
         'aria-rowspan': {
-          type: 'int'
+          type: 'int',
+          unsupported: false
         },
         'aria-selected': {
           type: 'nmtoken',
-          values: [ 'true', 'false', 'undefined' ]
+          values: [ 'true', 'false', 'undefined' ],
+          unsupported: false
         },
         'aria-setsize': {
-          type: 'int'
+          type: 'int',
+          unsupported: false
         },
         'aria-sort': {
           type: 'nmtoken',
-          values: [ 'ascending', 'descending', 'other', 'none' ]
+          values: [ 'ascending', 'descending', 'other', 'none' ],
+          unsupported: false
         },
         'aria-valuemax': {
-          type: 'decimal'
+          type: 'decimal',
+          unsupported: false
         },
         'aria-valuemin': {
-          type: 'decimal'
+          type: 'decimal',
+          unsupported: false
         },
         'aria-valuenow': {
-          type: 'decimal'
+          type: 'decimal',
+          unsupported: false
         },
         'aria-valuetext': {
-          type: 'string'
+          type: 'string',
+          unsupported: false
         }
       };
-      lookupTables.globalAttributes = [ 'aria-atomic', 'aria-busy', 'aria-controls', 'aria-current', 'aria-describedby', 'aria-disabled', 'aria-dropeffect', 'aria-flowto', 'aria-grabbed', 'aria-haspopup', 'aria-hidden', 'aria-invalid', 'aria-label', 'aria-labelledby', 'aria-live', 'aria-owns', 'aria-relevant' ];
-      lookupTables.role = {
+      lookupTable.globalAttributes = [ 'aria-atomic', 'aria-busy', 'aria-controls', 'aria-current', 'aria-describedby', 'aria-disabled', 'aria-dropeffect', 'aria-flowto', 'aria-grabbed', 'aria-haspopup', 'aria-hidden', 'aria-invalid', 'aria-keyshortcuts', 'aria-label', 'aria-labelledby', 'aria-live', 'aria-owns', 'aria-relevant', 'aria-roledescription' ];
+      lookupTable.role = {
         alert: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
         },
         alertdialog: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-modal', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'dialog', 'section' ]
         },
         application: {
           type: 'landmark',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'article', 'audio', 'embed', 'iframe', 'object', 'section', 'svg', 'video' ]
         },
         article: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-posinset', 'aria-setsize', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'article' ]
+          implicit: [ 'article' ],
+          unsupported: false
         },
         banner: {
           type: 'landmark',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'header' ]
+          implicit: [ 'header' ],
+          unsupported: false,
+          allowedElements: [ 'section' ]
         },
         button: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-expanded', 'aria-pressed' ]
+            allowed: [ 'aria-expanded', 'aria-pressed', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: null,
-          implicit: [ 'button', 'input[type="button"]', 'input[type="image"]', 'input[type="reset"]', 'input[type="submit"]', 'summary' ]
+          implicit: [ 'button', 'input[type="button"]', 'input[type="image"]', 'input[type="reset"]', 'input[type="submit"]', 'summary' ],
+          unsupported: false,
+          allowedElements: [ {
+            nodeName: 'a',
+            attributes: {
+              href: isNotNull
+            }
+          } ]
         },
         cell: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-colindex', 'aria-colspan', 'aria-rowindex', 'aria-rowspan' ]
+            allowed: [ 'aria-colindex', 'aria-colspan', 'aria-rowindex', 'aria-rowspan', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: [ 'row' ],
-          implicit: [ 'td', 'th' ]
+          implicit: [ 'td', 'th' ],
+          unsupported: false
         },
         checkbox: {
           type: 'widget',
           attributes: {
-            required: [ 'aria-checked' ]
+            allowed: [ 'aria-checked', 'aria-required', 'aria-readonly', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: null,
-          implicit: [ 'input[type="checkbox"]' ]
+          implicit: [ 'input[type="checkbox"]' ],
+          unsupported: false,
+          allowedElements: [ 'button' ]
         },
         columnheader: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-expanded', 'aria-sort', 'aria-readonly', 'aria-selected', 'aria-required' ]
+            allowed: [ 'aria-colindex', 'aria-colspan', 'aria-expanded', 'aria-rowindex', 'aria-rowspan', 'aria-required', 'aria-readonly', 'aria-selected', 'aria-sort', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: [ 'row' ],
-          implicit: [ 'th' ]
+          implicit: [ 'th' ],
+          unsupported: false
         },
         combobox: {
           type: 'composite',
           attributes: {
-            required: [ 'aria-expanded' ],
-            allowed: [ 'aria-autocomplete', 'aria-required', 'aria-activedescendant' ]
+            allowed: [ 'aria-autocomplete', 'aria-required', 'aria-activedescendant', 'aria-orientation', 'aria-errormessage' ],
+            required: [ 'aria-expanded' ]
           },
           owned: {
             all: [ 'listbox', 'textbox' ]
           },
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ {
+            nodeName: 'input',
+            properties: {
+              type: 'text'
+            }
+          } ]
         },
         command: {
           nameFrom: [ 'author' ],
-          type: 'abstract'
+          type: 'abstract',
+          unsupported: false
         },
         complementary: {
           type: 'landmark',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'aside' ]
+          implicit: [ 'aside' ],
+          unsupported: false,
+          allowedElements: [ 'section' ]
         },
         composite: {
           nameFrom: [ 'author' ],
-          type: 'abstract'
+          type: 'abstract',
+          unsupported: false
         },
         contentinfo: {
           type: 'landmark',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'footer' ]
+          implicit: [ 'footer' ],
+          unsupported: false,
+          allowedElements: [ 'section' ]
         },
         definition: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'dd' ]
+          implicit: [ 'dd', 'dfn' ],
+          unsupported: false
         },
         dialog: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-modal', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'dialog' ]
+          implicit: [ 'dialog' ],
+          unsupported: false,
+          allowedElements: [ 'section' ]
         },
         directory: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'ol', 'ul' ]
         },
         document: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'body' ]
+          implicit: [ 'body' ],
+          unsupported: false,
+          allowedElements: [ 'article', 'embed', 'iframe', 'object', 'section', 'svg' ]
         },
-        form: {
+        'doc-abstract': {
+          type: 'section',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          nameFrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-acknowledgments': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          nameFrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-afterword': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          nameFrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-appendix': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          nameFrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-backlink': {
+          type: 'link',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          nameFrom: [ 'author', 'contents' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ {
+            nodeName: 'a',
+            attributes: {
+              href: isNotNull
+            }
+          } ]
+        },
+        'doc-biblioentry': {
+          type: 'listitem',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-level', 'aria-posinset', 'aria-setsize', 'aria-errormessage' ]
+          },
+          owned: null,
+          nameFrom: [ 'author' ],
+          context: [ 'doc-bibliography' ],
+          unsupported: false,
+          allowedElements: [ 'li' ]
+        },
+        'doc-bibliography': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: {
+            one: [ 'doc-biblioentry' ]
+          },
+          nameFrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-biblioref': {
+          type: 'link',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          nameFrom: [ 'author', 'contents' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ {
+            nodeName: 'a',
+            attributes: {
+              href: isNotNull
+            }
+          } ]
+        },
+        'doc-chapter': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-colophon': {
+          type: 'section',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-conclusion': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-cover': {
+          type: 'img',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false
+        },
+        'doc-credit': {
+          type: 'section',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-credits': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-dedication': {
+          type: 'section',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-endnote': {
+          type: 'listitem',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-level', 'aria-posinset', 'aria-setsize', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: [ 'doc-endnotes' ],
+          unsupported: false,
+          allowedElements: [ 'li' ]
+        },
+        'doc-endnotes': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: {
+            one: [ 'doc-endnote' ]
+          },
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-epigraph': {
+          type: 'section',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false
+        },
+        'doc-epilogue': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-errata': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-example': {
+          type: 'section',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'aside', 'section' ]
+        },
+        'doc-footnote': {
+          type: 'section',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'aside', 'footer', 'header' ]
+        },
+        'doc-foreword': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-glossary': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: [ 'term', 'definition' ],
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'dl' ]
+        },
+        'doc-glossref': {
+          type: 'link',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author', 'contents' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ {
+            nodeName: 'a',
+            attributes: {
+              href: isNotNull
+            }
+          } ]
+        },
+        'doc-index': {
+          type: 'navigation',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'nav', 'section' ]
+        },
+        'doc-introduction': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-noteref': {
+          type: 'link',
+          attributes: {
+            allowed: [ 'aria-expanded' ]
+          },
+          owned: null,
+          namefrom: [ 'author', 'contents' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ {
+            nodeName: 'a',
+            attributes: {
+              href: isNotNull
+            }
+          } ]
+        },
+        'doc-notice': {
+          type: 'note',
+          attributes: {
+            allowed: [ 'aria-expanded' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-pagebreak': {
+          type: 'separator',
+          attributes: {
+            allowed: [ 'aria-expanded' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'hr' ]
+        },
+        'doc-pagelist': {
+          type: 'navigation',
+          attributes: {
+            allowed: [ 'aria-expanded' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'nav', 'section' ]
+        },
+        'doc-part': {
           type: 'landmark',
           attributes: {
             allowed: [ 'aria-expanded' ]
           },
           owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-preface': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-prologue': {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-pullquote': {
+          type: 'none',
+          attributes: {
+            allowed: [ 'aria-expanded' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'aside', 'section' ]
+        },
+        'doc-qna': {
+          type: 'section',
+          attributes: {
+            allowed: [ 'aria-expanded' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        'doc-subtitle': {
+          type: 'sectionhead',
+          attributes: {
+            allowed: [ 'aria-expanded' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: {
+            nodeName: [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ]
+          }
+        },
+        'doc-tip': {
+          type: 'note',
+          attributes: {
+            allowed: [ 'aria-expanded' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'aside' ]
+        },
+        'doc-toc': {
+          type: 'navigation',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          namefrom: [ 'author' ],
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'nav', 'section' ]
+        },
+        feed: {
+          type: 'structure',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: {
+            one: [ 'article' ]
+          },
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'form' ]
+          unsupported: false,
+          allowedElements: [ 'article', 'aside', 'section' ]
+        },
+        figure: {
+          type: 'structure',
+          unsupported: false
+        },
+        form: {
+          type: 'landmark',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          nameFrom: [ 'author' ],
+          context: null,
+          implicit: [ 'form' ],
+          unsupported: false
         },
         grid: {
           type: 'composite',
           attributes: {
-            allowed: [ 'aria-level', 'aria-multiselectable', 'aria-readonly', 'aria-activedescendant', 'aria-expanded' ]
+            allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-colcount', 'aria-level', 'aria-multiselectable', 'aria-readonly', 'aria-rowcount', 'aria-errormessage' ]
           },
           owned: {
             one: [ 'rowgroup', 'row' ]
           },
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'table' ]
+          implicit: [ 'table' ],
+          unsupported: false
         },
         gridcell: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-selected', 'aria-readonly', 'aria-expanded', 'aria-required' ]
+            allowed: [ 'aria-colindex', 'aria-colspan', 'aria-expanded', 'aria-rowindex', 'aria-rowspan', 'aria-selected', 'aria-readonly', 'aria-required', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: [ 'row' ],
-          implicit: [ 'td', 'th' ]
+          implicit: [ 'td', 'th' ],
+          unsupported: false
         },
         group: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-activedescendant', 'aria-expanded' ]
+            allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'details', 'optgroup' ]
+          implicit: [ 'details', 'optgroup' ],
+          unsupported: false,
+          allowedElements: [ 'dl', 'figcaption', 'fieldset', 'figure', 'footer', 'header', 'ol', 'ul' ]
         },
         heading: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-level', 'aria-expanded' ]
+            required: [ 'aria-level' ],
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: null,
-          implicit: [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ]
+          implicit: [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ],
+          unsupported: false
         },
         img: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'img' ]
+          implicit: [ 'img' ],
+          unsupported: false,
+          allowedElements: [ 'embed', 'iframe', 'object', 'svg' ]
         },
         input: {
           nameFrom: [ 'author' ],
-          type: 'abstract'
+          type: 'abstract',
+          unsupported: false
         },
         landmark: {
           nameFrom: [ 'author' ],
-          type: 'abstract'
+          type: 'abstract',
+          unsupported: false
         },
         link: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: null,
-          implicit: [ 'a[href]' ]
+          implicit: [ 'a[href]' ],
+          unsupported: false,
+          allowedElements: [ 'button', {
+            nodeName: 'input',
+            properties: {
+              type: [ 'image', 'button' ]
+            }
+          } ]
         },
         list: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: {
             all: [ 'listitem' ]
           },
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'ol', 'ul', 'dl' ]
+          implicit: [ 'ol', 'ul', 'dl' ],
+          unsupported: false
         },
         listbox: {
           type: 'composite',
           attributes: {
-            allowed: [ 'aria-activedescendant', 'aria-multiselectable', 'aria-required', 'aria-expanded' ]
+            allowed: [ 'aria-activedescendant', 'aria-multiselectable', 'aria-required', 'aria-expanded', 'aria-orientation', 'aria-errormessage' ]
           },
           owned: {
             all: [ 'option' ]
           },
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'select' ]
+          implicit: [ 'select' ],
+          unsupported: false,
+          allowedElements: [ 'ol', 'ul' ]
         },
         listitem: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-level', 'aria-posinset', 'aria-setsize', 'aria-expanded' ]
+            allowed: [ 'aria-level', 'aria-posinset', 'aria-setsize', 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: [ 'list' ],
-          implicit: [ 'li', 'dt' ]
+          implicit: [ 'li', 'dt' ],
+          unsupported: false
         },
         log: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
         },
         main: {
           type: 'landmark',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'main' ]
+          implicit: [ 'main' ],
+          unsupported: false,
+          allowedElements: [ 'article', 'section' ]
         },
         marquee: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-expanded' ]
-          },
-          owned: null,
-          nameFrom: [ 'author' ],
-          context: null
-        },
-        math: {
-          type: 'structure',
-          attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'math' ]
+          unsupported: false,
+          allowedElements: [ 'section' ]
+        },
+        math: {
+          type: 'structure',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
+          owned: null,
+          nameFrom: [ 'author' ],
+          context: null,
+          implicit: [ 'math' ],
+          unsupported: false
         },
         menu: {
           type: 'composite',
           attributes: {
-            allowed: [ 'aria-activedescendant', 'aria-expanded' ]
+            allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-orientation', 'aria-errormessage' ]
           },
           owned: {
             one: [ 'menuitem', 'menuitemradio', 'menuitemcheckbox' ]
           },
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'menu[type="context"]' ]
+          implicit: [ 'menu[type="context"]' ],
+          unsupported: false,
+          allowedElements: [ 'ol', 'ul' ]
         },
         menubar: {
           type: 'composite',
           attributes: {
-            allowed: [ 'aria-activedescendant', 'aria-expanded' ]
+            allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-orientation', 'aria-errormessage' ]
           },
-          owned: null,
+          owned: {
+            one: [ 'menuitem', 'menuitemradio', 'menuitemcheckbox' ]
+          },
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'ol', 'ul' ]
         },
         menuitem: {
           type: 'widget',
-          attributes: null,
+          attributes: {
+            allowed: [ 'aria-posinset', 'aria-setsize', 'aria-expanded', 'aria-errormessage' ]
+          },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: [ 'menu', 'menubar' ],
-          implicit: [ 'menuitem[type="command"]' ]
+          implicit: [ 'menuitem[type="command"]' ],
+          unsupported: false,
+          allowedElements: [ 'button', 'li', {
+            nodeName: 'iput',
+            properties: {
+              type: [ 'image', 'button' ]
+            }
+          }, {
+            nodeName: 'a',
+            attributes: {
+              href: isNotNull
+            }
+          } ]
         },
         menuitemcheckbox: {
           type: 'widget',
           attributes: {
-            required: [ 'aria-checked' ]
+            allowed: [ 'aria-checked', 'aria-posinset', 'aria-setsize', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: [ 'menu', 'menubar' ],
-          implicit: [ 'menuitem[type="checkbox"]' ]
+          implicit: [ 'menuitem[type="checkbox"]' ],
+          unsupported: false,
+          allowedElements: [ {
+            nodeName: [ 'button', 'li' ]
+          }, {
+            nodeName: 'input',
+            properties: {
+              type: [ 'checkbox', 'image', 'button' ]
+            }
+          }, {
+            nodeName: 'a',
+            attributes: {
+              href: isNotNull
+            }
+          } ]
         },
         menuitemradio: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-selected', 'aria-posinset', 'aria-setsize' ],
-            required: [ 'aria-checked' ]
+            allowed: [ 'aria-checked', 'aria-selected', 'aria-posinset', 'aria-setsize', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: [ 'menu', 'menubar' ],
-          implicit: [ 'menuitem[type="radio"]' ]
+          implicit: [ 'menuitem[type="radio"]' ],
+          unsupported: false,
+          allowedElements: [ {
+            nodeName: [ 'button', 'li' ]
+          }, {
+            nodeName: 'input',
+            properties: {
+              type: [ 'image', 'button', 'radio' ]
+            }
+          }, {
+            nodeName: 'a',
+            attributes: {
+              href: isNotNull
+            }
+          } ]
         },
         navigation: {
           type: 'landmark',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'nav' ]
+          implicit: [ 'nav' ],
+          unsupported: false,
+          allowedElements: [ 'section' ]
         },
         none: {
           type: 'structure',
           attributes: null,
           owned: null,
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ {
+            nodeName: [ 'article', 'aside', 'dl', 'embed', 'figcaption', 'fieldset', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'iframe', 'li', 'ol', 'section', 'ul' ]
+          }, {
+            nodeName: 'img',
+            attributes: {
+              alt: isNotNull
+            }
+          } ]
         },
         note: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'aside' ]
         },
         option: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-selected', 'aria-posinset', 'aria-setsize', 'aria-checked' ]
+            allowed: [ 'aria-selected', 'aria-posinset', 'aria-setsize', 'aria-checked', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: [ 'listbox' ],
-          implicit: [ 'option' ]
+          implicit: [ 'option' ],
+          unsupported: false,
+          allowedElements: [ {
+            nodeName: [ 'button', 'li' ]
+          }, {
+            nodeName: 'input',
+            properties: {
+              type: [ 'checkbox', 'button' ]
+            }
+          }, {
+            nodeName: 'a',
+            attributes: {
+              href: isNotNull
+            }
+          } ]
         },
         presentation: {
           type: 'structure',
           attributes: null,
           owned: null,
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ {
+            nodeName: [ 'article', 'aside', 'dl', 'embed', 'figcaption', 'fieldset', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'iframe', 'li', 'ol', 'section', 'ul' ]
+          }, {
+            nodeName: 'img',
+            attributes: {
+              alt: isNotNull
+            }
+          } ]
         },
         progressbar: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-valuetext', 'aria-valuenow', 'aria-valuemax', 'aria-valuemin' ]
+            allowed: [ 'aria-valuetext', 'aria-valuenow', 'aria-valuemax', 'aria-valuemin', 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'progress' ]
+          implicit: [ 'progress' ],
+          unsupported: false
         },
         radio: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-selected', 'aria-posinset', 'aria-setsize' ],
-            required: [ 'aria-checked' ]
+            allowed: [ 'aria-selected', 'aria-posinset', 'aria-setsize', 'aria-required', 'aria-errormessage', 'aria-checked' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: null,
-          implicit: [ 'input[type="radio"]' ]
+          implicit: [ 'input[type="radio"]' ],
+          unsupported: false,
+          allowedElements: [ {
+            nodeName: [ 'button', 'li' ]
+          }, {
+            nodeName: 'input',
+            properties: {
+              type: [ 'image', 'button' ]
+            }
+          } ]
         },
         radiogroup: {
           type: 'composite',
           attributes: {
-            allowed: [ 'aria-activedescendant', 'aria-required', 'aria-expanded' ]
+            allowed: [ 'aria-activedescendant', 'aria-required', 'aria-expanded', 'aria-readonly', 'aria-errormessage' ]
           },
           owned: {
             all: [ 'radio' ]
           },
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: {
+            nodeName: [ 'ol', 'ul' ]
+          }
         },
         range: {
           nameFrom: [ 'author' ],
-          type: 'abstract'
+          type: 'abstract',
+          unsupported: false
         },
         region: {
-          type: 'structure',
+          type: 'landmark',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'section' ]
+          implicit: [ 'section[aria-label]', 'section[aria-labelledby]', 'section[title]' ],
+          unsupported: false,
+          allowedElements: {
+            nodeName: [ 'article', 'aside' ]
+          }
         },
         roletype: {
-          type: 'abstract'
+          type: 'abstract',
+          unsupported: false
         },
         row: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-level', 'aria-selected', 'aria-activedescendant', 'aria-expanded' ]
+            allowed: [ 'aria-activedescendant', 'aria-colindex', 'aria-expanded', 'aria-level', 'aria-selected', 'aria-rowindex', 'aria-errormessage' ]
           },
           owned: {
             one: [ 'cell', 'columnheader', 'rowheader', 'gridcell' ]
           },
           nameFrom: [ 'author', 'contents' ],
           context: [ 'rowgroup', 'grid', 'treegrid', 'table' ],
-          implicit: [ 'tr' ]
+          implicit: [ 'tr' ],
+          unsupported: false
         },
         rowgroup: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-activedescendant', 'aria-expanded' ]
+            allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-errormessage' ]
           },
           owned: {
             all: [ 'row' ]
           },
           nameFrom: [ 'author', 'contents' ],
-          context: [ 'grid', 'table' ],
-          implicit: [ 'tbody', 'thead', 'tfoot' ]
+          context: [ 'grid', 'table', 'treegrid' ],
+          implicit: [ 'tbody', 'thead', 'tfoot' ],
+          unsupported: false
         },
         rowheader: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-sort', 'aria-required', 'aria-readonly', 'aria-expanded', 'aria-selected' ]
+            allowed: [ 'aria-colindex', 'aria-colspan', 'aria-expanded', 'aria-rowindex', 'aria-rowspan', 'aria-required', 'aria-readonly', 'aria-selected', 'aria-sort', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
           context: [ 'row' ],
-          implicit: [ 'th' ]
+          implicit: [ 'th' ],
+          unsupported: false
         },
         scrollbar: {
           type: 'widget',
           attributes: {
-            required: [ 'aria-controls', 'aria-orientation', 'aria-valuenow', 'aria-valuemax', 'aria-valuemin' ],
-            allowed: [ 'aria-valuetext' ]
+            required: [ 'aria-controls', 'aria-valuenow' ],
+            allowed: [ 'aria-valuetext', 'aria-orientation', 'aria-errormessage', 'aria-valuemax', 'aria-valuemin' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false
         },
         search: {
           type: 'landmark',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: {
+            nodeName: [ 'aside', 'form', 'section' ]
+          }
         },
         searchbox: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-activedescendant', 'aria-autocomplete', 'aria-multiline', 'aria-readonly', 'aria-required' ]
+            allowed: [ 'aria-activedescendant', 'aria-autocomplete', 'aria-multiline', 'aria-readonly', 'aria-required', 'aria-placeholder', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'input[type="search"]' ]
+          implicit: [ 'input[type="search"]' ],
+          unsupported: false,
+          allowedElements: {
+            nodeName: 'input',
+            properties: {
+              type: 'text'
+            }
+          }
         },
         section: {
           nameFrom: [ 'author', 'contents' ],
-          type: 'abstract'
+          type: 'abstract',
+          unsupported: false
         },
         sectionhead: {
           nameFrom: [ 'author', 'contents' ],
-          type: 'abstract'
+          type: 'abstract',
+          unsupported: false
         },
         select: {
           nameFrom: [ 'author' ],
-          type: 'abstract'
+          type: 'abstract',
+          unsupported: false
         },
         separator: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-expanded', 'aria-orientation' ]
+            allowed: [ 'aria-expanded', 'aria-orientation', 'aria-valuenow', 'aria-valuemax', 'aria-valuemin', 'aria-valuetext', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'hr' ]
+          implicit: [ 'hr' ],
+          unsupported: false,
+          allowedElements: [ 'li' ]
         },
         slider: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-valuetext', 'aria-orientation' ],
-            required: [ 'aria-valuenow', 'aria-valuemax', 'aria-valuemin' ]
+            allowed: [ 'aria-valuetext', 'aria-orientation', 'aria-readonly', 'aria-errormessage', 'aria-valuemax', 'aria-valuemin' ],
+            required: [ 'aria-valuenow' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'input[type="range"]' ]
+          implicit: [ 'input[type="range"]' ],
+          unsupported: false
         },
         spinbutton: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-valuetext', 'aria-required' ],
-            required: [ 'aria-valuenow', 'aria-valuemax', 'aria-valuemin' ]
+            allowed: [ 'aria-valuetext', 'aria-required', 'aria-readonly', 'aria-errormessage', 'aria-valuemax', 'aria-valuemin' ],
+            required: [ 'aria-valuenow' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'input[type="number"]' ]
+          implicit: [ 'input[type="number"]' ],
+          unsupported: false,
+          allowedElements: {
+            nodeName: 'input',
+            properties: {
+              type: 'text'
+            }
+          }
         },
         status: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'output' ]
+          implicit: [ 'output' ],
+          unsupported: false,
+          allowedElements: [ 'section' ]
         },
         structure: {
-          type: 'abstract'
+          type: 'abstract',
+          unsupported: false
         },
         switch: {
           type: 'widget',
           attributes: {
+            allowed: [ 'aria-errormessage' ],
             required: [ 'aria-checked' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'button', {
+            nodeName: 'input',
+            properties: {
+              type: [ 'checkbox', 'image', 'button' ]
+            }
+          }, {
+            nodeName: 'a',
+            attributes: {
+              href: isNotNull
+            }
+          } ]
         },
         tab: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-selected', 'aria-expanded' ]
+            allowed: [ 'aria-selected', 'aria-expanded', 'aria-setsize', 'aria-posinset', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
-          context: [ 'tablist' ]
+          context: [ 'tablist' ],
+          unsupported: false,
+          allowedElements: [ {
+            nodeName: [ 'button', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li' ]
+          }, {
+            nodeName: 'input',
+            properties: {
+              type: 'button'
+            }
+          }, {
+            nodeName: 'a',
+            attributes: {
+              href: isNotNull
+            }
+          } ]
         },
         table: {
           type: 'structure',
           attributes: {
-            allowed: [ 'aria-colcount', 'aria-rowcount' ]
+            allowed: [ 'aria-colcount', 'aria-rowcount', 'aria-errormessage' ]
           },
           owned: {
             one: [ 'rowgroup', 'row' ]
           },
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'table' ]
+          implicit: [ 'table' ],
+          unsupported: false
         },
         tablist: {
           type: 'composite',
           attributes: {
-            allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-level', 'aria-multiselectable' ]
+            allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-level', 'aria-multiselectable', 'aria-orientation', 'aria-errormessage' ]
           },
           owned: {
             all: [ 'tab' ]
           },
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'ol', 'ul' ]
         },
         tabpanel: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'section' ]
         },
-        text: {
+        term: {
           type: 'structure',
+          attributes: {
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
+          },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
-          context: null
+          context: null,
+          implicit: [ 'dt' ],
+          unsupported: false
         },
         textbox: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-activedescendant', 'aria-autocomplete', 'aria-multiline', 'aria-readonly', 'aria-required' ]
+            allowed: [ 'aria-activedescendant', 'aria-autocomplete', 'aria-multiline', 'aria-readonly', 'aria-required', 'aria-placeholder', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'input[type="text"]', 'input[type="email"]', 'input[type="password"]', 'input[type="tel"]', 'input[type="url"]', 'input:not([type])', 'textarea' ]
+          implicit: [ 'input[type="text"]', 'input[type="email"]', 'input[type="password"]', 'input[type="tel"]', 'input[type="url"]', 'input:not([type])', 'textarea' ],
+          unsupported: false
         },
         timer: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-expanded' ]
-          },
-          owned: null,
-          nameFrom: [ 'author' ],
-          context: null
-        },
-        toolbar: {
-          type: 'structure',
-          attributes: {
-            allowed: [ 'aria-activedescendant', 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author' ],
           context: null,
-          implicit: [ 'menu[type="toolbar"]' ]
+          unsupported: false
+        },
+        toolbar: {
+          type: 'structure',
+          attributes: {
+            allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-orientation', 'aria-errormessage' ]
+          },
+          owned: null,
+          nameFrom: [ 'author' ],
+          context: null,
+          implicit: [ 'menu[type="toolbar"]' ],
+          unsupported: false,
+          allowedElements: [ 'ol', 'ul' ]
         },
         tooltip: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-expanded' ]
+            allowed: [ 'aria-expanded', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
-          context: null
+          context: null,
+          unsupported: false
         },
         tree: {
           type: 'composite',
           attributes: {
-            allowed: [ 'aria-activedescendant', 'aria-multiselectable', 'aria-required', 'aria-expanded' ]
+            allowed: [ 'aria-activedescendant', 'aria-multiselectable', 'aria-required', 'aria-expanded', 'aria-orientation', 'aria-errormessage' ]
           },
           owned: {
             all: [ 'treeitem' ]
           },
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false,
+          allowedElements: [ 'ol', 'ul' ]
         },
         treegrid: {
           type: 'composite',
           attributes: {
-            allowed: [ 'aria-activedescendant', 'aria-expanded', 'aria-level', 'aria-multiselectable', 'aria-readonly', 'aria-required' ]
+            allowed: [ 'aria-activedescendant', 'aria-colcount', 'aria-expanded', 'aria-level', 'aria-multiselectable', 'aria-readonly', 'aria-required', 'aria-rowcount', 'aria-orientation', 'aria-errormessage' ]
           },
           owned: {
-            all: [ 'treeitem' ]
+            one: [ 'rowgroup', 'row' ]
           },
           nameFrom: [ 'author' ],
-          context: null
+          context: null,
+          unsupported: false
         },
         treeitem: {
           type: 'widget',
           attributes: {
-            allowed: [ 'aria-checked', 'aria-selected', 'aria-expanded', 'aria-level', 'aria-posinset', 'aria-setsize' ]
+            allowed: [ 'aria-checked', 'aria-selected', 'aria-expanded', 'aria-level', 'aria-posinset', 'aria-setsize', 'aria-errormessage' ]
           },
           owned: null,
           nameFrom: [ 'author', 'contents' ],
-          context: [ 'treegrid', 'tree' ]
+          context: [ 'group', 'tree' ],
+          unsupported: false,
+          allowedElements: [ 'li', {
+            nodeName: 'a',
+            attributes: {
+              href: isNotNull
+            }
+          } ]
         },
         widget: {
-          type: 'abstract'
+          type: 'abstract',
+          unsupported: false
         },
         window: {
           nameFrom: [ 'author' ],
-          type: 'abstract'
+          type: 'abstract',
+          unsupported: false
         }
       };
+      lookupTable.elementsAllowedNoRole = [ {
+        nodeName: [ 'base', 'body', 'caption', 'col', 'colgroup', 'datalist', 'dd', 'details', 'dt', 'head', 'html', 'keygen', 'label', 'legend', 'main', 'map', 'math', 'meta', 'meter', 'noscript', 'optgroup', 'param', 'picture', 'progress', 'script', 'source', 'style', 'template', 'textarea', 'title', 'track' ]
+      }, {
+        nodeName: 'area',
+        attributes: {
+          href: isNotNull
+        }
+      }, {
+        nodeName: 'input',
+        properties: {
+          type: [ 'color', 'data', 'datatime', 'file', 'hidden', 'month', 'number', 'password', 'range', 'reset', 'submit', 'time', 'week' ]
+        }
+      }, {
+        nodeName: 'input',
+        attributes: {
+          list: isNull
+        },
+        properties: {
+          type: [ 'email', 'search', 'tel', 'url' ]
+        }
+      }, {
+        nodeName: 'link',
+        attributes: {
+          href: isNotNull
+        }
+      }, {
+        nodeName: 'menu',
+        attributes: {
+          type: 'context'
+        }
+      }, {
+        nodeName: 'menuitem',
+        attributes: {
+          type: [ 'command', 'checkbox', 'radio' ]
+        }
+      }, {
+        nodeName: 'select',
+        condition: function condition(node) {
+          return Number(node.getAttribute('size')) > 1;
+        },
+        properties: {
+          multiple: true
+        }
+      }, {
+        nodeName: [ 'clippath', 'cursor', 'defs', 'desc', 'feblend', 'fecolormatrix', 'fecomponenttransfer', 'fecomposite', 'feconvolvematrix', 'fediffuselighting', 'fedisplacementmap', 'fedistantlight', 'fedropshadow', 'feflood', 'fefunca', 'fefuncb', 'fefuncg', 'fefuncr', 'fegaussianblur', 'feimage', 'femerge', 'femergenode', 'femorphology', 'feoffset', 'fepointlight', 'fespecularlighting', 'fespotlight', 'fetile', 'feturbulence', 'filter', 'hatch', 'hatchpath', 'lineargradient', 'marker', 'mask', 'meshgradient', 'meshpatch', 'meshrow', 'metadata', 'mpath', 'pattern', 'radialgradient', 'solidcolor', 'stop', 'switch', 'view' ]
+      } ];
+      lookupTable.elementsAllowedAnyRole = [ {
+        nodeName: 'a',
+        attributes: {
+          href: isNull
+        }
+      }, {
+        nodeName: [ 'abbr', 'address', 'canvas', 'div', 'p', 'pre', 'blockquote', 'ins', 'del', 'output', 'span', 'table', 'tbody', 'thead', 'tfoot', 'td', 'em', 'strong', 'small', 's', 'cite', 'q', 'dfn', 'abbr', 'time', 'code', 'var', 'samp', 'kbd', 'sub', 'sup', 'i', 'b', 'u', 'mark', 'ruby', 'rt', 'rp', 'bdi', 'bdo', 'br', 'wbr', 'th', 'tr' ]
+      } ];
+      lookupTable.evaluateRoleForElement = {
+        A: function A(_ref12) {
+          var node = _ref12.node, out = _ref12.out;
+          if (node.namespaceURI === 'http://www.w3.org/2000/svg') {
+            return true;
+          }
+          if (node.href.length) {
+            return out;
+          }
+          return true;
+        },
+        AREA: function AREA(_ref13) {
+          var node = _ref13.node;
+          return !node.href;
+        },
+        BUTTON: function BUTTON(_ref14) {
+          var node = _ref14.node, role = _ref14.role, out = _ref14.out;
+          if (node.getAttribute('type') === 'menu') {
+            return role === 'menuitem';
+          }
+          return out;
+        },
+        IMG: function IMG(_ref15) {
+          var node = _ref15.node, out = _ref15.out;
+          if (node.alt) {
+            return !out;
+          }
+          return out;
+        },
+        INPUT: function INPUT(_ref16) {
+          var node = _ref16.node, role = _ref16.role, out = _ref16.out;
+          switch (node.type) {
+           case 'button':
+           case 'image':
+            return out;
+
+           case 'checkbox':
+            if (role === 'button' && node.hasAttribute('aria-pressed')) {
+              return true;
+            }
+            return out;
+
+           case 'radio':
+            return role === 'menuitemradio';
+
+           case 'text':
+            return role === 'combobox' || role === 'searchbox' || role === 'spinbutton';
+
+           default:
+            return false;
+          }
+        },
+        LI: function LI(_ref17) {
+          var node = _ref17.node, out = _ref17.out;
+          var hasImplicitListitemRole = axe.utils.matchesSelector(node, 'ol li, ul li');
+          if (hasImplicitListitemRole) {
+            return out;
+          }
+          return true;
+        },
+        MENU: function MENU(_ref18) {
+          var node = _ref18.node;
+          if (node.getAttribute('type') === 'context') {
+            return false;
+          }
+          return true;
+        },
+        OPTION: function OPTION(_ref19) {
+          var node = _ref19.node;
+          var withinOptionList = axe.utils.matchesSelector(node, 'select > option, datalist > option, optgroup > option');
+          return !withinOptionList;
+        },
+        SELECT: function SELECT(_ref20) {
+          var node = _ref20.node, role = _ref20.role;
+          return !node.multiple && node.size <= 1 && role === 'menu';
+        },
+        SVG: function SVG(_ref21) {
+          var node = _ref21.node, out = _ref21.out;
+          if (node.parentNode && node.parentNode.namespaceURI === 'http://www.w3.org/2000/svg') {
+            return true;
+          }
+          return out;
+        }
+      };
+      lookupTable.rolesOfType = {
+        widget: [ 'button', 'checkbox', 'dialog', 'gridcell', 'heading', 'link', 'log', 'marquee', 'menuitem', 'menuitemcheckbox', 'menuitemradio', 'option', 'progressbar', 'radio', 'scrollbar', 'slider', 'spinbutton', 'status', 'switch', 'tab', 'tabpanel', 'textbox', 'timer', 'tooltip', 'tree', 'treeitem' ]
+      };
       var color = {};
       commons.color = color;
       var dom = commons.dom = {};
+      var forms = {};
+      commons.forms = forms;
+      function matches(node, definition) {
+        return matches.fromDefinition(node, definition);
+      }
+      commons.matches = matches;
       var table = commons.table = {};
-      var text = commons.text = {};
+      var text = commons.text = {
+        EdgeFormDefaults: {}
+      };
       var utils = commons.utils = axe.utils;
+      aria.arialabelText = function arialabelText(node) {
+        node = node.actualNode || node;
+        if (node.nodeType !== 1) {
+          return '';
+        }
+        return node.getAttribute('aria-label') || '';
+      };
+      aria.arialabelledbyText = function arialabelledbyText(node) {
+        var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+        node = node.actualNode || node;
+        if (node.nodeType !== 1 || context.inLabelledByContext || context.inControlContext) {
+          return '';
+        }
+        var refs = dom.idrefs(node, 'aria-labelledby').filter(function(elm) {
+          return elm;
+        });
+        return refs.reduce(function(accessibleName, elm) {
+          var accessibleNameAdd = text.accessibleText(elm, _extends({
+            inLabelledByContext: true,
+            startNode: context.startNode || node
+          }, context));
+          if (!accessibleName) {
+            return accessibleNameAdd;
+          } else {
+            return ''.concat(accessibleName, ' ').concat(accessibleNameAdd);
+          }
+        }, '');
+      };
       aria.requiredAttr = function(role) {
-        'use strict';
-        var roles = lookupTables.role[role], attr = roles && roles.attributes && roles.attributes.required;
+        var roles = aria.lookupTable.role[role], attr = roles && roles.attributes && roles.attributes.required;
         return attr || [];
       };
       aria.allowedAttr = function(role) {
-        'use strict';
-        var roles = lookupTables.role[role], attr = roles && roles.attributes && roles.attributes.allowed || [], requiredAttr = roles && roles.attributes && roles.attributes.required || [];
-        return attr.concat(lookupTables.globalAttributes).concat(requiredAttr);
+        var roles = aria.lookupTable.role[role], attr = roles && roles.attributes && roles.attributes.allowed || [], requiredAttr = roles && roles.attributes && roles.attributes.required || [];
+        return attr.concat(aria.lookupTable.globalAttributes).concat(requiredAttr);
       };
-      aria.validateAttr = function(att) {
-        'use strict';
-        return !!lookupTables.attributes[att];
+      aria.validateAttr = function validateAttr(att) {
+        var attrDefinition = aria.lookupTable.attributes[att];
+        return !!attrDefinition;
       };
-      aria.validateAttrValue = function(node, attr) {
-        'use strict';
-        var matches, list, value = node.getAttribute(attr), attrInfo = lookupTables.attributes[attr];
-        var doc = dom.getRootNode(node);
-        if (!attrInfo) {
+      function getRoleSegments(node) {
+        var roles = [];
+        if (!node) {
+          return roles;
+        }
+        if (node.hasAttribute('role')) {
+          var nodeRoles = axe.utils.tokenList(node.getAttribute('role').toLowerCase());
+          roles = roles.concat(nodeRoles);
+        }
+        if (node.hasAttributeNS('http://www.idpf.org/2007/ops', 'type')) {
+          var epubRoles = axe.utils.tokenList(node.getAttributeNS('http://www.idpf.org/2007/ops', 'type').toLowerCase()).map(function(role) {
+            return 'doc-'.concat(role);
+          });
+          roles = roles.concat(epubRoles);
+        }
+        roles = roles.filter(function(role) {
+          return axe.commons.aria.isValidRole(role);
+        });
+        return roles;
+      }
+      aria.getElementUnallowedRoles = function getElementUnallowedRoles(node) {
+        var allowImplicit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
+        var tagName = node.nodeName.toUpperCase();
+        if (!axe.utils.isHtmlElement(node)) {
+          return [];
+        }
+        var roleSegments = getRoleSegments(node);
+        var implicitRole = axe.commons.aria.implicitRole(node);
+        var unallowedRoles = roleSegments.filter(function(role) {
+          if (allowImplicit && role === implicitRole) {
+            return false;
+          }
+          if (!allowImplicit && !(role === 'row' && tagName === 'TR' && axe.utils.matchesSelector(node, 'table[role="grid"] > tr'))) {
+            return true;
+          }
+          return !aria.isAriaRoleAllowedOnElement(node, role);
+        });
+        return unallowedRoles;
+      };
+      aria.getOwnedVirtual = function getOwned(_ref22) {
+        var actualNode = _ref22.actualNode, children = _ref22.children;
+        if (!actualNode || !children) {
+          throw new Error('getOwnedVirtual requires a virtual node');
+        }
+        return dom.idrefs(actualNode, 'aria-owns').reduce(function(ownedElms, element) {
+          if (element) {
+            var virtualNode = axe.utils.getNodeFromTree(element);
+            ownedElms.push(virtualNode);
+          }
+          return ownedElms;
+        }, children);
+      };
+      aria.getRole = function getRole(node) {
+        var _ref23 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, noImplicit = _ref23.noImplicit, fallback = _ref23.fallback, abstracts = _ref23.abstracts, dpub = _ref23.dpub;
+        node = node.actualNode || node;
+        if (node.nodeType !== 1) {
+          return null;
+        }
+        var roleAttr = (node.getAttribute('role') || '').trim().toLowerCase();
+        var roleList = fallback ? axe.utils.tokenList(roleAttr) : [ roleAttr ];
+        var validRoles = roleList.filter(function(role) {
+          if (!dpub && role.substr(0, 4) === 'doc-') {
+            return false;
+          }
+          return aria.isValidRole(role, {
+            allowAbstract: abstracts
+          });
+        });
+        var explicitRole = validRoles[0];
+        if (!explicitRole && !noImplicit) {
+          return aria.implicitRole(node);
+        }
+        return explicitRole || null;
+      };
+      var idRefsRegex = /^idrefs?$/;
+      function cacheIdRefs(node, refAttrs) {
+        if (node.hasAttribute) {
+          if (node.nodeName.toUpperCase() === 'LABEL' && node.hasAttribute('for')) {
+            axe._cache.get('idRefs')[node.getAttribute('for')] = true;
+          }
+          refAttrs.filter(function(attr) {
+            return node.hasAttribute(attr);
+          }).forEach(function(attr) {
+            var attrValue = node.getAttribute(attr);
+            axe.utils.tokenList(attrValue).forEach(function(id) {
+              axe._cache.get('idRefs')[id] = true;
+            });
+          });
+        }
+        for (var i = 0; i < node.children.length; i++) {
+          cacheIdRefs(node.children[i], refAttrs);
+        }
+      }
+      aria.isAccessibleRef = function isAccessibleRef(node) {
+        node = node.actualNode || node;
+        var root = dom.getRootNode(node);
+        root = root.documentElement || root;
+        var id = node.id;
+        if (!axe._cache.get('idRefs')) {
+          axe._cache.set('idRefs', {});
+          var refAttrs = Object.keys(aria.lookupTable.attributes).filter(function(attr) {
+            var type = aria.lookupTable.attributes[attr].type;
+            return idRefsRegex.test(type);
+          });
+          cacheIdRefs(root, refAttrs);
+        }
+        return axe._cache.get('idRefs')[id] === true;
+      };
+      aria.isAriaRoleAllowedOnElement = function isAriaRoleAllowedOnElement(node, role) {
+        var nodeName = node.nodeName.toUpperCase();
+        var lookupTable = axe.commons.aria.lookupTable;
+        if (matches(node, lookupTable.elementsAllowedNoRole)) {
+          return false;
+        }
+        if (matches(node, lookupTable.elementsAllowedAnyRole)) {
           return true;
         }
-        switch (attrInfo.type) {
-         case 'boolean':
-         case 'nmtoken':
-          return typeof value === 'string' && attrInfo.values.indexOf(value.toLowerCase()) !== -1;
-
-         case 'nmtokens':
-          list = axe.utils.tokenList(value);
-          return list.reduce(function(result, token) {
-            return result && attrInfo.values.indexOf(token) !== -1;
-          }, list.length !== 0);
-
-         case 'idref':
-          return !!(value && doc.getElementById(value));
-
-         case 'idrefs':
-          list = axe.utils.tokenList(value);
-          return list.reduce(function(result, token) {
-            return !!(result && doc.getElementById(token));
-          }, list.length !== 0);
-
-         case 'string':
-          return true;
-
-         case 'decimal':
-          matches = value.match(/^[-+]?([0-9]*)\.?([0-9]*)$/);
-          return !!(matches && (matches[1] || matches[2]));
-
-         case 'int':
-          return /^[-+]?[0-9]+$/.test(value);
+        var roleValue = lookupTable.role[role];
+        if (!roleValue || !roleValue.allowedElements) {
+          return false;
         }
+        var out = matches(node, roleValue.allowedElements);
+        if (Object.keys(lookupTable.evaluateRoleForElement).includes(nodeName)) {
+          return lookupTable.evaluateRoleForElement[nodeName]({
+            node: node,
+            role: role,
+            out: out
+          });
+        }
+        return out;
       };
-      aria.label = function(node) {
+      aria.isUnsupportedRole = function(role) {
+        var roleDefinition = aria.lookupTable.role[role];
+        return roleDefinition ? roleDefinition.unsupported : false;
+      };
+      aria.labelVirtual = function(_ref24) {
+        var actualNode = _ref24.actualNode;
         var ref, candidate;
-        if (node.actualNode instanceof Node === false) {
-          node = axe.utils.getNodeFromTree(axe._tree[0], node);
-        }
-        if (node.actualNode.getAttribute('aria-labelledby')) {
-          ref = dom.idrefs(node.actualNode, 'aria-labelledby');
+        if (actualNode.getAttribute('aria-labelledby')) {
+          ref = dom.idrefs(actualNode, 'aria-labelledby');
           candidate = ref.map(function(thing) {
-            var vNode = axe.utils.getNodeFromTree(axe._tree[0], thing);
-            return vNode ? text.visible(vNode, true) : '';
+            var vNode = axe.utils.getNodeFromTree(thing);
+            return vNode ? text.visibleVirtual(vNode, true) : '';
           }).join(' ').trim();
           if (candidate) {
             return candidate;
           }
         }
-        candidate = node.actualNode.getAttribute('aria-label');
+        candidate = actualNode.getAttribute('aria-label');
         if (candidate) {
           candidate = text.sanitize(candidate).trim();
           if (candidate) {
@@ -8216,30 +14473,52 @@
         }
         return null;
       };
-      aria.isValidRole = function(role) {
-        'use strict';
-        if (lookupTables.role[role]) {
+      aria.label = function(node) {
+        node = axe.utils.getNodeFromTree(node);
+        return aria.labelVirtual(node);
+      };
+      aria.namedFromContents = function namedFromContents(node) {
+        var _ref25 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, strict = _ref25.strict;
+        node = node.actualNode || node;
+        if (node.nodeType !== 1) {
+          return false;
+        }
+        var role = aria.getRole(node);
+        var roleDef = aria.lookupTable.role[role];
+        if (roleDef && roleDef.nameFrom.includes('contents') || node.nodeName.toUpperCase() === 'TABLE') {
           return true;
         }
-        return false;
+        if (strict) {
+          return false;
+        }
+        return !roleDef || [ 'presentation', 'none' ].includes(role);
+      };
+      aria.isValidRole = function(role) {
+        var _ref26 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, allowAbstract = _ref26.allowAbstract, _ref26$flagUnsupporte = _ref26.flagUnsupported, flagUnsupported = _ref26$flagUnsupporte === void 0 ? false : _ref26$flagUnsupporte;
+        var roleDefinition = aria.lookupTable.role[role];
+        var isRoleUnsupported = roleDefinition ? roleDefinition.unsupported : false;
+        if (!roleDefinition || flagUnsupported && isRoleUnsupported) {
+          return false;
+        }
+        return allowAbstract ? true : roleDefinition.type !== 'abstract';
       };
       aria.getRolesWithNameFromContents = function() {
-        return Object.keys(lookupTables.role).filter(function(r) {
-          return lookupTables.role[r].nameFrom && lookupTables.role[r].nameFrom.indexOf('contents') !== -1;
+        return Object.keys(aria.lookupTable.role).filter(function(r) {
+          return aria.lookupTable.role[r].nameFrom && aria.lookupTable.role[r].nameFrom.indexOf('contents') !== -1;
         });
       };
       aria.getRolesByType = function(roleType) {
-        return Object.keys(lookupTables.role).filter(function(r) {
-          return lookupTables.role[r].type === roleType;
+        return Object.keys(aria.lookupTable.role).filter(function(r) {
+          return aria.lookupTable.role[r].type === roleType;
         });
       };
       aria.getRoleType = function(role) {
-        var r = lookupTables.role[role];
+        var r = aria.lookupTable.role[role];
         return r && r.type || null;
       };
       aria.requiredOwned = function(role) {
         'use strict';
-        var owned = null, roles = lookupTables.role[role];
+        var owned = null, roles = aria.lookupTable.role[role];
         if (roles) {
           owned = axe.utils.clone(roles.owned);
         }
@@ -8247,7 +14526,7 @@
       };
       aria.requiredContext = function(role) {
         'use strict';
-        var context = null, roles = lookupTables.role[role];
+        var context = null, roles = aria.lookupTable.role[role];
         if (roles) {
           context = axe.utils.clone(roles.context);
         }
@@ -8255,7 +14534,7 @@
       };
       aria.implicitNodes = function(role) {
         'use strict';
-        var implicit = null, roles = lookupTables.role[role];
+        var implicit = null, roles = aria.lookupTable.role[role];
         if (roles && roles.implicit) {
           implicit = axe.utils.clone(roles.implicit);
         }
@@ -8292,8 +14571,8 @@
             return sortedRole.name;
           });
         };
-        var roles = Object.keys(lookupTables.role).map(function(role) {
-          var lookup = lookupTables.role[role];
+        var roles = Object.keys(aria.lookupTable.role).map(function(role) {
+          var lookup = aria.lookupTable.role[role];
           return {
             name: role,
             implicit: lookup && lookup.implicit
@@ -8303,7 +14582,7 @@
         if (!availableImplicitRoles.length) {
           return null;
         }
-        var nodeAttributes = node.attributes;
+        var nodeAttributes = axe.utils.getNodeAttributes(node);
         var ariaAttributes = [];
         for (var i = 0, j = nodeAttributes.length; i < j; i++) {
           var attr = nodeAttributes[i];
@@ -8313,6 +14592,61 @@
         }
         return sortRolesByOptimalAriaContext(availableImplicitRoles, ariaAttributes).shift();
       };
+      aria.validateAttrValue = function validateAttrValue(node, attr) {
+        'use strict';
+        var matches, list, value = node.getAttribute(attr), attrInfo = aria.lookupTable.attributes[attr];
+        var doc = dom.getRootNode(node);
+        if (!attrInfo) {
+          return true;
+        }
+        if (attrInfo.allowEmpty && (!value || value.trim() === '')) {
+          return true;
+        }
+        switch (attrInfo.type) {
+         case 'boolean':
+         case 'nmtoken':
+          return typeof value === 'string' && attrInfo.values.includes(value.toLowerCase());
+
+         case 'nmtokens':
+          list = axe.utils.tokenList(value);
+          return list.reduce(function(result, token) {
+            return result && attrInfo.values.includes(token);
+          }, list.length !== 0);
+
+         case 'idref':
+          return !!(value && doc.getElementById(value));
+
+         case 'idrefs':
+          list = axe.utils.tokenList(value);
+          return list.some(function(token) {
+            return doc.getElementById(token);
+          });
+
+         case 'string':
+          return value.trim() !== '';
+
+         case 'decimal':
+          matches = value.match(/^[-+]?([0-9]*)\.?([0-9]*)$/);
+          return !!(matches && (matches[1] || matches[2]));
+
+         case 'int':
+          return /^[-+]?[0-9]+$/.test(value);
+        }
+      };
+      color.centerPointOfRect = function centerPointOfRect(rect) {
+        if (rect.left > window.innerWidth) {
+          return undefined;
+        }
+        if (rect.top > window.innerHeight) {
+          return undefined;
+        }
+        var x = Math.min(Math.ceil(rect.left + rect.width / 2), window.innerWidth - 1);
+        var y = Math.min(Math.ceil(rect.top + rect.height / 2), window.innerHeight - 1);
+        return {
+          x: x,
+          y: y
+        };
+      };
       color.Color = function(red, green, blue, alpha) {
         this.red = red;
         this.green = green;
@@ -8347,7 +14681,7 @@
             this.red = parseInt(match[1], 10);
             this.green = parseInt(match[2], 10);
             this.blue = parseInt(match[3], 10);
-            this.alpha = parseFloat(match[4]);
+            this.alpha = Math.round(parseFloat(match[4]) * 100) / 100;
             return;
           }
         };
@@ -8383,11 +14717,29 @@
       color.hasValidContrastRatio = function(bg, fg, fontSize, isBold) {
         var contrast = color.getContrast(bg, fg);
         var isSmallFont = isBold && Math.ceil(fontSize * 72) / 96 < 14 || !isBold && Math.ceil(fontSize * 72) / 96 < 18;
+        var expectedContrastRatio = isSmallFont ? 4.5 : 3;
         return {
-          isValid: isSmallFont && contrast >= 4.5 || !isSmallFont && contrast >= 3,
-          contrastRatio: contrast
+          isValid: contrast > expectedContrastRatio,
+          contrastRatio: contrast,
+          expectedContrastRatio: expectedContrastRatio
         };
       };
+      color.elementHasImage = function elementHasImage(elm, style) {
+        var graphicNodes = [ 'IMG', 'CANVAS', 'OBJECT', 'IFRAME', 'VIDEO', 'SVG' ];
+        var nodeName = elm.nodeName.toUpperCase();
+        if (graphicNodes.includes(nodeName)) {
+          axe.commons.color.incompleteData.set('bgColor', 'imgNode');
+          return true;
+        }
+        style = style || window.getComputedStyle(elm);
+        var bgImageStyle = style.getPropertyValue('background-image');
+        var hasBgImage = bgImageStyle !== 'none';
+        if (hasBgImage) {
+          var hasGradient = /gradient/.test(bgImageStyle);
+          axe.commons.color.incompleteData.set('bgColor', hasGradient ? 'bgGradient' : 'bgImage');
+        }
+        return hasBgImage;
+      };
       function _getFonts(style) {
         return style.getPropertyValue('font-family').split(/[,;]/g).map(function(font) {
           return font.trim().toLowerCase();
@@ -8420,139 +14772,20 @@
         return hasStyle;
       }
       color.elementIsDistinct = elementIsDistinct;
-      var graphicNodes = [ 'IMG', 'CANVAS', 'OBJECT', 'IFRAME', 'VIDEO', 'SVG' ];
-      function elmHasImage(elm, style) {
-        var nodeName = elm.nodeName.toUpperCase();
-        if (graphicNodes.includes(nodeName)) {
-          axe.commons.color.incompleteData.set('bgColor', 'imgNode');
-          return true;
-        }
-        style = style || window.getComputedStyle(elm);
-        var bgImageStyle = style.getPropertyValue('background-image');
-        var hasBgImage = bgImageStyle !== 'none';
-        if (hasBgImage) {
-          var hasGradient = /gradient/.test(bgImageStyle);
-          axe.commons.color.incompleteData.set('bgColor', hasGradient ? 'bgGradient' : 'bgImage');
-        }
-        return hasBgImage;
-      }
-      function getBgColor(elm, elmStyle) {
-        elmStyle = elmStyle || window.getComputedStyle(elm);
-        var bgColor = new color.Color();
-        bgColor.parseRgbString(elmStyle.getPropertyValue('background-color'));
-        if (bgColor.alpha !== 0) {
-          var opacity = elmStyle.getPropertyValue('opacity');
-          bgColor.alpha = bgColor.alpha * opacity;
-        }
-        return bgColor;
-      }
-      function contentOverlapping(targetElement, bgNode) {
-        var targetRect = targetElement.getClientRects()[0];
-        var obscuringElements = document.elementsFromPoint(targetRect.left, targetRect.top);
-        if (obscuringElements) {
-          for (var i = 0; i < obscuringElements.length; i++) {
-            if (obscuringElements[i] !== targetElement && obscuringElements[i] === bgNode) {
-              return true;
-            }
-          }
-        }
-        return false;
-      }
-      function calculateObscuringAlpha(elmIndex, elmStack, originalElm) {
-        var totalAlpha = 0;
-        if (elmIndex > 0) {
-          for (var i = elmIndex - 1; i >= 0; i--) {
-            var bgElm = elmStack[i];
-            var bgElmStyle = window.getComputedStyle(bgElm);
-            var bgColor = getBgColor(bgElm, bgElmStyle);
-            if (bgColor.alpha && contentOverlapping(originalElm, bgElm)) {
-              totalAlpha += bgColor.alpha;
-            } else {
-              elmStack.splice(i, 1);
-            }
-          }
-        }
-        return totalAlpha;
-      }
-      function elmPartiallyObscured(elm, bgElm, bgColor) {
-        var obscured = elm !== bgElm && !dom.visuallyContains(elm, bgElm) && bgColor.alpha !== 0;
-        if (obscured) {
-          axe.commons.color.incompleteData.set('bgColor', 'elmPartiallyObscured');
-        }
-        return obscured;
-      }
-      function includeMissingElements(elmStack, elm) {
-        var elementMap = {
-          TD: 'TR',
-          INPUT: 'LABEL'
-        };
-        var tagArray = elmStack.map(function(elm) {
-          return elm.tagName;
-        });
-        var bgNodes = elmStack;
-        for (var candidate in elementMap) {
-          if (elementMap.hasOwnProperty(candidate)) {
-            if (elm.tagName === candidate) {
-              var ancestorMatch = axe.commons.dom.findUp(elm, elementMap[candidate]);
-              if (ancestorMatch && elmStack.indexOf(ancestorMatch) === -1) {
-                var overlaps = axe.commons.dom.visuallyOverlaps(elm.getBoundingClientRect(), ancestorMatch);
-                if (overlaps) {
-                  bgNodes.splice(elmStack.indexOf(elm) + 1, 0, ancestorMatch);
-                }
-              }
-            }
-            if (elm.tagName === elementMap[candidate] && tagArray.indexOf(elm.tagName) === -1) {
-              bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, elm);
-            }
-          }
-        }
-        return bgNodes;
-      }
-      function sortPageBackground(elmStack) {
-        var bodyIndex = elmStack.indexOf(document.body);
-        var bgNodes = elmStack;
-        if (bodyIndex > 1 && !elmHasImage(document.documentElement) && getBgColor(document.documentElement).alpha === 0) {
-          bgNodes.splice(bodyIndex, 1);
-          bgNodes.splice(elmStack.indexOf(document.documentElement), 1);
-          bgNodes.push(document.body);
-        }
-        return bgNodes;
-      }
-      color.getBackgroundStack = function(elm) {
-        var rect = elm.getBoundingClientRect();
-        var x = void 0, y = void 0;
-        if (rect.left > window.innerWidth) {
-          return;
-        }
-        if (rect.top > window.innerHeight) {
-          return;
-        }
-        x = Math.min(Math.ceil(rect.left + rect.width / 2), window.innerWidth - 1);
-        y = Math.min(Math.ceil(rect.top + rect.height / 2), window.innerHeight - 1);
-        var elmStack = document.elementsFromPoint(x, y);
-        elmStack = includeMissingElements(elmStack, elm);
-        elmStack = dom.reduceToElementsBelowFloating(elmStack, elm);
-        elmStack = sortPageBackground(elmStack);
-        var elmIndex = elmStack.indexOf(elm);
-        if (calculateObscuringAlpha(elmIndex, elmStack, elm) >= .99) {
-          axe.commons.color.incompleteData.set('bgColor', 'bgOverlap');
-          return null;
-        }
-        return elmIndex !== -1 ? elmStack : null;
-      };
-      color.getBackgroundColor = function(elm) {
+      color.getBackgroundColor = function getBackgroundColor(elm) {
         var bgElms = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
         var noScroll = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
         if (noScroll !== true) {
-          var alignToTop = elm.clientHeight - 2 >= window.innerHeight * 2;
+          var clientHeight = elm.getBoundingClientRect().height;
+          var alignToTop = clientHeight - 2 >= window.innerHeight * 2;
           elm.scrollIntoView(alignToTop);
         }
         var bgColors = [];
         var elmStack = color.getBackgroundStack(elm);
         (elmStack || []).some(function(bgElm) {
           var bgElmStyle = window.getComputedStyle(bgElm);
-          var bgColor = getBgColor(bgElm, bgElmStyle);
-          if (elmPartiallyObscured(elm, bgElm, bgColor) || elmHasImage(bgElm, bgElmStyle)) {
+          var bgColor = color.getOwnBackgroundColor(bgElmStyle);
+          if (elmPartiallyObscured(elm, bgElm, bgColor) || color.elementHasImage(bgElm, bgElmStyle)) {
             bgColors = null;
             bgElms.push(bgElm);
             return true;
@@ -8572,9 +14805,151 @@
         }
         return null;
       };
+      color.getBackgroundStack = function getBackgroundStack(elm) {
+        var elmStack = color.filteredRectStack(elm);
+        if (elmStack === null) {
+          return null;
+        }
+        elmStack = includeMissingElements(elmStack, elm);
+        elmStack = dom.reduceToElementsBelowFloating(elmStack, elm);
+        elmStack = sortPageBackground(elmStack);
+        var elmIndex = elmStack.indexOf(elm);
+        if (calculateObscuringElement(elmIndex, elmStack, elm)) {
+          axe.commons.color.incompleteData.set('bgColor', 'bgOverlap');
+          return null;
+        }
+        return elmIndex !== -1 ? elmStack : null;
+      };
+      color.filteredRectStack = function filteredRectStack(elm) {
+        var rectStack = color.getRectStack(elm);
+        if (rectStack && rectStack.length === 1) {
+          return rectStack[0];
+        }
+        if (rectStack && rectStack.length > 1) {
+          var boundingStack = rectStack.shift();
+          var isSame;
+          includeMissingElements(boundingStack, elm);
+          rectStack.forEach(function(rectList, index) {
+            if (index === 0) {
+              return;
+            }
+            var rectA = rectStack[index - 1], rectB = rectStack[index];
+            isSame = rectA.every(function(element, elementIndex) {
+              return element === rectB[elementIndex];
+            }) || boundingStack.includes(elm);
+          });
+          if (!isSame) {
+            axe.commons.color.incompleteData.set('bgColor', 'elmPartiallyObscuring');
+            return null;
+          }
+          return rectStack[0];
+        }
+        axe.commons.color.incompleteData.set('bgColor', 'outsideViewport');
+        return null;
+      };
+      color.getRectStack = function(elm) {
+        var boundingCoords = axe.commons.color.centerPointOfRect(elm.getBoundingClientRect());
+        if (!boundingCoords) {
+          return null;
+        }
+        var boundingStack = dom.shadowElementsFromPoint(boundingCoords.x, boundingCoords.y);
+        var rects = Array.from(elm.getClientRects());
+        if (!rects || rects.length <= 1) {
+          return [ boundingStack ];
+        }
+        var filteredArr = rects.filter(function(rect) {
+          return rect.width && rect.width > 0;
+        }).map(function(rect) {
+          var coords = axe.commons.color.centerPointOfRect(rect);
+          if (coords) {
+            return dom.shadowElementsFromPoint(coords.x, coords.y);
+          }
+        });
+        if (filteredArr.some(function(stack) {
+          return stack === undefined;
+        })) {
+          return null;
+        }
+        filteredArr.splice(0, 0, boundingStack);
+        return filteredArr;
+      };
+      function sortPageBackground(elmStack) {
+        var bodyIndex = elmStack.indexOf(document.body);
+        var bgNodes = elmStack;
+        var sortBodyElement = bodyIndex > 1 || bodyIndex === -1;
+        if (sortBodyElement && !color.elementHasImage(document.documentElement) && color.getOwnBackgroundColor(window.getComputedStyle(document.documentElement)).alpha === 0) {
+          if (bodyIndex > 1) {
+            bgNodes.splice(bodyIndex, 1);
+          }
+          bgNodes.splice(elmStack.indexOf(document.documentElement), 1);
+          bgNodes.push(document.body);
+        }
+        return bgNodes;
+      }
+      function includeMissingElements(elmStack, elm) {
+        var nodeName = elm.nodeName.toUpperCase();
+        var elementMap = {
+          TD: [ 'TR', 'THEAD', 'TBODY', 'TFOOT' ],
+          TH: [ 'TR', 'THEAD', 'TBODY', 'TFOOT' ],
+          INPUT: [ 'LABEL' ]
+        };
+        var tagArray = elmStack.map(function(elm) {
+          return elm.nodeName.toUpperCase();
+        });
+        var bgNodes = elmStack;
+        for (var candidate in elementMap) {
+          if (tagArray.includes(candidate)) {
+            for (var candidateIndex = 0; candidateIndex < elementMap[candidate].length; candidateIndex++) {
+              var ancestorMatch = axe.commons.dom.findUp(elm, elementMap[candidate][candidateIndex]);
+              if (ancestorMatch && elmStack.indexOf(ancestorMatch) === -1) {
+                var overlaps = axe.commons.dom.visuallyOverlaps(elm.getBoundingClientRect(), ancestorMatch);
+                if (overlaps) {
+                  bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, ancestorMatch);
+                }
+              }
+              if (nodeName === elementMap[candidate][candidateIndex] && tagArray.indexOf(nodeName) === -1) {
+                bgNodes.splice(tagArray.indexOf(candidate) + 1, 0, elm);
+              }
+            }
+          }
+        }
+        return bgNodes;
+      }
+      function elmPartiallyObscured(elm, bgElm, bgColor) {
+        var obscured = elm !== bgElm && !dom.visuallyContains(elm, bgElm) && bgColor.alpha !== 0;
+        if (obscured) {
+          axe.commons.color.incompleteData.set('bgColor', 'elmPartiallyObscured');
+        }
+        return obscured;
+      }
+      function calculateObscuringElement(elmIndex, elmStack, originalElm) {
+        if (elmIndex > 0) {
+          for (var i = elmIndex - 1; i >= 0; i--) {
+            var bgElm = elmStack[i];
+            if (contentOverlapping(originalElm, bgElm)) {
+              return true;
+            } else {
+              elmStack.splice(i, 1);
+            }
+          }
+        }
+        return false;
+      }
+      function contentOverlapping(targetElement, bgNode) {
+        var targetRect = targetElement.getClientRects()[0];
+        var obscuringElements = dom.shadowElementsFromPoint(targetRect.left, targetRect.top);
+        if (obscuringElements) {
+          for (var i = 0; i < obscuringElements.length; i++) {
+            if (obscuringElements[i] !== targetElement && obscuringElements[i] === bgNode) {
+              return true;
+            }
+          }
+        }
+        return false;
+      }
       dom.isOpaque = function(node) {
         var style = window.getComputedStyle(node);
-        return elmHasImage(node, style) || getBgColor(node, style).alpha === 1;
+        return color.elementHasImage(node, style) || color.getOwnBackgroundColor(style).alpha === 1;
       };
       color.getForegroundColor = function(node, noScroll) {
         var nodeStyle = window.getComputedStyle(node);
@@ -8593,6 +14968,15 @@
         }
         return color.flattenColors(fgColor, bgColor);
       };
+      color.getOwnBackgroundColor = function getOwnBackgroundColor(elmStyle) {
+        var bgColor = new color.Color();
+        bgColor.parseRgbString(elmStyle.getPropertyValue('background-color'));
+        if (bgColor.alpha !== 0) {
+          var opacity = elmStyle.getPropertyValue('opacity');
+          bgColor.alpha = bgColor.alpha * opacity;
+        }
+        return bgColor;
+      };
       color.incompleteData = function() {
         var data = {};
         return {
@@ -8629,10 +15013,9 @@
         }
         return finalElements;
       };
-      dom.findElmsInContext = function(_ref8) {
-        var context = _ref8.context, value = _ref8.value, attr = _ref8.attr, _ref8$elm = _ref8.elm, elm = _ref8$elm === undefined ? '' : _ref8$elm;
-        var root = void 0;
-        context = context.actualNode || context;
+      dom.findElmsInContext = function(_ref27) {
+        var context = _ref27.context, value = _ref27.value, attr = _ref27.attr, _ref27$elm = _ref27.elm, elm = _ref27$elm === void 0 ? '' : _ref27$elm;
+        var root;
         var escapedValue = axe.utils.escapeSelector(value);
         if (context.nodeType === 9 || context.nodeType === 11) {
           root = context;
@@ -8642,22 +15025,30 @@
         return Array.from(root.querySelectorAll(elm + '[' + attr + '=' + escapedValue + ']'));
       };
       dom.findUp = function(element, target) {
-        var doc = void 0, matches = void 0, parent = element;
+        return dom.findUpVirtual(axe.utils.getNodeFromTree(element), target);
+      };
+      dom.findUpVirtual = function(element, target) {
+        var parent;
+        parent = element.actualNode;
+        if (!element.shadowId && typeof element.actualNode.closest === 'function') {
+          var match = element.actualNode.closest(target);
+          if (match) {
+            return match;
+          }
+          return null;
+        }
         do {
           parent = parent.assignedSlot ? parent.assignedSlot : parent.parentNode;
           if (parent && parent.nodeType === 11) {
-            matches = null;
             parent = parent.host;
           }
-          if (!matches) {
-            doc = axe.commons.dom.getRootNode(parent);
-            matches = doc.querySelectorAll(target);
-            matches = axe.utils.toArray(matches);
-            if (doc === document && !matches.length) {
-              return null;
-            }
-          }
-        } while (parent && !matches.includes(parent));
+        } while (parent && !axe.utils.matchesSelector(parent, target) && parent !== document.documentElement);
+        if (!parent) {
+          return null;
+        }
+        if (!axe.utils.matchesSelector(parent, target)) {
+          return null;
+        }
         return parent;
       };
       dom.getComposedParent = function getComposedParent(element) {
@@ -8675,16 +15066,21 @@
       };
       dom.getElementByReference = function(node, attr) {
         var fragment = node.getAttribute(attr);
-        if (fragment && fragment.charAt(0) === '#') {
-          fragment = fragment.substring(1);
-          var candidate = document.getElementById(fragment);
-          if (candidate) {
-            return candidate;
-          }
-          candidate = document.getElementsByName(fragment);
-          if (candidate.length) {
-            return candidate[0];
-          }
+        if (!fragment) {
+          return null;
+        }
+        if (fragment.charAt(0) === '#') {
+          fragment = decodeURIComponent(fragment.substring(1));
+        } else if (fragment.substr(0, 2) === '/#') {
+          fragment = decodeURIComponent(fragment.substring(2));
+        }
+        var candidate = document.getElementById(fragment);
+        if (candidate) {
+          return candidate;
+        }
+        candidate = document.getElementsByName(fragment);
+        if (candidate.length) {
+          return candidate[0];
         }
         return null;
       };
@@ -8700,13 +15096,7 @@
           height: coords.bottom - coords.top
         };
       };
-      dom.getRootNode = function(node) {
-        var doc = node.getRootNode && node.getRootNode() || document;
-        if (doc === node) {
-          doc = document;
-        }
-        return doc;
-      };
+      dom.getRootNode = axe.utils.getRootNode;
       dom.getScrollOffset = function(element) {
         'use strict';
         if (!element.nodeType && element.document) {
@@ -8724,6 +15114,16 @@
           top: element.scrollTop
         };
       };
+      dom.getTabbableElements = function getTabbableElements(virtualNode) {
+        var nodeAndDescendents = axe.utils.querySelectorAll(virtualNode, '*');
+        var tabbableElements = nodeAndDescendents.filter(function(vNode) {
+          var isFocusable = vNode.isFocusable;
+          var tabIndex = vNode.actualNode.getAttribute('tabindex');
+          tabIndex = tabIndex && !isNaN(parseInt(tabIndex, 10)) ? parseInt(tabIndex) : null;
+          return tabIndex ? isFocusable && tabIndex >= 0 : isFocusable;
+        });
+        return tabbableElements;
+      };
       dom.getViewportSize = function(win) {
         'use strict';
         var body, doc = win.document, docElement = doc.documentElement;
@@ -8748,20 +15148,21 @@
       var hiddenTextElms = [ 'HEAD', 'TITLE', 'TEMPLATE', 'SCRIPT', 'STYLE', 'IFRAME', 'OBJECT', 'VIDEO', 'AUDIO', 'NOSCRIPT' ];
       function hasChildTextNodes(elm) {
         if (!hiddenTextElms.includes(elm.actualNode.nodeName.toUpperCase())) {
-          return elm.children.some(function(_ref9) {
-            var actualNode = _ref9.actualNode;
+          return elm.children.some(function(_ref28) {
+            var actualNode = _ref28.actualNode;
             return actualNode.nodeType === 3 && actualNode.nodeValue.trim();
           });
         }
       }
-      dom.hasContent = function hasContent(elm, noRecursion) {
-        if (!elm.actualNode) {
-          elm = axe.utils.getNodeFromTree(axe._tree[0], elm);
-        }
-        return hasChildTextNodes(elm) || dom.isVisualContent(elm.actualNode) || !!aria.label(elm) || !noRecursion && elm.children.some(function(child) {
-          return child.actualNode.nodeType === 1 && dom.hasContent(child);
+      dom.hasContentVirtual = function(elm, noRecursion, ignoreAria) {
+        return hasChildTextNodes(elm) || dom.isVisualContent(elm.actualNode) || !!ignoreAria || !!aria.labelVirtual(elm) || !noRecursion && elm.children.some(function(child) {
+          return child.actualNode.nodeType === 1 && dom.hasContentVirtual(child);
         });
       };
+      dom.hasContent = function hasContent(elm, noRecursion, ignoreAria) {
+        elm = axe.utils.getNodeFromTree(elm);
+        return dom.hasContentVirtual(elm, noRecursion, ignoreAria);
+      };
       dom.idrefs = function(node, attr) {
         'use strict';
         var index, length, doc = dom.getRootNode(node), result = [], idrefs = node.getAttribute(attr);
@@ -8773,9 +15174,25 @@
         }
         return result;
       };
+      function focusDisabled(el) {
+        return el.disabled || dom.isHiddenWithCSS(el) && el.nodeName.toUpperCase() !== 'AREA';
+      }
       dom.isFocusable = function(el) {
         'use strict';
-        if (!el || el.disabled || !dom.isVisible(el) && el.nodeName.toUpperCase() !== 'AREA') {
+        if (focusDisabled(el)) {
+          return false;
+        } else if (dom.isNativelyFocusable(el)) {
+          return true;
+        }
+        var tabindex = el.getAttribute('tabindex');
+        if (tabindex && !isNaN(parseInt(tabindex, 10))) {
+          return true;
+        }
+        return false;
+      };
+      dom.isNativelyFocusable = function(el) {
+        'use strict';
+        if (!el || focusDisabled(el)) {
           return false;
         }
         switch (el.nodeName.toUpperCase()) {
@@ -8795,10 +15212,41 @@
          case 'BUTTON':
           return true;
         }
-        var tabindex = el.getAttribute('tabindex');
-        if (tabindex && !isNaN(parseInt(tabindex, 10))) {
+        return false;
+      };
+      dom.insertedIntoFocusOrder = function(el) {
+        return el.tabIndex > -1 && dom.isFocusable(el) && !dom.isNativelyFocusable(el);
+      };
+      dom.isHiddenWithCSS = function isHiddenWithCSS(el, descendentVisibilityValue) {
+        if (el.nodeType === 9) {
+          return false;
+        }
+        if (el.nodeType === 11) {
+          el = el.host;
+        }
+        if ([ 'STYLE', 'SCRIPT' ].includes(el.nodeName.toUpperCase())) {
+          return false;
+        }
+        var style = window.getComputedStyle(el, null);
+        if (!style) {
+          throw new Error('Style does not exist for the given element.');
+        }
+        var displayValue = style.getPropertyValue('display');
+        if (displayValue === 'none') {
           return true;
         }
+        var HIDDEN_VISIBILITY_VALUES = [ 'hidden', 'collapse' ];
+        var visibilityValue = style.getPropertyValue('visibility');
+        if (HIDDEN_VISIBILITY_VALUES.includes(visibilityValue) && !descendentVisibilityValue) {
+          return true;
+        }
+        if (HIDDEN_VISIBILITY_VALUES.includes(visibilityValue) && descendentVisibilityValue && HIDDEN_VISIBILITY_VALUES.includes(descendentVisibilityValue)) {
+          return true;
+        }
+        var parent = dom.getComposedParent(el);
+        if (parent && !HIDDEN_VISIBILITY_VALUES.includes(visibilityValue)) {
+          return dom.isHiddenWithCSS(parent, visibilityValue);
+        }
         return false;
       };
       dom.isHTML5 = function(doc) {
@@ -8825,7 +15273,7 @@
         while (parentBlock && !isBlock(parentBlock)) {
           parentBlock = dom.getComposedParent(parentBlock);
         }
-        return axe.utils.getNodeFromTree(axe._tree[0], parentBlock);
+        return axe.utils.getNodeFromTree(parentBlock);
       }
       dom.isInTextBlock = function isInTextBlock(node) {
         if (isBlock(node)) {
@@ -8853,7 +15301,7 @@
             } else {
               inBrBlock = 2;
             }
-          } else if (currNode.style.display === 'none' || currNode.style.overflow === 'hidden' || ![ '', null, 'none' ].includes(currNode.style.float) || ![ '', null, 'relative' ].includes(currNode.style.position)) {
+          } else if (currNode.style.display === 'none' || currNode.style.overflow === 'hidden' || ![ '', null, 'none' ].includes(currNode.style['float']) || ![ '', null, 'relative' ].includes(currNode.style.position)) {
             return false;
           } else if (nodeName === 'A' && currNode.href || (currNode.getAttribute('role') || '').toLowerCase() === 'link') {
             if (currNode === node) {
@@ -8867,26 +15315,29 @@
         linkText = axe.commons.text.sanitize(linkText);
         return parentText.length > linkText.length;
       };
-      dom.isNode = function(candidate) {
+      dom.isNode = function(element) {
         'use strict';
-        return candidate instanceof Node;
+        return element instanceof Node;
       };
-      dom.isOffscreen = function(element) {
-        'use strict';
-        var noParentScrolled = function noParentScrolled(element, offset) {
-          element = element.parentNode;
-          while (element.nodeName.toLowerCase() !== 'html') {
-            if (element.scrollTop) {
-              offset += element.scrollTop;
-              if (offset >= 0) {
-                return false;
-              }
+      function noParentScrolled(element, offset) {
+        element = dom.getComposedParent(element);
+        while (element && element.nodeName.toLowerCase() !== 'html') {
+          if (element.scrollTop) {
+            offset += element.scrollTop;
+            if (offset >= 0) {
+              return false;
             }
-            element = element.parentNode;
           }
-          return true;
-        };
-        var leftBoundary, docElement = document.documentElement, styl = window.getComputedStyle(element), dir = window.getComputedStyle(document.body || docElement).getPropertyValue('direction'), coords = dom.getElementCoordinates(element);
+          element = dom.getComposedParent(element);
+        }
+        return true;
+      }
+      dom.isOffscreen = function(element) {
+        var leftBoundary;
+        var docElement = document.documentElement;
+        var styl = window.getComputedStyle(element);
+        var dir = window.getComputedStyle(document.body || docElement).getPropertyValue('direction');
+        var coords = dom.getElementCoordinates(element);
         if (coords.bottom < 0 && (noParentScrolled(element, coords.bottom) || styl.position === 'absolute')) {
           return true;
         }
@@ -8905,6 +15356,23 @@
         }
         return false;
       };
+      var isInternalLinkRegex = /^\/?#[^/!]/;
+      dom.isSkipLink = function(element) {
+        if (!isInternalLinkRegex.test(element.getAttribute('href'))) {
+          return false;
+        }
+        var firstPageLink;
+        if (typeof axe._cache.get('firstPageLink') !== 'undefined') {
+          firstPageLink = axe._cache.get('firstPageLink');
+        } else {
+          firstPageLink = axe.utils.querySelectorAll(axe._tree, 'a:not([href^="#"]):not([href^="/#"]):not([href^="javascript"])')[0];
+          axe._cache.set('firstPageLink', firstPageLink || null);
+        }
+        if (!firstPageLink) {
+          return true;
+        }
+        return element.compareDocumentPosition(firstPageLink.actualNode) === element.DOCUMENT_POSITION_FOLLOWING;
+      };
       function isClipped(clip) {
         'use strict';
         var matches = clip.match(/rect\s*\(([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px\s*\)/);
@@ -8915,34 +15383,42 @@
       }
       dom.isVisible = function(el, screenReader, recursed) {
         'use strict';
-        var style, nodeName, parent;
+        var node = axe.utils.getNodeFromTree(el);
+        var cacheName = '_isVisible' + (screenReader ? 'ScreenReader' : '');
         if (el.nodeType === 9) {
           return true;
         }
         if (el.nodeType === 11) {
           el = el.host;
         }
-        style = window.getComputedStyle(el, null);
+        if (node && typeof node[cacheName] !== 'undefined') {
+          return node[cacheName];
+        }
+        var style = window.getComputedStyle(el, null);
         if (style === null) {
           return false;
         }
-        nodeName = el.nodeName.toUpperCase();
-        if (style.getPropertyValue('display') === 'none' || nodeName.toUpperCase() === 'STYLE' || nodeName.toUpperCase() === 'SCRIPT' || !screenReader && isClipped(style.getPropertyValue('clip')) || !recursed && (style.getPropertyValue('visibility') === 'hidden' || !screenReader && dom.isOffscreen(el)) || screenReader && el.getAttribute('aria-hidden') === 'true') {
+        var nodeName = el.nodeName.toUpperCase();
+        if (style.getPropertyValue('display') === 'none' || [ 'STYLE', 'SCRIPT', 'NOSCRIPT', 'TEMPLATE' ].includes(nodeName) || !screenReader && isClipped(style.getPropertyValue('clip')) || !recursed && (style.getPropertyValue('visibility') === 'hidden' || !screenReader && dom.isOffscreen(el)) || screenReader && el.getAttribute('aria-hidden') === 'true') {
           return false;
         }
-        parent = el.assignedSlot ? el.assignedSlot : el.parentNode;
+        var parent = el.assignedSlot ? el.assignedSlot : el.parentNode;
+        var isVisible = false;
         if (parent) {
-          return dom.isVisible(parent, screenReader, true);
+          isVisible = dom.isVisible(parent, screenReader, true);
         }
-        return false;
+        if (node) {
+          node[cacheName] = isVisible;
+        }
+        return isVisible;
       };
       var visualRoles = [ 'checkbox', 'img', 'radio', 'range', 'slider', 'spinbutton', 'textbox' ];
-      dom.isVisualContent = function(candidate) {
-        var role = candidate.getAttribute('role');
+      dom.isVisualContent = function(element) {
+        var role = element.getAttribute('role');
         if (role) {
           return visualRoles.indexOf(role) !== -1;
         }
-        switch (candidate.tagName.toUpperCase()) {
+        switch (element.nodeName.toUpperCase()) {
          case 'IMG':
          case 'IFRAME':
          case 'OBJECT':
@@ -8960,12 +15436,33 @@
           return true;
 
          case 'INPUT':
-          return candidate.type !== 'hidden';
+          return element.type !== 'hidden';
 
          default:
           return false;
         }
       };
+      dom.shadowElementsFromPoint = function(nodeX, nodeY) {
+        var root = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : document;
+        var i = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
+        if (i > 999) {
+          throw new Error('Infinite loop detected');
+        }
+        return Array.from(root.elementsFromPoint(nodeX, nodeY)).filter(function(nodes) {
+          return dom.getRootNode(nodes) === root;
+        }).reduce(function(stack, elm) {
+          if (axe.utils.isShadowRoot(elm)) {
+            var shadowStack = dom.shadowElementsFromPoint(nodeX, nodeY, elm.shadowRoot, i + 1);
+            stack = stack.concat(shadowStack);
+            if (stack.length && axe.commons.dom.visuallyContains(stack[0], elm)) {
+              stack.push(elm);
+            }
+          } else {
+            stack.push(elm);
+          }
+          return stack;
+        }, []);
+      };
       dom.visuallyContains = function(node, parent) {
         var rectBound = node.getBoundingClientRect();
         var margin = .01;
@@ -9015,6 +15512,114 @@
         }
         return true;
       };
+      forms.isAriaCombobox = function(node) {
+        var role = axe.commons.aria.getRole(node, {
+          noImplicit: true
+        });
+        return role === 'combobox';
+      };
+      forms.isAriaListbox = function(node) {
+        var role = axe.commons.aria.getRole(node, {
+          noImplicit: true
+        });
+        return role === 'listbox';
+      };
+      var rangeRoles = [ 'progressbar', 'scrollbar', 'slider', 'spinbutton' ];
+      forms.isAriaRange = function(node) {
+        var role = axe.commons.aria.getRole(node, {
+          noImplicit: true
+        });
+        return rangeRoles.includes(role);
+      };
+      forms.isAriaTextbox = function(node) {
+        var role = axe.commons.aria.getRole(node, {
+          noImplicit: true
+        });
+        return role === 'textbox';
+      };
+      forms.isNativeSelect = function(node) {
+        var nodeName = node.nodeName.toUpperCase();
+        return nodeName === 'SELECT';
+      };
+      var nonTextInputTypes = [ 'button', 'checkbox', 'color', 'file', 'hidden', 'image', 'password', 'radio', 'reset', 'submit' ];
+      forms.isNativeTextbox = function(node) {
+        var nodeName = node.nodeName.toUpperCase();
+        return nodeName === 'TEXTAREA' || nodeName === 'INPUT' && !nonTextInputTypes.includes(node.type);
+      };
+      matches.attributes = function matchesAttributes(node, matcher) {
+        node = node.actualNode || node;
+        return matches.fromFunction(function(attrName) {
+          return node.getAttribute(attrName);
+        }, matcher);
+      };
+      matches.condition = function(arg, condition) {
+        return !!condition(arg);
+      };
+      var matchers = [ 'nodeName', 'attributes', 'properties', 'condition' ];
+      matches.fromDefinition = function matchFromDefinition(node, definition) {
+        node = node.actualNode || node;
+        if (Array.isArray(definition)) {
+          return definition.some(function(definitionItem) {
+            return matches(node, definitionItem);
+          });
+        }
+        if (typeof definition === 'string') {
+          return axe.utils.matchesSelector(node, definition);
+        }
+        return Object.keys(definition).every(function(matcherName) {
+          if (!matchers.includes(matcherName)) {
+            throw new Error('Unknown matcher type "'.concat(matcherName, '"'));
+          }
+          var matchMethod = matches[matcherName];
+          var matcher = definition[matcherName];
+          return matchMethod(node, matcher);
+        });
+      };
+      matches.fromFunction = function matchFromFunction(getValue, matcher) {
+        var matcherType = _typeof(matcher);
+        if (matcherType !== 'object' || Array.isArray(matcher) || matcher instanceof RegExp) {
+          throw new Error('Expect matcher to be an object');
+        }
+        return Object.keys(matcher).every(function(propName) {
+          return matches.fromPrimative(getValue(propName), matcher[propName]);
+        });
+      };
+      matches.fromPrimative = function matchFromPrimative(someString, matcher) {
+        var matcherType = _typeof(matcher);
+        if (Array.isArray(matcher) && typeof someString !== 'undefined') {
+          return matcher.includes(someString);
+        }
+        if (matcherType === 'function') {
+          return !!matcher(someString);
+        }
+        if (matcher instanceof RegExp) {
+          return matcher.test(someString);
+        }
+        return matcher === someString;
+      };
+      var isXHTMLGlobal;
+      matches.nodeName = function matchNodeName(node, matcher) {
+        var _ref29 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, isXHTML = _ref29.isXHTML;
+        node = node.actualNode || node;
+        if (typeof isXHTML === 'undefined') {
+          if (typeof matcher === 'string') {
+            return axe.utils.matchesSelector(node, matcher);
+          }
+          if (typeof isXHTMLGlobal === 'undefined') {
+            isXHTMLGlobal = axe.utils.isXHTML(node.ownerDocument);
+          }
+          isXHTML = isXHTMLGlobal;
+        }
+        var nodeName = isXHTML ? node.nodeName : node.nodeName.toLowerCase();
+        return matches.fromPrimative(nodeName, matcher);
+      };
+      matches.properties = function matchesProperties(node, matcher) {
+        node = node.actualNode || node;
+        var out = matches.fromFunction(function(propName) {
+          return node[propName];
+        }, matcher);
+        return out;
+      };
       table.getAllCells = function(tableElm) {
         var rowIndex, cellIndex, rowLength, cellLength;
         var cells = [];
@@ -9082,24 +15687,29 @@
         var headerCol = tableGrid.map(function(col) {
           return col[pos.x];
         }).reduce(function(headerCol, cell) {
-          return headerCol && cell.nodeName.toUpperCase() === 'TH';
+          return headerCol && cell && cell.nodeName.toUpperCase() === 'TH';
         }, true);
         if (headerCol) {
           return 'row';
         }
         return 'auto';
       };
-      table.isColumnHeader = function(node) {
-        return [ 'col', 'auto' ].indexOf(table.getScope(node)) !== -1;
+      table.isColumnHeader = function(element) {
+        return [ 'col', 'auto' ].indexOf(table.getScope(element)) !== -1;
       };
       table.isDataCell = function(cell) {
         if (!cell.children.length && !cell.textContent.trim()) {
           return false;
         }
-        return cell.nodeName.toUpperCase() === 'TD';
+        var role = cell.getAttribute('role');
+        if (axe.commons.aria.isValidRole(role)) {
+          return [ 'cell', 'gridcell' ].includes(role);
+        } else {
+          return cell.nodeName.toUpperCase() === 'TD';
+        }
       };
       table.isDataTable = function(node) {
-        var role = node.getAttribute('role');
+        var role = (node.getAttribute('role') || '').toLowerCase();
         if ((role === 'presentation' || role === 'none') && !dom.isFocusable(node)) {
           return false;
         }
@@ -9143,7 +15753,7 @@
             if (cell.getAttribute('scope') || cell.getAttribute('headers') || cell.getAttribute('abbr')) {
               return true;
             }
-            if ([ 'columnheader', 'rowheader' ].indexOf(cell.getAttribute('role')) !== -1) {
+            if ([ 'columnheader', 'rowheader' ].includes((cell.getAttribute('role') || '').toLowerCase())) {
               return true;
             }
             if (cell.children.length === 1 && cell.children[0].nodeName.toUpperCase() === 'ABBR') {
@@ -9202,12 +15812,12 @@
         }
         if (cell.getAttribute('id')) {
           var id = axe.utils.escapeSelector(cell.getAttribute('id'));
-          return !!document.querySelector('[headers~="' + id + '"]');
+          return !!document.querySelector('[headers~="'.concat(id, '"]'));
         }
         return false;
       };
-      table.isRowHeader = function(node) {
-        return [ 'row', 'auto' ].indexOf(table.getScope(node)) !== -1;
+      table.isRowHeader = function(cell) {
+        return [ 'row', 'auto' ].includes(table.getScope(cell));
       };
       table.toGrid = function(node) {
         var table = [];
@@ -9298,279 +15908,514 @@
           }, tableGrid, callback);
         };
       })(table);
-      var defaultButtonValues = {
-        submit: 'Submit',
-        reset: 'Reset'
+      text.accessibleText = function accessibleText(element, context) {
+        var virtualNode = axe.utils.getNodeFromTree(element);
+        return text.accessibleTextVirtual(virtualNode, context);
       };
-      var inputTypes = [ 'text', 'search', 'tel', 'url', 'email', 'date', 'time', 'number', 'range', 'color' ];
-      var phrasingElements = [ 'A', 'EM', 'STRONG', 'SMALL', 'MARK', 'ABBR', 'DFN', 'I', 'B', 'S', 'U', 'CODE', 'VAR', 'SAMP', 'KBD', 'SUP', 'SUB', 'Q', 'CITE', 'SPAN', 'BDO', 'BDI', 'BR', 'WBR', 'INS', 'DEL', 'IMG', 'EMBED', 'OBJECT', 'IFRAME', 'MAP', 'AREA', 'SCRIPT', 'NOSCRIPT', 'RUBY', 'VIDEO', 'AUDIO', 'INPUT', 'TEXTAREA', 'SELECT', 'BUTTON', 'LABEL', 'OUTPUT', 'DATALIST', 'KEYGEN', 'PROGRESS', 'COMMAND', 'CANVAS', 'TIME', 'METER' ];
-      function findLabel(_ref10) {
-        var actualNode = _ref10.actualNode;
-        var label = void 0;
-        if (actualNode.id) {
-          label = dom.findElmsInContext({
-            elm: 'label',
-            attr: 'for',
-            value: actualNode.id,
-            context: actualNode
-          })[0];
-        } else {
-          label = dom.findUp(actualNode, 'label');
-        }
-        return axe.utils.getNodeFromTree(axe._tree[0], label);
-      }
-      function isButton(_ref11) {
-        var actualNode = _ref11.actualNode;
-        return [ 'button', 'reset', 'submit' ].includes(actualNode.type.toLowerCase());
-      }
-      function isInput(_ref12) {
-        var actualNode = _ref12.actualNode;
-        var nodeName = actualNode.nodeName.toUpperCase();
-        return nodeName === 'TEXTAREA' || nodeName === 'SELECT' || nodeName === 'INPUT' && actualNode.type.toLowerCase() !== 'hidden';
-      }
-      function shouldCheckSubtree(_ref13) {
-        var actualNode = _ref13.actualNode;
-        return [ 'BUTTON', 'SUMMARY', 'A' ].includes(actualNode.nodeName.toUpperCase());
-      }
-      function shouldNeverCheckSubtree(_ref14) {
-        var actualNode = _ref14.actualNode;
-        return [ 'TABLE', 'FIGURE' ].includes(actualNode.nodeName.toUpperCase());
-      }
-      function formValueText(_ref15) {
-        var actualNode = _ref15.actualNode;
-        var nodeName = actualNode.nodeName.toUpperCase();
-        if (nodeName === 'INPUT') {
-          if (!actualNode.hasAttribute('type') || inputTypes.includes(actualNode.type.toLowerCase())) {
-            return actualNode.value;
-          }
+      text.accessibleTextVirtual = function accessibleTextVirtual(virtualNode) {
+        var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+        var actualNode = virtualNode.actualNode;
+        context = prepareContext(virtualNode, context);
+        if (shouldIgnoreHidden(virtualNode, context)) {
           return '';
         }
-        if (nodeName === 'SELECT') {
-          var opts = actualNode.options;
-          if (opts && opts.length) {
-            var returnText = '';
-            for (var i = 0; i < opts.length; i++) {
-              if (opts[i].selected) {
-                returnText += ' ' + opts[i].text;
-              }
-            }
-            return text.sanitize(returnText);
+        var computationSteps = [ aria.arialabelledbyText, aria.arialabelText, text.nativeTextAlternative, text.formControlValue, text.subtreeText, textNodeContent, text.titleText ];
+        var accName = computationSteps.reduce(function(accName, step) {
+          if (context.startNode === virtualNode) {
+            accName = text.sanitize(accName);
           }
+          if (accName !== '') {
+            return accName;
+          }
+          return step(virtualNode, context);
+        }, '');
+        if (context.debug) {
+          axe.log(accName || '{empty-value}', actualNode, context);
+        }
+        return accName;
+      };
+      function textNodeContent(_ref30) {
+        var actualNode = _ref30.actualNode;
+        if (actualNode.nodeType !== 3) {
           return '';
         }
-        if (nodeName === 'TEXTAREA' && actualNode.value) {
-          return actualNode.value;
-        }
-        return '';
+        return actualNode.textContent;
       }
-      function checkDescendant(_ref16, nodeName) {
-        var actualNode = _ref16.actualNode;
-        var candidate = actualNode.querySelector(nodeName.toLowerCase());
-        if (candidate) {
-          return text.accessibleText(candidate);
-        }
-        return '';
-      }
-      function isEmbeddedControl(elm) {
-        if (!elm) {
+      function shouldIgnoreHidden(_ref31, context) {
+        var actualNode = _ref31.actualNode;
+        if (actualNode.nodeType !== 1 || context.includeHidden) {
           return false;
         }
-        var actualNode = elm.actualNode;
-        switch (actualNode.nodeName.toUpperCase()) {
-         case 'SELECT':
-         case 'TEXTAREA':
+        return !dom.isVisible(actualNode, true);
+      }
+      function prepareContext(virtualNode, context) {
+        var actualNode = virtualNode.actualNode;
+        if (!context.startNode) {
+          context = _extends({
+            startNode: virtualNode
+          }, context);
+        }
+        if (actualNode.nodeType === 1 && context.inLabelledByContext && context.includeHidden === undefined) {
+          context = _extends({
+            includeHidden: !dom.isVisible(actualNode, true)
+          }, context);
+        }
+        return context;
+      }
+      text.accessibleTextVirtual.alreadyProcessed = function alreadyProcessed(virtualnode, context) {
+        context.processed = context.processed || [];
+        if (context.processed.includes(virtualnode)) {
           return true;
-
-         case 'INPUT':
-          return !actualNode.hasAttribute('type') || inputTypes.includes(actualNode.getAttribute('type').toLowerCase());
-
-         default:
-          return false;
         }
-      }
-      function shouldCheckAlt(_ref17) {
-        var actualNode = _ref17.actualNode;
-        var nodeName = actualNode.nodeName.toUpperCase();
-        return [ 'IMG', 'APPLET', 'AREA' ].includes(nodeName) || nodeName === 'INPUT' && actualNode.type.toLowerCase() === 'image';
-      }
-      function nonEmptyText(t) {
-        return !!text.sanitize(t);
-      }
-      text.accessibleText = function(element, inLabelledByContext) {
-        var accessibleNameComputation = void 0;
-        var encounteredNodes = [];
-        if (element instanceof Node) {
-          element = axe.utils.getNodeFromTree(axe._tree[0], element);
-        }
-        function getInnerText(element, inLabelledByContext, inControlContext) {
-          return element.children.reduce(function(returnText, child) {
-            var actualNode = child.actualNode;
-            if (actualNode.nodeType === 3) {
-              returnText += actualNode.nodeValue;
-            } else if (actualNode.nodeType === 1) {
-              if (!phrasingElements.includes(actualNode.nodeName.toUpperCase())) {
-                returnText += ' ';
-              }
-              returnText += accessibleNameComputation(child, inLabelledByContext, inControlContext);
-            }
-            return returnText;
-          }, '');
-        }
-        function checkNative(element, inLabelledByContext, inControlContext) {
-          var returnText = '';
-          var actualNode = element.actualNode;
-          var nodeName = actualNode.nodeName.toUpperCase();
-          if (shouldCheckSubtree(element)) {
-            returnText = getInnerText(element, false, false) || '';
-            if (nonEmptyText(returnText)) {
-              return returnText;
-            }
-          }
-          if (nodeName === 'FIGURE') {
-            returnText = checkDescendant(element, 'figcaption');
-            if (nonEmptyText(returnText)) {
-              return returnText;
-            }
-          }
-          if (nodeName === 'TABLE') {
-            returnText = checkDescendant(element, 'caption');
-            if (nonEmptyText(returnText)) {
-              return returnText;
-            }
-            returnText = actualNode.getAttribute('title') || actualNode.getAttribute('summary') || '';
-            if (nonEmptyText(returnText)) {
-              return returnText;
-            }
-          }
-          if (shouldCheckAlt(element)) {
-            return actualNode.getAttribute('alt') || '';
-          }
-          if (isInput(element) && !inControlContext) {
-            if (isButton(element)) {
-              return actualNode.value || actualNode.title || defaultButtonValues[actualNode.type] || '';
-            }
-            var labelElement = findLabel(element);
-            if (labelElement) {
-              return accessibleNameComputation(labelElement, inLabelledByContext, true);
-            }
-          }
-          return '';
-        }
-        function checkARIA(element, inLabelledByContext, inControlContext) {
-          var returnText = '';
-          var actualNode = element.actualNode;
-          if (!inLabelledByContext && actualNode.hasAttribute('aria-labelledby')) {
-            returnText = text.sanitize(dom.idrefs(actualNode, 'aria-labelledby').map(function(label) {
-              if (label !== null) {
-                if (actualNode === label) {
-                  encounteredNodes.pop();
-                }
-                var vLabel = axe.utils.getNodeFromTree(axe._tree[0], label);
-                return accessibleNameComputation(vLabel, true, actualNode !== label);
-              } else {
-                return '';
-              }
-            }).join(' '));
-          }
-          if (!returnText && !(inControlContext && isEmbeddedControl(element)) && actualNode.hasAttribute('aria-label')) {
-            return text.sanitize(actualNode.getAttribute('aria-label'));
-          }
-          return returnText;
-        }
-        accessibleNameComputation = function accessibleNameComputation(element, inLabelledByContext, inControlContext) {
-          var returnText = void 0;
-          if (!element || encounteredNodes.includes(element)) {
-            return '';
-          } else if (element !== null && element.actualNode instanceof Node !== true) {
-            throw new Error('Invalid argument. Virtual Node must be provided');
-          } else if (!inLabelledByContext && !dom.isVisible(element.actualNode, true)) {
-            return '';
-          }
-          encounteredNodes.push(element);
-          var role = element.actualNode.getAttribute('role');
-          returnText = checkARIA(element, inLabelledByContext, inControlContext);
-          if (nonEmptyText(returnText)) {
-            return returnText;
-          }
-          returnText = checkNative(element, inLabelledByContext, inControlContext);
-          if (nonEmptyText(returnText)) {
-            return returnText;
-          }
-          if (inControlContext) {
-            returnText = formValueText(element);
-            if (nonEmptyText(returnText)) {
-              return returnText;
-            }
-          }
-          if (!shouldNeverCheckSubtree(element) && (!role || aria.getRolesWithNameFromContents().indexOf(role) !== -1)) {
-            returnText = getInnerText(element, inLabelledByContext, inControlContext);
-            if (nonEmptyText(returnText)) {
-              return returnText;
-            }
-          }
-          if (element.actualNode.hasAttribute('title')) {
-            return element.actualNode.getAttribute('title');
-          }
-          return '';
-        };
-        return text.sanitize(accessibleNameComputation(element, inLabelledByContext));
+        context.processed.push(virtualnode);
+        return false;
       };
-      text.label = function(node) {
+      var controlValueRoles = [ 'textbox', 'progressbar', 'scrollbar', 'slider', 'spinbutton', 'combobox', 'listbox' ];
+      text.formControlValueMethods = {
+        nativeTextboxValue: nativeTextboxValue,
+        nativeSelectValue: nativeSelectValue,
+        ariaTextboxValue: ariaTextboxValue,
+        ariaListboxValue: ariaListboxValue,
+        ariaComboboxValue: ariaComboboxValue,
+        ariaRangeValue: ariaRangeValue
+      };
+      text.formControlValue = function formControlValue(virtualNode) {
+        var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+        var actualNode = virtualNode.actualNode;
+        var unsupported = text.unsupported.accessibleNameFromFieldValue || [];
+        var role = aria.getRole(actualNode);
+        if (context.startNode === virtualNode || !controlValueRoles.includes(role) || unsupported.includes(role)) {
+          return '';
+        }
+        var valueMethods = Object.keys(text.formControlValueMethods).map(function(name) {
+          return text.formControlValueMethods[name];
+        });
+        var valueString = valueMethods.reduce(function(accName, step) {
+          return accName || step(virtualNode, context);
+        }, '');
+        if (context.debug) {
+          axe.log(valueString || '{empty-value}', actualNode, context);
+        }
+        return valueString;
+      };
+      function nativeTextboxValue(node) {
+        node = node.actualNode || node;
+        if (axe.commons.forms.isNativeTextbox(node)) {
+          return node.value || '';
+        }
+        return '';
+      }
+      function nativeSelectValue(node) {
+        node = node.actualNode || node;
+        if (!axe.commons.forms.isNativeSelect(node)) {
+          return '';
+        }
+        return Array.from(node.options).filter(function(option) {
+          return option.selected;
+        }).map(function(option) {
+          return option.text;
+        }).join(' ') || '';
+      }
+      function ariaTextboxValue(virtualNode) {
+        var actualNode = virtualNode.actualNode;
+        if (!axe.commons.forms.isAriaTextbox(actualNode)) {
+          return '';
+        }
+        if (!dom.isHiddenWithCSS(actualNode)) {
+          return text.visibleVirtual(virtualNode, true);
+        } else {
+          return actualNode.textContent;
+        }
+      }
+      function ariaListboxValue(virtualNode, context) {
+        var actualNode = virtualNode.actualNode;
+        if (!axe.commons.forms.isAriaListbox(actualNode)) {
+          return '';
+        }
+        var selected = aria.getOwnedVirtual(virtualNode).filter(function(owned) {
+          return aria.getRole(owned) === 'option' && owned.actualNode.getAttribute('aria-selected') === 'true';
+        });
+        if (selected.length === 0) {
+          return '';
+        }
+        return axe.commons.text.accessibleTextVirtual(selected[0], context);
+      }
+      function ariaComboboxValue(virtualNode, context) {
+        var actualNode = virtualNode.actualNode;
+        var listbox;
+        if (!axe.commons.forms.isAriaCombobox(actualNode)) {
+          return '';
+        }
+        listbox = aria.getOwnedVirtual(virtualNode).filter(function(elm) {
+          return aria.getRole(elm) === 'listbox';
+        })[0];
+        return listbox ? text.formControlValueMethods.ariaListboxValue(listbox, context) : '';
+      }
+      function ariaRangeValue(node) {
+        node = node.actualNode || node;
+        if (!axe.commons.forms.isAriaRange(node) || !node.hasAttribute('aria-valuenow')) {
+          return '';
+        }
+        var valueNow = +node.getAttribute('aria-valuenow');
+        return !isNaN(valueNow) ? String(valueNow) : '0';
+      }
+      text.isHumanInterpretable = function(str) {
+        if (!str.length) {
+          return 0;
+        }
+        var alphaNumericIconMap = [ 'x', 'i' ];
+        if (alphaNumericIconMap.includes(str)) {
+          return 0;
+        }
+        var noUnicodeStr = text.removeUnicode(str, {
+          emoji: true,
+          nonBmp: true,
+          punctuations: true
+        });
+        if (!text.sanitize(noUnicodeStr)) {
+          return 0;
+        }
+        return 1;
+      };
+      var autocomplete = {
+        stateTerms: [ 'on', 'off' ],
+        standaloneTerms: [ 'name', 'honorific-prefix', 'given-name', 'additional-name', 'family-name', 'honorific-suffix', 'nickname', 'username', 'new-password', 'current-password', 'organization-title', 'organization', 'street-address', 'address-line1', 'address-line2', 'address-line3', 'address-level4', 'address-level3', 'address-level2', 'address-level1', 'country', 'country-name', 'postal-code', 'cc-name', 'cc-given-name', 'cc-additional-name', 'cc-family-name', 'cc-number', 'cc-exp', 'cc-exp-month', 'cc-exp-year', 'cc-csc', 'cc-type', 'transaction-currency', 'transaction-amount', 'language', 'bday', 'bday-day', 'bday-month', 'bday-year', 'sex', 'url', 'photo' ],
+        qualifiers: [ 'home', 'work', 'mobile', 'fax', 'pager' ],
+        qualifiedTerms: [ 'tel', 'tel-country-code', 'tel-national', 'tel-area-code', 'tel-local', 'tel-local-prefix', 'tel-local-suffix', 'tel-extension', 'email', 'impp' ],
+        locations: [ 'billing', 'shipping' ]
+      };
+      text.autocomplete = autocomplete;
+      text.isValidAutocomplete = function isValidAutocomplete(autocomplete) {
+        var _ref32 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref32$looseTyped = _ref32.looseTyped, looseTyped = _ref32$looseTyped === void 0 ? false : _ref32$looseTyped, _ref32$stateTerms = _ref32.stateTerms, stateTerms = _ref32$stateTerms === void 0 ? [] : _ref32$stateTerms, _ref32$locations = _ref32.locations, locations = _ref32$locations === void 0 ? [] : _ref32$locations, _ref32$qualifiers = _ref32.qualifiers, qualifiers = _ref32$qualifiers === void 0 ? [] : _ref32$qualifiers, _ref32$standaloneTerm = _ref32.standaloneTerms, standaloneTerms = _ref32$standaloneTerm === void 0 ? [] : _ref32$standaloneTerm, _ref32$qualifiedTerms = _ref32.qualifiedTerms, qualifiedTerms = _ref32$qualifiedTerms === void 0 ? [] : _ref32$qualifiedTerms;
+        autocomplete = autocomplete.toLowerCase().trim();
+        stateTerms = stateTerms.concat(text.autocomplete.stateTerms);
+        if (stateTerms.includes(autocomplete) || autocomplete === '') {
+          return true;
+        }
+        qualifiers = qualifiers.concat(text.autocomplete.qualifiers);
+        locations = locations.concat(text.autocomplete.locations);
+        standaloneTerms = standaloneTerms.concat(text.autocomplete.standaloneTerms);
+        qualifiedTerms = qualifiedTerms.concat(text.autocomplete.qualifiedTerms);
+        var autocompleteTerms = autocomplete.split(/\s+/g);
+        if (!looseTyped) {
+          if (autocompleteTerms[0].length > 8 && autocompleteTerms[0].substr(0, 8) === 'section-') {
+            autocompleteTerms.shift();
+          }
+          if (locations.includes(autocompleteTerms[0])) {
+            autocompleteTerms.shift();
+          }
+          if (qualifiers.includes(autocompleteTerms[0])) {
+            autocompleteTerms.shift();
+            standaloneTerms = [];
+          }
+          if (autocompleteTerms.length !== 1) {
+            return false;
+          }
+        }
+        var purposeTerm = autocompleteTerms[autocompleteTerms.length - 1];
+        return standaloneTerms.includes(purposeTerm) || qualifiedTerms.includes(purposeTerm);
+      };
+      text.labelText = function labelText(virtualNode) {
+        var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+        var alreadyProcessed = text.accessibleTextVirtual.alreadyProcessed;
+        if (context.inControlContext || context.inLabelledByContext || alreadyProcessed(virtualNode, context)) {
+          return '';
+        }
+        if (!context.startNode) {
+          context.startNode = virtualNode;
+        }
+        var labelContext = _extends({
+          inControlContext: true
+        }, context);
+        var explicitLabels = getExplicitLabels(virtualNode);
+        var implicitLabel = dom.findUpVirtual(virtualNode, 'label');
+        var labels;
+        if (implicitLabel) {
+          labels = [].concat(_toConsumableArray(explicitLabels), [ implicitLabel ]);
+          labels.sort(axe.utils.nodeSorter);
+        } else {
+          labels = explicitLabels;
+        }
+        return labels.map(function(label) {
+          return text.accessibleText(label, labelContext);
+        }).filter(function(text) {
+          return text !== '';
+        }).join(' ');
+      };
+      function getExplicitLabels(_ref33) {
+        var actualNode = _ref33.actualNode;
+        if (!actualNode.id) {
+          return [];
+        }
+        return dom.findElmsInContext({
+          elm: 'label',
+          attr: 'for',
+          value: actualNode.id,
+          context: actualNode
+        });
+      }
+      text.labelVirtual = function(node) {
         var ref, candidate, doc;
-        candidate = aria.label(node);
+        candidate = aria.labelVirtual(node);
         if (candidate) {
           return candidate;
         }
         if (node.actualNode.id) {
-          var id = axe.commons.utils.escapeSelector(node.actualNode.getAttribute('id'));
+          var id = axe.utils.escapeSelector(node.actualNode.getAttribute('id'));
           doc = axe.commons.dom.getRootNode(node.actualNode);
           ref = doc.querySelector('label[for="' + id + '"]');
-          ref = axe.utils.getNodeFromTree(axe._tree[0], ref);
           candidate = ref && text.visible(ref, true);
           if (candidate) {
             return candidate;
           }
         }
-        ref = dom.findUp(node.actualNode, 'label');
-        ref = axe.utils.getNodeFromTree(axe._tree[0], ref);
+        ref = dom.findUpVirtual(node, 'label');
         candidate = ref && text.visible(ref, true);
         if (candidate) {
           return candidate;
         }
         return null;
       };
+      text.label = function(node) {
+        node = axe.utils.getNodeFromTree(node);
+        return text.labelVirtual(node);
+      };
+      text.nativeElementType = [ {
+        matches: [ {
+          nodeName: 'textarea'
+        }, {
+          nodeName: 'input',
+          properties: {
+            type: [ 'text', 'password', 'search', 'tel', 'email', 'url' ]
+          }
+        } ],
+        namingMethods: 'labelText'
+      }, {
+        matches: {
+          nodeName: 'input',
+          properties: {
+            type: [ 'button', 'submit', 'reset' ]
+          }
+        },
+        namingMethods: [ 'valueText', 'titleText', 'buttonDefaultText' ]
+      }, {
+        matches: {
+          nodeName: 'input',
+          properties: {
+            type: 'image'
+          }
+        },
+        namingMethods: [ 'altText', 'valueText', 'labelText', 'titleText', 'buttonDefaultText' ]
+      }, {
+        matches: 'button',
+        namingMethods: 'subtreeText'
+      }, {
+        matches: 'fieldset',
+        namingMethods: 'fieldsetLegendText'
+      }, {
+        matches: 'OUTPUT',
+        namingMethods: 'subtreeText'
+      }, {
+        matches: [ {
+          nodeName: 'select'
+        }, {
+          nodeName: 'input',
+          properties: {
+            type: /^(?!text|password|search|tel|email|url|button|submit|reset)/
+          }
+        } ],
+        namingMethods: 'labelText'
+      }, {
+        matches: 'summary',
+        namingMethods: 'subtreeText'
+      }, {
+        matches: 'figure',
+        namingMethods: [ 'figureText', 'titleText' ]
+      }, {
+        matches: 'img',
+        namingMethods: 'altText'
+      }, {
+        matches: 'table',
+        namingMethods: [ 'tableCaptionText', 'tableSummaryText' ]
+      }, {
+        matches: [ 'hr', 'br' ],
+        namingMethods: [ 'titleText', 'singleSpace' ]
+      } ];
+      text.nativeTextAlternative = function nativeTextAlternative(virtualNode) {
+        var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+        var actualNode = virtualNode.actualNode;
+        if (actualNode.nodeType !== 1 || [ 'presentation', 'none' ].includes(aria.getRole(actualNode))) {
+          return '';
+        }
+        var textMethods = findTextMethods(virtualNode);
+        var accName = textMethods.reduce(function(accName, step) {
+          return accName || step(virtualNode, context);
+        }, '');
+        if (context.debug) {
+          axe.log(accName || '{empty-value}', actualNode, context);
+        }
+        return accName;
+      };
+      function findTextMethods(virtualNode) {
+        var nativeElementType = text.nativeElementType, nativeTextMethods = text.nativeTextMethods;
+        var nativeType = nativeElementType.find(function(_ref34) {
+          var matches = _ref34.matches;
+          return axe.commons.matches(virtualNode, matches);
+        });
+        var methods = nativeType ? [].concat(nativeType.namingMethods) : [];
+        return methods.map(function(methodName) {
+          return nativeTextMethods[methodName];
+        });
+      }
+      var defaultButtonValues = {
+        submit: 'Submit',
+        image: 'Submit',
+        reset: 'Reset',
+        button: ''
+      };
+      text.nativeTextMethods = {
+        valueText: function valueText(_ref35) {
+          var actualNode = _ref35.actualNode;
+          return actualNode.value || '';
+        },
+        buttonDefaultText: function buttonDefaultText(_ref36) {
+          var actualNode = _ref36.actualNode;
+          return defaultButtonValues[actualNode.type] || '';
+        },
+        tableCaptionText: descendantText.bind(null, 'caption'),
+        figureText: descendantText.bind(null, 'figcaption'),
+        fieldsetLegendText: descendantText.bind(null, 'legend'),
+        altText: attrText.bind(null, 'alt'),
+        tableSummaryText: attrText.bind(null, 'summary'),
+        titleText: function titleText(virtualNode, context) {
+          return text.titleText(virtualNode, context);
+        },
+        subtreeText: function subtreeText(virtualNode, context) {
+          return text.subtreeText(virtualNode, context);
+        },
+        labelText: function labelText(virtualNode, context) {
+          return text.labelText(virtualNode, context);
+        },
+        singleSpace: function singleSpace() {
+          return ' ';
+        }
+      };
+      function attrText(attr, _ref37) {
+        var actualNode = _ref37.actualNode;
+        return actualNode.getAttribute(attr) || '';
+      }
+      function descendantText(nodeName, _ref38, context) {
+        var actualNode = _ref38.actualNode;
+        nodeName = nodeName.toLowerCase();
+        var nodeNames = [ nodeName, actualNode.nodeName.toLowerCase() ].join(',');
+        var candidate = actualNode.querySelector(nodeNames);
+        if (!candidate || candidate.nodeName.toLowerCase() !== nodeName) {
+          return '';
+        }
+        return text.accessibleText(candidate, context);
+      }
       text.sanitize = function(str) {
         'use strict';
         return str.replace(/\r\n/g, '\n').replace(/\u00A0/g, ' ').replace(/[\s]{2,}/g, ' ').trim();
       };
-      text.visible = function(element, screenReader, noRecursing) {
-        'use strict';
-        var index, child, nodeValue, childNodes = element.children, length = childNodes.length, result = '';
-        for (index = 0; index < length; index++) {
-          child = childNodes[index];
-          if (child.actualNode.nodeType === 3) {
-            nodeValue = child.actualNode.nodeValue;
-            if (nodeValue && dom.isVisible(element.actualNode, screenReader)) {
-              result += nodeValue;
-            }
-          } else if (!noRecursing) {
-            result += text.visible(child, screenReader);
+      text.subtreeText = function subtreeText(virtualNode) {
+        var context = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
+        var alreadyProcessed = text.accessibleTextVirtual.alreadyProcessed;
+        context.startNode = context.startNode || virtualNode;
+        var strict = context.strict;
+        if (alreadyProcessed(virtualNode, context) || !aria.namedFromContents(virtualNode, {
+          strict: strict
+        })) {
+          return '';
+        }
+        return aria.getOwnedVirtual(virtualNode).reduce(function(contentText, child) {
+          return appendAccessibleText(contentText, child, context);
+        }, '');
+      };
+      var phrasingElements = [ 'A', 'EM', 'STRONG', 'SMALL', 'MARK', 'ABBR', 'DFN', 'I', 'B', 'S', 'U', 'CODE', 'VAR', 'SAMP', 'KBD', 'SUP', 'SUB', 'Q', 'CITE', 'SPAN', 'BDO', 'BDI', 'WBR', 'INS', 'DEL', 'MAP', 'AREA', 'NOSCRIPT', 'RUBY', 'BUTTON', 'LABEL', 'OUTPUT', 'DATALIST', 'KEYGEN', 'PROGRESS', 'COMMAND', 'CANVAS', 'TIME', 'METER', '#TEXT' ];
+      function appendAccessibleText(contentText, virtualNode, context) {
+        var nodeName = virtualNode.actualNode.nodeName.toUpperCase();
+        var contentTextAdd = text.accessibleTextVirtual(virtualNode, context);
+        if (!contentTextAdd) {
+          return contentText;
+        }
+        if (!phrasingElements.includes(nodeName)) {
+          if (contentTextAdd[0] !== ' ') {
+            contentTextAdd += ' ';
+          }
+          if (contentText && contentText[contentText.length - 1] !== ' ') {
+            contentTextAdd = ' ' + contentTextAdd;
           }
         }
+        return contentText + contentTextAdd;
+      }
+      var alwaysTitleElements = [ 'button', 'iframe', 'a[href]', {
+        nodeName: 'input',
+        properties: {
+          type: 'button'
+        }
+      } ];
+      text.titleText = function titleText(node) {
+        node = node.actualNode || node;
+        if (node.nodeType !== 1 || !node.hasAttribute('title')) {
+          return '';
+        }
+        if (!axe.commons.matches(node, alwaysTitleElements) && [ 'none', 'presentation' ].includes(aria.getRole(node))) {
+          return '';
+        }
+        return node.getAttribute('title');
+      };
+      text.hasUnicode = function hasUnicode(str, options) {
+        var emoji = options.emoji, nonBmp = options.nonBmp, punctuations = options.punctuations;
+        if (emoji) {
+          return axe.imports.emojiRegexText().test(str);
+        }
+        if (nonBmp) {
+          return getUnicodeNonBmpRegExp().test(str);
+        }
+        if (punctuations) {
+          return getPunctuationRegExp().test(str);
+        }
+        return false;
+      };
+      text.removeUnicode = function removeUnicode(str, options) {
+        var emoji = options.emoji, nonBmp = options.nonBmp, punctuations = options.punctuations;
+        if (emoji) {
+          str = str.replace(axe.imports.emojiRegexText(), '');
+        }
+        if (nonBmp) {
+          str = str.replace(getUnicodeNonBmpRegExp(), '');
+        }
+        if (punctuations) {
+          str = str.replace(getPunctuationRegExp(), '');
+        }
+        return str;
+      };
+      function getUnicodeNonBmpRegExp() {
+        return new RegExp('[' + 'ᴀ-ᵿ' + 'ᶀ-ᶿ' + '᷀-᷿' + '₠-⃏' + '⃐-⃿' + '℀-⅏' + '⅐-↏' + '←-⇿' + '∀-⋿' + '⌀-⏿' + '␀-␿' + '⑀-⑟' + '①-⓿' + '─-╿' + '▀-▟' + '■-◿' + '☀-⛿' + '✀-➿' + ']');
+      }
+      function getPunctuationRegExp() {
+        return /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]/g;
+      }
+      text.unsupported = {
+        accessibleNameFromFieldValue: [ 'combobox', 'listbox', 'progressbar' ]
+      };
+      text.visibleVirtual = function(element, screenReader, noRecursing) {
+        var result = element.children.map(function(child) {
+          if (child.actualNode.nodeType === 3) {
+            var nodeValue = child.actualNode.nodeValue;
+            if (nodeValue && dom.isVisible(element.actualNode, screenReader)) {
+              return nodeValue;
+            }
+          } else if (!noRecursing) {
+            return text.visibleVirtual(child, screenReader);
+          }
+        }).join('');
         return text.sanitize(result);
       };
-      axe.utils.toArray = function(thing) {
-        'use strict';
-        return Array.prototype.slice.call(thing);
-      };
-      axe.utils.tokenList = function(str) {
-        'use strict';
-        return str.trim().replace(/\s{2,}/g, ' ').split(' ');
-      };
-      var langs = [ 'aa', 'ab', 'ae', 'af', 'ak', 'am', 'an', 'ar', 'as', 'av', 'ay', 'az', 'ba', 'be', 'bg', 'bh', 'bi', 'bm', 'bn', 'bo', 'br', 'bs', 'ca', 'ce', 'ch', 'co', 'cr', 'cs', 'cu', 'cv', 'cy', 'da', 'de', 'dv', 'dz', 'ee', 'el', 'en', 'eo', 'es', 'et', 'eu', 'fa', 'ff', 'fi', 'fj', 'fo', 'fr', 'fy', 'ga', 'gd', 'gl', 'gn', 'gu', 'gv', 'ha', 'he', 'hi', 'ho', 'hr', 'ht', 'hu', 'hy', 'hz', 'ia', 'id', 'ie', 'ig', 'ii', 'ik', 'in', 'io', 'is', 'it', 'iu', 'iw', 'ja', 'ji', 'jv', 'jw', 'ka', 'kg', 'ki', 'kj', 'kk', 'kl', 'km', 'kn', 'ko', 'kr', 'ks', 'ku', 'kv', 'kw', 'ky', 'la', 'lb', 'lg', 'li', 'ln', 'lo', 'lt', 'lu', 'lv', 'mg', 'mh', 'mi', 'mk', 'ml', 'mn', 'mo', 'mr', 'ms', 'mt', 'my', 'na', 'nb', 'nd', 'ne', 'ng', 'nl', 'nn', 'no', 'nr', 'nv', 'ny', 'oc', 'oj', 'om', 'or', 'os', 'pa', 'pi', 'pl', 'ps', 'pt', 'qu', 'rm', 'rn', 'ro', 'ru', 'rw', 'sa', 'sc', 'sd', 'se', 'sg', 'sh', 'si', 'sk', 'sl', 'sm', 'sn', 'so', 'sq', 'sr', 'ss', 'st', 'su', 'sv', 'sw', 'ta', 'te', 'tg', 'th', 'ti', 'tk', 'tl', 'tn', 'to', 'tr', 'ts', 'tt', 'tw', 'ty', 'ug', 'uk', 'ur', 'uz', 've', 'vi', 'vo', 'wa', 'wo', 'xh', 'yi', 'yo', 'za', 'zh', 'zu', 'aaa', 'aab', 'aac', 'aad', 'aae', 'aaf', 'aag', 'aah', 'aai', 'aak', 'aal', 'aam', 'aan', 'aao', 'aap', 'aaq', 'aas', 'aat', 'aau', 'aav', 'aaw', 'aax', 'aaz', 'aba', 'abb', 'abc', 'abd', 'abe', 'abf', 'abg', 'abh', 'abi', 'abj', 'abl', 'abm', 'abn', 'abo', 'abp', 'abq', 'abr', 'abs', 'abt', 'abu', 'abv', 'abw', 'abx', 'aby', 'abz', 'aca', 'acb', 'acd', 'ace', 'acf', 'ach', 'aci', 'ack', 'acl', 'acm', 'acn', 'acp', 'acq', 'acr', 'acs', 'act', 'acu', 'acv', 'acw', 'acx', 'acy', 'acz', 'ada', 'adb', 'add', 'ade', 'adf', 'adg', 'adh', 'adi', 'adj', 'adl', 'adn', 'ado', 'adp', 'adq', 'adr', 'ads', 'adt', 'adu', 'adw', 'adx', 'ady', 'adz', 'aea', 'aeb', 'aec', 'aed', 'aee', 'aek', 'ael', 'aem', 'aen', 'aeq', 'aer', 'aes', 'aeu', 'aew', 'aey', 'aez', 'afa', 'afb', 'afd', 'afe', 'afg', 'afh', 'afi', 'afk', 'afn', 'afo', 'afp', 'afs', 'aft', 'afu', 'afz', 'aga', 'agb', 'agc', 'agd', 'age', 'agf', 'agg', 'agh', 'agi', 'agj', 'agk', 'agl', 'agm', 'agn', 'ago', 'agp', 'agq', 'agr', 'ags', 'agt', 'agu', 'agv', 'agw', 'agx', 'agy', 'agz', 'aha', 'ahb', 'ahg', 'ahh', 'ahi', 'ahk', 'ahl', 'ahm', 'ahn', 'aho', 'ahp', 'ahr', 'ahs', 'aht', 'aia', 'aib', 'aic', 'aid', 'aie', 'aif', 'aig', 'aih', 'aii', 'aij', 'aik', 'ail', 'aim', 'ain', 'aio', 'aip', 'aiq', 'air', 'ais', 'ait', 'aiw', 'aix', 'aiy', 'aja', 'ajg', 'aji', 'ajn', 'ajp', 'ajt', 'aju', 'ajw', 'ajz', 'akb', 'akc', 'akd', 'ake', 'akf', 'akg', 'akh', 'aki', 'akj', 'akk', 'akl', 'akm', 'ako', 'akp', 'akq', 'akr', 'aks', 'akt', 'aku', 'akv', 'akw', 'akx', 'aky', 'akz', 'ala', 'alc', 'ald', 'ale', 'alf', 'alg', 'alh', 'ali', 'alj', 'alk', 'all', 'alm', 'aln', 'alo', 'alp', 'alq', 'alr', 'als', 'alt', 'alu', 'alv', 'alw', 'alx', 'aly', 'alz', 'ama', 'amb', 'amc', 'ame', 'amf', 'amg', 'ami', 'amj', 'amk', 'aml', 'amm', 'amn', 'amo', 'amp', 'amq', 'amr', 'ams', 'amt', 'amu', 'amv', 'amw', 'amx', 'amy', 'amz', 'ana', 'anb', 'anc', 'and', 'ane', 'anf', 'ang', 'anh', 'ani', 'anj', 'ank', 'anl', 'anm', 'ann', 'ano', 'anp', 'anq', 'anr', 'ans', 'ant', 'anu', 'anv', 'anw', 'anx', 'any', 'anz', 'aoa', 'aob', 'aoc', 'aod', 'aoe', 'aof', 'aog', 'aoh', 'aoi', 'aoj', 'aok', 'aol', 'aom', 'aon', 'aor', 'aos', 'aot', 'aou', 'aox', 'aoz', 'apa', 'apb', 'apc', 'apd', 'ape', 'apf', 'apg', 'aph', 'api', 'apj', 'apk', 'apl', 'apm', 'apn', 'apo', 'app', 'apq', 'apr', 'aps', 'apt', 'apu', 'apv', 'apw', 'apx', 'apy', 'apz', 'aqa', 'aqc', 'aqd', 'aqg', 'aql', 'aqm', 'aqn', 'aqp', 'aqr', 'aqt', 'aqz', 'arb', 'arc', 'ard', 'are', 'arh', 'ari', 'arj', 'ark', 'arl', 'arn', 'aro', 'arp', 'arq', 'arr', 'ars', 'art', 'aru', 'arv', 'arw', 'arx', 'ary', 'arz', 'asa', 'asb', 'asc', 'asd', 'ase', 'asf', 'asg', 'ash', 'asi', 'asj', 'ask', 'asl', 'asn', 'aso', 'asp', 'asq', 'asr', 'ass', 'ast', 'asu', 'asv', 'asw', 'asx', 'asy', 'asz', 'ata', 'atb', 'atc', 'atd', 'ate', 'atg', 'ath', 'ati', 'atj', 'atk', 'atl', 'atm', 'atn', 'ato', 'atp', 'atq', 'atr', 'ats', 'att', 'atu', 'atv', 'atw', 'atx', 'aty', 'atz', 'aua', 'aub', 'auc', 'aud', 'aue', 'auf', 'aug', 'auh', 'aui', 'auj', 'auk', 'aul', 'aum', 'aun', 'auo', 'aup', 'auq', 'aur', 'aus', 'aut', 'auu', 'auw', 'aux', 'auy', 'auz', 'avb', 'avd', 'avi', 'avk', 'avl', 'avm', 'avn', 'avo', 'avs', 'avt', 'avu', 'avv', 'awa', 'awb', 'awc', 'awd', 'awe', 'awg', 'awh', 'awi', 'awk', 'awm', 'awn', 'awo', 'awr', 'aws', 'awt', 'awu', 'awv', 'aww', 'awx', 'awy', 'axb', 'axe', 'axg', 'axk', 'axl', 'axm', 'axx', 'aya', 'ayb', 'ayc', 'ayd', 'aye', 'ayg', 'ayh', 'ayi', 'ayk', 'ayl', 'ayn', 'ayo', 'ayp', 'ayq', 'ayr', 'ays', 'ayt', 'ayu', 'ayx', 'ayy', 'ayz', 'aza', 'azb', 'azc', 'azd', 'azg', 'azj', 'azm', 'azn', 'azo', 'azt', 'azz', 'baa', 'bab', 'bac', 'bad', 'bae', 'baf', 'bag', 'bah', 'bai', 'baj', 'bal', 'ban', 'bao', 'bap', 'bar', 'bas', 'bat', 'bau', 'bav', 'baw', 'bax', 'bay', 'baz', 'bba', 'bbb', 'bbc', 'bbd', 'bbe', 'bbf', 'bbg', 'bbh', 'bbi', 'bbj', 'bbk', 'bbl', 'bbm', 'bbn', 'bbo', 'bbp', 'bbq', 'bbr', 'bbs', 'bbt', 'bbu', 'bbv', 'bbw', 'bbx', 'bby', 'bbz', 'bca', 'bcb', 'bcc', 'bcd', 'bce', 'bcf', 'bcg', 'bch', 'bci', 'bcj', 'bck', 'bcl', 'bcm', 'bcn', 'bco', 'bcp', 'bcq', 'bcr', 'bcs', 'bct', 'bcu', 'bcv', 'bcw', 'bcy', 'bcz', 'bda', 'bdb', 'bdc', 'bdd', 'bde', 'bdf', 'bdg', 'bdh', 'bdi', 'bdj', 'bdk', 'bdl', 'bdm', 'bdn', 'bdo', 'bdp', 'bdq', 'bdr', 'bds', 'bdt', 'bdu', 'bdv', 'bdw', 'bdx', 'bdy', 'bdz', 'bea', 'beb', 'bec', 'bed', 'bee', 'bef', 'beg', 'beh', 'bei', 'bej', 'bek', 'bem', 'beo', 'bep', 'beq', 'ber', 'bes', 'bet', 'beu', 'bev', 'bew', 'bex', 'bey', 'bez', 'bfa', 'bfb', 'bfc', 'bfd', 'bfe', 'bff', 'bfg', 'bfh', 'bfi', 'bfj', 'bfk', 'bfl', 'bfm', 'bfn', 'bfo', 'bfp', 'bfq', 'bfr', 'bfs', 'bft', 'bfu', 'bfw', 'bfx', 'bfy', 'bfz', 'bga', 'bgb', 'bgc', 'bgd', 'bge', 'bgf', 'bgg', 'bgi', 'bgj', 'bgk', 'bgl', 'bgm', 'bgn', 'bgo', 'bgp', 'bgq', 'bgr', 'bgs', 'bgt', 'bgu', 'bgv', 'bgw', 'bgx', 'bgy', 'bgz', 'bha', 'bhb', 'bhc', 'bhd', 'bhe', 'bhf', 'bhg', 'bhh', 'bhi', 'bhj', 'bhk', 'bhl', 'bhm', 'bhn', 'bho', 'bhp', 'bhq', 'bhr', 'bhs', 'bht', 'bhu', 'bhv', 'bhw', 'bhx', 'bhy', 'bhz', 'bia', 'bib', 'bic', 'bid', 'bie', 'bif', 'big', 'bij', 'bik', 'bil', 'bim', 'bin', 'bio', 'bip', 'biq', 'bir', 'bit', 'biu', 'biv', 'biw', 'bix', 'biy', 'biz', 'bja', 'bjb', 'bjc', 'bjd', 'bje', 'bjf', 'bjg', 'bjh', 'bji', 'bjj', 'bjk', 'bjl', 'bjm', 'bjn', 'bjo', 'bjp', 'bjq', 'bjr', 'bjs', 'bjt', 'bju', 'bjv', 'bjw', 'bjx', 'bjy', 'bjz', 'bka', 'bkb', 'bkc', 'bkd', 'bkf', 'bkg', 'bkh', 'bki', 'bkj', 'bkk', 'bkl', 'bkm', 'bkn', 'bko', 'bkp', 'bkq', 'bkr', 'bks', 'bkt', 'bku', 'bkv', 'bkw', 'bkx', 'bky', 'bkz', 'bla', 'blb', 'blc', 'bld', 'ble', 'blf', 'blg', 'blh', 'bli', 'blj', 'blk', 'bll', 'blm', 'bln', 'blo', 'blp', 'blq', 'blr', 'bls', 'blt', 'blv', 'blw', 'blx', 'bly', 'blz', 'bma', 'bmb', 'bmc', 'bmd', 'bme', 'bmf', 'bmg', 'bmh', 'bmi', 'bmj', 'bmk', 'bml', 'bmm', 'bmn', 'bmo', 'bmp', 'bmq', 'bmr', 'bms', 'bmt', 'bmu', 'bmv', 'bmw', 'bmx', 'bmy', 'bmz', 'bna', 'bnb', 'bnc', 'bnd', 'bne', 'bnf', 'bng', 'bni', 'bnj', 'bnk', 'bnl', 'bnm', 'bnn', 'bno', 'bnp', 'bnq', 'bnr', 'bns', 'bnt', 'bnu', 'bnv', 'bnw', 'bnx', 'bny', 'bnz', 'boa', 'bob', 'boe', 'bof', 'bog', 'boh', 'boi', 'boj', 'bok', 'bol', 'bom', 'bon', 'boo', 'bop', 'boq', 'bor', 'bot', 'bou', 'bov', 'bow', 'box', 'boy', 'boz', 'bpa', 'bpb', 'bpd', 'bpg', 'bph', 'bpi', 'bpj', 'bpk', 'bpl', 'bpm', 'bpn', 'bpo', 'bpp', 'bpq', 'bpr', 'bps', 'bpt', 'bpu', 'bpv', 'bpw', 'bpx', 'bpy', 'bpz', 'bqa', 'bqb', 'bqc', 'bqd', 'bqf', 'bqg', 'bqh', 'bqi', 'bqj', 'bqk', 'bql', 'bqm', 'bqn', 'bqo', 'bqp', 'bqq', 'bqr', 'bqs', 'bqt', 'bqu', 'bqv', 'bqw', 'bqx', 'bqy', 'bqz', 'bra', 'brb', 'brc', 'brd', 'brf', 'brg', 'brh', 'bri', 'brj', 'brk', 'brl', 'brm', 'brn', 'bro', 'brp', 'brq', 'brr', 'brs', 'brt', 'bru', 'brv', 'brw', 'brx', 'bry', 'brz', 'bsa', 'bsb', 'bsc', 'bse', 'bsf', 'bsg', 'bsh', 'bsi', 'bsj', 'bsk', 'bsl', 'bsm', 'bsn', 'bso', 'bsp', 'bsq', 'bsr', 'bss', 'bst', 'bsu', 'bsv', 'bsw', 'bsx', 'bsy', 'bta', 'btb', 'btc', 'btd', 'bte', 'btf', 'btg', 'bth', 'bti', 'btj', 'btk', 'btl', 'btm', 'btn', 'bto', 'btp', 'btq', 'btr', 'bts', 'btt', 'btu', 'btv', 'btw', 'btx', 'bty', 'btz', 'bua', 'bub', 'buc', 'bud', 'bue', 'buf', 'bug', 'buh', 'bui', 'buj', 'buk', 'bum', 'bun', 'buo', 'bup', 'buq', 'bus', 'but', 'buu', 'buv', 'buw', 'bux', 'buy', 'buz', 'bva', 'bvb', 'bvc', 'bvd', 'bve', 'bvf', 'bvg', 'bvh', 'bvi', 'bvj', 'bvk', 'bvl', 'bvm', 'bvn', 'bvo', 'bvp', 'bvq', 'bvr', 'bvt', 'bvu', 'bvv', 'bvw', 'bvx', 'bvy', 'bvz', 'bwa', 'bwb', 'bwc', 'bwd', 'bwe', 'bwf', 'bwg', 'bwh', 'bwi', 'bwj', 'bwk', 'bwl', 'bwm', 'bwn', 'bwo', 'bwp', 'bwq', 'bwr', 'bws', 'bwt', 'bwu', 'bww', 'bwx', 'bwy', 'bwz', 'bxa', 'bxb', 'bxc', 'bxd', 'bxe', 'bxf', 'bxg', 'bxh', 'bxi', 'bxj', 'bxk', 'bxl', 'bxm', 'bxn', 'bxo', 'bxp', 'bxq', 'bxr', 'bxs', 'bxu', 'bxv', 'bxw', 'bxx', 'bxz', 'bya', 'byb', 'byc', 'byd', 'bye', 'byf', 'byg', 'byh', 'byi', 'byj', 'byk', 'byl', 'bym', 'byn', 'byo', 'byp', 'byq', 'byr', 'bys', 'byt', 'byv', 'byw', 'byx', 'byy', 'byz', 'bza', 'bzb', 'bzc', 'bzd', 'bze', 'bzf', 'bzg', 'bzh', 'bzi', 'bzj', 'bzk', 'bzl', 'bzm', 'bzn', 'bzo', 'bzp', 'bzq', 'bzr', 'bzs', 'bzt', 'bzu', 'bzv', 'bzw', 'bzx', 'bzy', 'bzz', 'caa', 'cab', 'cac', 'cad', 'cae', 'caf', 'cag', 'cah', 'cai', 'caj', 'cak', 'cal', 'cam', 'can', 'cao', 'cap', 'caq', 'car', 'cas', 'cau', 'cav', 'caw', 'cax', 'cay', 'caz', 'cba', 'cbb', 'cbc', 'cbd', 'cbe', 'cbg', 'cbh', 'cbi', 'cbj', 'cbk', 'cbl', 'cbn', 'cbo', 'cbq', 'cbr', 'cbs', 'cbt', 'cbu', 'cbv', 'cbw', 'cby', 'cca', 'ccc', 'ccd', 'cce', 'ccg', 'cch', 'ccj', 'ccl', 'ccm', 'ccn', 'cco', 'ccp', 'ccq', 'ccr', 'ccs', 'cda', 'cdc', 'cdd', 'cde', 'cdf', 'cdg', 'cdh', 'cdi', 'cdj', 'cdm', 'cdn', 'cdo', 'cdr', 'cds', 'cdy', 'cdz', 'cea', 'ceb', 'ceg', 'cek', 'cel', 'cen', 'cet', 'cfa', 'cfd', 'cfg', 'cfm', 'cga', 'cgc', 'cgg', 'cgk', 'chb', 'chc', 'chd', 'chf', 'chg', 'chh', 'chj', 'chk', 'chl', 'chm', 'chn', 'cho', 'chp', 'chq', 'chr', 'cht', 'chw', 'chx', 'chy', 'chz', 'cia', 'cib', 'cic', 'cid', 'cie', 'cih', 'cik', 'cim', 'cin', 'cip', 'cir', 'ciw', 'ciy', 'cja', 'cje', 'cjh', 'cji', 'cjk', 'cjm', 'cjn', 'cjo', 'cjp', 'cjr', 'cjs', 'cjv', 'cjy', 'cka', 'ckb', 'ckh', 'ckl', 'ckn', 'cko', 'ckq', 'ckr', 'cks', 'ckt', 'cku', 'ckv', 'ckx', 'cky', 'ckz', 'cla', 'clc', 'cld', 'cle', 'clh', 'cli', 'clj', 'clk', 'cll', 'clm', 'clo', 'clt', 'clu', 'clw', 'cly', 'cma', 'cmc', 'cme', 'cmg', 'cmi', 'cmk', 'cml', 'cmm', 'cmn', 'cmo', 'cmr', 'cms', 'cmt', 'cna', 'cnb', 'cnc', 'cng', 'cnh', 'cni', 'cnk', 'cnl', 'cno', 'cns', 'cnt', 'cnu', 'cnw', 'cnx', 'coa', 'cob', 'coc', 'cod', 'coe', 'cof', 'cog', 'coh', 'coj', 'cok', 'col', 'com', 'con', 'coo', 'cop', 'coq', 'cot', 'cou', 'cov', 'cow', 'cox', 'coy', 'coz', 'cpa', 'cpb', 'cpc', 'cpe', 'cpf', 'cpg', 'cpi', 'cpn', 'cpo', 'cpp', 'cps', 'cpu', 'cpx', 'cpy', 'cqd', 'cqu', 'cra', 'crb', 'crc', 'crd', 'crf', 'crg', 'crh', 'cri', 'crj', 'crk', 'crl', 'crm', 'crn', 'cro', 'crp', 'crq', 'crr', 'crs', 'crt', 'crv', 'crw', 'crx', 'cry', 'crz', 'csa', 'csb', 'csc', 'csd', 'cse', 'csf', 'csg', 'csh', 'csi', 'csj', 'csk', 'csl', 'csm', 'csn', 'cso', 'csq', 'csr', 'css', 'cst', 'csu', 'csv', 'csw', 'csy', 'csz', 'cta', 'ctc', 'ctd', 'cte', 'ctg', 'cth', 'ctl', 'ctm', 'ctn', 'cto', 'ctp', 'cts', 'ctt', 'ctu', 'ctz', 'cua', 'cub', 'cuc', 'cug', 'cuh', 'cui', 'cuj', 'cuk', 'cul', 'cum', 'cuo', 'cup', 'cuq', 'cur', 'cus', 'cut', 'cuu', 'cuv', 'cuw', 'cux', 'cvg', 'cvn', 'cwa', 'cwb', 'cwd', 'cwe', 'cwg', 'cwt', 'cya', 'cyb', 'cyo', 'czh', 'czk', 'czn', 'czo', 'czt', 'daa', 'dac', 'dad', 'dae', 'daf', 'dag', 'dah', 'dai', 'daj', 'dak', 'dal', 'dam', 'dao', 'dap', 'daq', 'dar', 'das', 'dau', 'dav', 'daw', 'dax', 'day', 'daz', 'dba', 'dbb', 'dbd', 'dbe', 'dbf', 'dbg', 'dbi', 'dbj', 'dbl', 'dbm', 'dbn', 'dbo', 'dbp', 'dbq', 'dbr', 'dbt', 'dbu', 'dbv', 'dbw', 'dby', 'dcc', 'dcr', 'dda', 'ddd', 'dde', 'ddg', 'ddi', 'ddj', 'ddn', 'ddo', 'ddr', 'dds', 'ddw', 'dec', 'ded', 'dee', 'def', 'deg', 'deh', 'dei', 'dek', 'del', 'dem', 'den', 'dep', 'deq', 'der', 'des', 'dev', 'dez', 'dga', 'dgb', 'dgc', 'dgd', 'dge', 'dgg', 'dgh', 'dgi', 'dgk', 'dgl', 'dgn', 'dgo', 'dgr', 'dgs', 'dgt', 'dgu', 'dgw', 'dgx', 'dgz', 'dha', 'dhd', 'dhg', 'dhi', 'dhl', 'dhm', 'dhn', 'dho', 'dhr', 'dhs', 'dhu', 'dhv', 'dhw', 'dhx', 'dia', 'dib', 'dic', 'did', 'dif', 'dig', 'dih', 'dii', 'dij', 'dik', 'dil', 'dim', 'din', 'dio', 'dip', 'diq', 'dir', 'dis', 'dit', 'diu', 'diw', 'dix', 'diy', 'diz', 'dja', 'djb', 'djc', 'djd', 'dje', 'djf', 'dji', 'djj', 'djk', 'djl', 'djm', 'djn', 'djo', 'djr', 'dju', 'djw', 'dka', 'dkk', 'dkl', 'dkr', 'dks', 'dkx', 'dlg', 'dlk', 'dlm', 'dln', 'dma', 'dmb', 'dmc', 'dmd', 'dme', 'dmg', 'dmk', 'dml', 'dmm', 'dmn', 'dmo', 'dmr', 'dms', 'dmu', 'dmv', 'dmw', 'dmx', 'dmy', 'dna', 'dnd', 'dne', 'dng', 'dni', 'dnj', 'dnk', 'dnn', 'dnr', 'dnt', 'dnu', 'dnv', 'dnw', 'dny', 'doa', 'dob', 'doc', 'doe', 'dof', 'doh', 'doi', 'dok', 'dol', 'don', 'doo', 'dop', 'doq', 'dor', 'dos', 'dot', 'dov', 'dow', 'dox', 'doy', 'doz', 'dpp', 'dra', 'drb', 'drc', 'drd', 'dre', 'drg', 'drh', 'dri', 'drl', 'drn', 'dro', 'drq', 'drr', 'drs', 'drt', 'dru', 'drw', 'dry', 'dsb', 'dse', 'dsh', 'dsi', 'dsl', 'dsn', 'dso', 'dsq', 'dta', 'dtb', 'dtd', 'dth', 'dti', 'dtk', 'dtm', 'dtn', 'dto', 'dtp', 'dtr', 'dts', 'dtt', 'dtu', 'dty', 'dua', 'dub', 'duc', 'dud', 'due', 'duf', 'dug', 'duh', 'dui', 'duj', 'duk', 'dul', 'dum', 'dun', 'duo', 'dup', 'duq', 'dur', 'dus', 'duu', 'duv', 'duw', 'dux', 'duy', 'duz', 'dva', 'dwa', 'dwl', 'dwr', 'dws', 'dwu', 'dww', 'dwy', 'dya', 'dyb', 'dyd', 'dyg', 'dyi', 'dym', 'dyn', 'dyo', 'dyu', 'dyy', 'dza', 'dzd', 'dze', 'dzg', 'dzl', 'dzn', 'eaa', 'ebg', 'ebk', 'ebo', 'ebr', 'ebu', 'ecr', 'ecs', 'ecy', 'eee', 'efa', 'efe', 'efi', 'ega', 'egl', 'ego', 'egx', 'egy', 'ehu', 'eip', 'eit', 'eiv', 'eja', 'eka', 'ekc', 'eke', 'ekg', 'eki', 'ekk', 'ekl', 'ekm', 'eko', 'ekp', 'ekr', 'eky', 'ele', 'elh', 'eli', 'elk', 'elm', 'elo', 'elp', 'elu', 'elx', 'ema', 'emb', 'eme', 'emg', 'emi', 'emk', 'emm', 'emn', 'emo', 'emp', 'ems', 'emu', 'emw', 'emx', 'emy', 'ena', 'enb', 'enc', 'end', 'enf', 'enh', 'enl', 'enm', 'enn', 'eno', 'enq', 'enr', 'enu', 'env', 'enw', 'enx', 'eot', 'epi', 'era', 'erg', 'erh', 'eri', 'erk', 'ero', 'err', 'ers', 'ert', 'erw', 'ese', 'esg', 'esh', 'esi', 'esk', 'esl', 'esm', 'esn', 'eso', 'esq', 'ess', 'esu', 'esx', 'esy', 'etb', 'etc', 'eth', 'etn', 'eto', 'etr', 'ets', 'ett', 'etu', 'etx', 'etz', 'euq', 'eve', 'evh', 'evn', 'ewo', 'ext', 'eya', 'eyo', 'eza', 'eze', 'faa', 'fab', 'fad', 'faf', 'fag', 'fah', 'fai', 'faj', 'fak', 'fal', 'fam', 'fan', 'fap', 'far', 'fat', 'fau', 'fax', 'fay', 'faz', 'fbl', 'fcs', 'fer', 'ffi', 'ffm', 'fgr', 'fia', 'fie', 'fil', 'fip', 'fir', 'fit', 'fiu', 'fiw', 'fkk', 'fkv', 'fla', 'flh', 'fli', 'fll', 'fln', 'flr', 'fly', 'fmp', 'fmu', 'fnb', 'fng', 'fni', 'fod', 'foi', 'fom', 'fon', 'for', 'fos', 'fox', 'fpe', 'fqs', 'frc', 'frd', 'frk', 'frm', 'fro', 'frp', 'frq', 'frr', 'frs', 'frt', 'fse', 'fsl', 'fss', 'fub', 'fuc', 'fud', 'fue', 'fuf', 'fuh', 'fui', 'fuj', 'fum', 'fun', 'fuq', 'fur', 'fut', 'fuu', 'fuv', 'fuy', 'fvr', 'fwa', 'fwe', 'gaa', 'gab', 'gac', 'gad', 'gae', 'gaf', 'gag', 'gah', 'gai', 'gaj', 'gak', 'gal', 'gam', 'gan', 'gao', 'gap', 'gaq', 'gar', 'gas', 'gat', 'gau', 'gav', 'gaw', 'gax', 'gay', 'gaz', 'gba', 'gbb', 'gbc', 'gbd', 'gbe', 'gbf', 'gbg', 'gbh', 'gbi', 'gbj', 'gbk', 'gbl', 'gbm', 'gbn', 'gbo', 'gbp', 'gbq', 'gbr', 'gbs', 'gbu', 'gbv', 'gbw', 'gbx', 'gby', 'gbz', 'gcc', 'gcd', 'gce', 'gcf', 'gcl', 'gcn', 'gcr', 'gct', 'gda', 'gdb', 'gdc', 'gdd', 'gde', 'gdf', 'gdg', 'gdh', 'gdi', 'gdj', 'gdk', 'gdl', 'gdm', 'gdn', 'gdo', 'gdq', 'gdr', 'gds', 'gdt', 'gdu', 'gdx', 'gea', 'geb', 'gec', 'ged', 'geg', 'geh', 'gei', 'gej', 'gek', 'gel', 'gem', 'geq', 'ges', 'gev', 'gew', 'gex', 'gey', 'gez', 'gfk', 'gft', 'gfx', 'gga', 'ggb', 'ggd', 'gge', 'ggg', 'ggk', 'ggl', 'ggn', 'ggo', 'ggr', 'ggt', 'ggu', 'ggw', 'gha', 'ghc', 'ghe', 'ghh', 'ghk', 'ghl', 'ghn', 'gho', 'ghr', 'ghs', 'ght', 'gia', 'gib', 'gic', 'gid', 'gie', 'gig', 'gih', 'gil', 'gim', 'gin', 'gio', 'gip', 'giq', 'gir', 'gis', 'git', 'giu', 'giw', 'gix', 'giy', 'giz', 'gji', 'gjk', 'gjm', 'gjn', 'gjr', 'gju', 'gka', 'gke', 'gkn', 'gko', 'gkp', 'gku', 'glc', 'gld', 'glh', 'gli', 'glj', 'glk', 'gll', 'glo', 'glr', 'glu', 'glw', 'gly', 'gma', 'gmb', 'gmd', 'gme', 'gmg', 'gmh', 'gml', 'gmm', 'gmn', 'gmq', 'gmu', 'gmv', 'gmw', 'gmx', 'gmy', 'gmz', 'gna', 'gnb', 'gnc', 'gnd', 'gne', 'gng', 'gnh', 'gni', 'gnk', 'gnl', 'gnm', 'gnn', 'gno', 'gnq', 'gnr', 'gnt', 'gnu', 'gnw', 'gnz', 'goa', 'gob', 'goc', 'god', 'goe', 'gof', 'gog', 'goh', 'goi', 'goj', 'gok', 'gol', 'gom', 'gon', 'goo', 'gop', 'goq', 'gor', 'gos', 'got', 'gou', 'gow', 'gox', 'goy', 'goz', 'gpa', 'gpe', 'gpn', 'gqa', 'gqi', 'gqn', 'gqr', 'gqu', 'gra', 'grb', 'grc', 'grd', 'grg', 'grh', 'gri', 'grj', 'grk', 'grm', 'gro', 'grq', 'grr', 'grs', 'grt', 'gru', 'grv', 'grw', 'grx', 'gry', 'grz', 'gse', 'gsg', 'gsl', 'gsm', 'gsn', 'gso', 'gsp', 'gss', 'gsw', 'gta', 'gti', 'gtu', 'gua', 'gub', 'guc', 'gud', 'gue', 'guf', 'gug', 'guh', 'gui', 'guk', 'gul', 'gum', 'gun', 'guo', 'gup', 'guq', 'gur', 'gus', 'gut', 'guu', 'guv', 'guw', 'gux', 'guz', 'gva', 'gvc', 'gve', 'gvf', 'gvj', 'gvl', 'gvm', 'gvn', 'gvo', 'gvp', 'gvr', 'gvs', 'gvy', 'gwa', 'gwb', 'gwc', 'gwd', 'gwe', 'gwf', 'gwg', 'gwi', 'gwj', 'gwm', 'gwn', 'gwr', 'gwt', 'gwu', 'gww', 'gwx', 'gxx', 'gya', 'gyb', 'gyd', 'gye', 'gyf', 'gyg', 'gyi', 'gyl', 'gym', 'gyn', 'gyr', 'gyy', 'gza', 'gzi', 'gzn', 'haa', 'hab', 'hac', 'had', 'hae', 'haf', 'hag', 'hah', 'hai', 'haj', 'hak', 'hal', 'ham', 'han', 'hao', 'hap', 'haq', 'har', 'has', 'hav', 'haw', 'hax', 'hay', 'haz', 'hba', 'hbb', 'hbn', 'hbo', 'hbu', 'hca', 'hch', 'hdn', 'hds', 'hdy', 'hea', 'hed', 'heg', 'heh', 'hei', 'hem', 'hgm', 'hgw', 'hhi', 'hhr', 'hhy', 'hia', 'hib', 'hid', 'hif', 'hig', 'hih', 'hii', 'hij', 'hik', 'hil', 'him', 'hio', 'hir', 'hit', 'hiw', 'hix', 'hji', 'hka', 'hke', 'hkk', 'hks', 'hla', 'hlb', 'hld', 'hle', 'hlt', 'hlu', 'hma', 'hmb', 'hmc', 'hmd', 'hme', 'hmf', 'hmg', 'hmh', 'hmi', 'hmj', 'hmk', 'hml', 'hmm', 'hmn', 'hmp', 'hmq', 'hmr', 'hms', 'hmt', 'hmu', 'hmv', 'hmw', 'hmx', 'hmy', 'hmz', 'hna', 'hnd', 'hne', 'hnh', 'hni', 'hnj', 'hnn', 'hno', 'hns', 'hnu', 'hoa', 'hob', 'hoc', 'hod', 'hoe', 'hoh', 'hoi', 'hoj', 'hok', 'hol', 'hom', 'hoo', 'hop', 'hor', 'hos', 'hot', 'hov', 'how', 'hoy', 'hoz', 'hpo', 'hps', 'hra', 'hrc', 'hre', 'hrk', 'hrm', 'hro', 'hrp', 'hrr', 'hrt', 'hru', 'hrw', 'hrx', 'hrz', 'hsb', 'hsh', 'hsl', 'hsn', 'hss', 'hti', 'hto', 'hts', 'htu', 'htx', 'hub', 'huc', 'hud', 'hue', 'huf', 'hug', 'huh', 'hui', 'huj', 'huk', 'hul', 'hum', 'huo', 'hup', 'huq', 'hur', 'hus', 'hut', 'huu', 'huv', 'huw', 'hux', 'huy', 'huz', 'hvc', 'hve', 'hvk', 'hvn', 'hvv', 'hwa', 'hwc', 'hwo', 'hya', 'hyx', 'iai', 'ian', 'iap', 'iar', 'iba', 'ibb', 'ibd', 'ibe', 'ibg', 'ibh', 'ibi', 'ibl', 'ibm', 'ibn', 'ibr', 'ibu', 'iby', 'ica', 'ich', 'icl', 'icr', 'ida', 'idb', 'idc', 'idd', 'ide', 'idi', 'idr', 'ids', 'idt', 'idu', 'ifa', 'ifb', 'ife', 'iff', 'ifk', 'ifm', 'ifu', 'ify', 'igb', 'ige', 'igg', 'igl', 'igm', 'ign', 'igo', 'igs', 'igw', 'ihb', 'ihi', 'ihp', 'ihw', 'iin', 'iir', 'ijc', 'ije', 'ijj', 'ijn', 'ijo', 'ijs', 'ike', 'iki', 'ikk', 'ikl', 'iko', 'ikp', 'ikr', 'iks', 'ikt', 'ikv', 'ikw', 'ikx', 'ikz', 'ila', 'ilb', 'ilg', 'ili', 'ilk', 'ill', 'ilm', 'ilo', 'ilp', 'ils', 'ilu', 'ilv', 'ilw', 'ima', 'ime', 'imi', 'iml', 'imn', 'imo', 'imr', 'ims', 'imy', 'inb', 'inc', 'ine', 'ing', 'inh', 'inj', 'inl', 'inm', 'inn', 'ino', 'inp', 'ins', 'int', 'inz', 'ior', 'iou', 'iow', 'ipi', 'ipo', 'iqu', 'iqw', 'ira', 'ire', 'irh', 'iri', 'irk', 'irn', 'iro', 'irr', 'iru', 'irx', 'iry', 'isa', 'isc', 'isd', 'ise', 'isg', 'ish', 'isi', 'isk', 'ism', 'isn', 'iso', 'isr', 'ist', 'isu', 'itb', 'itc', 'itd', 'ite', 'iti', 'itk', 'itl', 'itm', 'ito', 'itr', 'its', 'itt', 'itv', 'itw', 'itx', 'ity', 'itz', 'ium', 'ivb', 'ivv', 'iwk', 'iwm', 'iwo', 'iws', 'ixc', 'ixl', 'iya', 'iyo', 'iyx', 'izh', 'izi', 'izr', 'izz', 'jaa', 'jab', 'jac', 'jad', 'jae', 'jaf', 'jah', 'jaj', 'jak', 'jal', 'jam', 'jan', 'jao', 'jaq', 'jar', 'jas', 'jat', 'jau', 'jax', 'jay', 'jaz', 'jbe', 'jbi', 'jbj', 'jbk', 'jbn', 'jbo', 'jbr', 'jbt', 'jbu', 'jbw', 'jcs', 'jct', 'jda', 'jdg', 'jdt', 'jeb', 'jee', 'jeg', 'jeh', 'jei', 'jek', 'jel', 'jen', 'jer', 'jet', 'jeu', 'jgb', 'jge', 'jgk', 'jgo', 'jhi', 'jhs', 'jia', 'jib', 'jic', 'jid', 'jie', 'jig', 'jih', 'jii', 'jil', 'jim', 'jio', 'jiq', 'jit', 'jiu', 'jiv', 'jiy', 'jje', 'jjr', 'jka', 'jkm', 'jko', 'jkp', 'jkr', 'jku', 'jle', 'jls', 'jma', 'jmb', 'jmc', 'jmd', 'jmi', 'jml', 'jmn', 'jmr', 'jms', 'jmw', 'jmx', 'jna', 'jnd', 'jng', 'jni', 'jnj', 'jnl', 'jns', 'job', 'jod', 'jog', 'jor', 'jos', 'jow', 'jpa', 'jpr', 'jpx', 'jqr', 'jra', 'jrb', 'jrr', 'jrt', 'jru', 'jsl', 'jua', 'jub', 'juc', 'jud', 'juh', 'jui', 'juk', 'jul', 'jum', 'jun', 'juo', 'jup', 'jur', 'jus', 'jut', 'juu', 'juw', 'juy', 'jvd', 'jvn', 'jwi', 'jya', 'jye', 'jyy', 'kaa', 'kab', 'kac', 'kad', 'kae', 'kaf', 'kag', 'kah', 'kai', 'kaj', 'kak', 'kam', 'kao', 'kap', 'kaq', 'kar', 'kav', 'kaw', 'kax', 'kay', 'kba', 'kbb', 'kbc', 'kbd', 'kbe', 'kbf', 'kbg', 'kbh', 'kbi', 'kbj', 'kbk', 'kbl', 'kbm', 'kbn', 'kbo', 'kbp', 'kbq', 'kbr', 'kbs', 'kbt', 'kbu', 'kbv', 'kbw', 'kbx', 'kby', 'kbz', 'kca', 'kcb', 'kcc', 'kcd', 'kce', 'kcf', 'kcg', 'kch', 'kci', 'kcj', 'kck', 'kcl', 'kcm', 'kcn', 'kco', 'kcp', 'kcq', 'kcr', 'kcs', 'kct', 'kcu', 'kcv', 'kcw', 'kcx', 'kcy', 'kcz', 'kda', 'kdc', 'kdd', 'kde', 'kdf', 'kdg', 'kdh', 'kdi', 'kdj', 'kdk', 'kdl', 'kdm', 'kdn', 'kdo', 'kdp', 'kdq', 'kdr', 'kdt', 'kdu', 'kdv', 'kdw', 'kdx', 'kdy', 'kdz', 'kea', 'keb', 'kec', 'ked', 'kee', 'kef', 'keg', 'keh', 'kei', 'kej', 'kek', 'kel', 'kem', 'ken', 'keo', 'kep', 'keq', 'ker', 'kes', 'ket', 'keu', 'kev', 'kew', 'kex', 'key', 'kez', 'kfa', 'kfb', 'kfc', 'kfd', 'kfe', 'kff', 'kfg', 'kfh', 'kfi', 'kfj', 'kfk', 'kfl', 'kfm', 'kfn', 'kfo', 'kfp', 'kfq', 'kfr', 'kfs', 'kft', 'kfu', 'kfv', 'kfw', 'kfx', 'kfy', 'kfz', 'kga', 'kgb', 'kgc', 'kgd', 'kge', 'kgf', 'kgg', 'kgh', 'kgi', 'kgj', 'kgk', 'kgl', 'kgm', 'kgn', 'kgo', 'kgp', 'kgq', 'kgr', 'kgs', 'kgt', 'kgu', 'kgv', 'kgw', 'kgx', 'kgy', 'kha', 'khb', 'khc', 'khd', 'khe', 'khf', 'khg', 'khh', 'khi', 'khj', 'khk', 'khl', 'khn', 'kho', 'khp', 'khq', 'khr', 'khs', 'kht', 'khu', 'khv', 'khw', 'khx', 'khy', 'khz', 'kia', 'kib', 'kic', 'kid', 'kie', 'kif', 'kig', 'kih', 'kii', 'kij', 'kil', 'kim', 'kio', 'kip', 'kiq', 'kis', 'kit', 'kiu', 'kiv', 'kiw', 'kix', 'kiy', 'kiz', 'kja', 'kjb', 'kjc', 'kjd', 'kje', 'kjf', 'kjg', 'kjh', 'kji', 'kjj', 'kjk', 'kjl', 'kjm', 'kjn', 'kjo', 'kjp', 'kjq', 'kjr', 'kjs', 'kjt', 'kju', 'kjv', 'kjx', 'kjy', 'kjz', 'kka', 'kkb', 'kkc', 'kkd', 'kke', 'kkf', 'kkg', 'kkh', 'kki', 'kkj', 'kkk', 'kkl', 'kkm', 'kkn', 'kko', 'kkp', 'kkq', 'kkr', 'kks', 'kkt', 'kku', 'kkv', 'kkw', 'kkx', 'kky', 'kkz', 'kla', 'klb', 'klc', 'kld', 'kle', 'klf', 'klg', 'klh', 'kli', 'klj', 'klk', 'kll', 'klm', 'kln', 'klo', 'klp', 'klq', 'klr', 'kls', 'klt', 'klu', 'klv', 'klw', 'klx', 'kly', 'klz', 'kma', 'kmb', 'kmc', 'kmd', 'kme', 'kmf', 'kmg', 'kmh', 'kmi', 'kmj', 'kmk', 'kml', 'kmm', 'kmn', 'kmo', 'kmp', 'kmq', 'kmr', 'kms', 'kmt', 'kmu', 'kmv', 'kmw', 'kmx', 'kmy', 'kmz', 'kna', 'knb', 'knc', 'knd', 'kne', 'knf', 'kng', 'kni', 'knj', 'knk', 'knl', 'knm', 'knn', 'kno', 'knp', 'knq', 'knr', 'kns', 'knt', 'knu', 'knv', 'knw', 'knx', 'kny', 'knz', 'koa', 'koc', 'kod', 'koe', 'kof', 'kog', 'koh', 'koi', 'koj', 'kok', 'kol', 'koo', 'kop', 'koq', 'kos', 'kot', 'kou', 'kov', 'kow', 'kox', 'koy', 'koz', 'kpa', 'kpb', 'kpc', 'kpd', 'kpe', 'kpf', 'kpg', 'kph', 'kpi', 'kpj', 'kpk', 'kpl', 'kpm', 'kpn', 'kpo', 'kpp', 'kpq', 'kpr', 'kps', 'kpt', 'kpu', 'kpv', 'kpw', 'kpx', 'kpy', 'kpz', 'kqa', 'kqb', 'kqc', 'kqd', 'kqe', 'kqf', 'kqg', 'kqh', 'kqi', 'kqj', 'kqk', 'kql', 'kqm', 'kqn', 'kqo', 'kqp', 'kqq', 'kqr', 'kqs', 'kqt', 'kqu', 'kqv', 'kqw', 'kqx', 'kqy', 'kqz', 'kra', 'krb', 'krc', 'krd', 'kre', 'krf', 'krh', 'kri', 'krj', 'krk', 'krl', 'krm', 'krn', 'kro', 'krp', 'krr', 'krs', 'krt', 'kru', 'krv', 'krw', 'krx', 'kry', 'krz', 'ksa', 'ksb', 'ksc', 'ksd', 'kse', 'ksf', 'ksg', 'ksh', 'ksi', 'ksj', 'ksk', 'ksl', 'ksm', 'ksn', 'kso', 'ksp', 'ksq', 'ksr', 'kss', 'kst', 'ksu', 'ksv', 'ksw', 'ksx', 'ksy', 'ksz', 'kta', 'ktb', 'ktc', 'ktd', 'kte', 'ktf', 'ktg', 'kth', 'kti', 'ktj', 'ktk', 'ktl', 'ktm', 'ktn', 'kto', 'ktp', 'ktq', 'ktr', 'kts', 'ktt', 'ktu', 'ktv', 'ktw', 'ktx', 'kty', 'ktz', 'kub', 'kuc', 'kud', 'kue', 'kuf', 'kug', 'kuh', 'kui', 'kuj', 'kuk', 'kul', 'kum', 'kun', 'kuo', 'kup', 'kuq', 'kus', 'kut', 'kuu', 'kuv', 'kuw', 'kux', 'kuy', 'kuz', 'kva', 'kvb', 'kvc', 'kvd', 'kve', 'kvf', 'kvg', 'kvh', 'kvi', 'kvj', 'kvk', 'kvl', 'kvm', 'kvn', 'kvo', 'kvp', 'kvq', 'kvr', 'kvs', 'kvt', 'kvu', 'kvv', 'kvw', 'kvx', 'kvy', 'kvz', 'kwa', 'kwb', 'kwc', 'kwd', 'kwe', 'kwf', 'kwg', 'kwh', 'kwi', 'kwj', 'kwk', 'kwl', 'kwm', 'kwn', 'kwo', 'kwp', 'kwq', 'kwr', 'kws', 'kwt', 'kwu', 'kwv', 'kww', 'kwx', 'kwy', 'kwz', 'kxa', 'kxb', 'kxc', 'kxd', 'kxe', 'kxf', 'kxh', 'kxi', 'kxj', 'kxk', 'kxl', 'kxm', 'kxn', 'kxo', 'kxp', 'kxq', 'kxr', 'kxs', 'kxt', 'kxu', 'kxv', 'kxw', 'kxx', 'kxy', 'kxz', 'kya', 'kyb', 'kyc', 'kyd', 'kye', 'kyf', 'kyg', 'kyh', 'kyi', 'kyj', 'kyk', 'kyl', 'kym', 'kyn', 'kyo', 'kyp', 'kyq', 'kyr', 'kys', 'kyt', 'kyu', 'kyv', 'kyw', 'kyx', 'kyy', 'kyz', 'kza', 'kzb', 'kzc', 'kzd', 'kze', 'kzf', 'kzg', 'kzh', 'kzi', 'kzj', 'kzk', 'kzl', 'kzm', 'kzn', 'kzo', 'kzp', 'kzq', 'kzr', 'kzs', 'kzt', 'kzu', 'kzv', 'kzw', 'kzx', 'kzy', 'kzz', 'laa', 'lab', 'lac', 'lad', 'lae', 'laf', 'lag', 'lah', 'lai', 'laj', 'lak', 'lal', 'lam', 'lan', 'lap', 'laq', 'lar', 'las', 'lau', 'law', 'lax', 'lay', 'laz', 'lba', 'lbb', 'lbc', 'lbe', 'lbf', 'lbg', 'lbi', 'lbj', 'lbk', 'lbl', 'lbm', 'lbn', 'lbo', 'lbq', 'lbr', 'lbs', 'lbt', 'lbu', 'lbv', 'lbw', 'lbx', 'lby', 'lbz', 'lcc', 'lcd', 'lce', 'lcf', 'lch', 'lcl', 'lcm', 'lcp', 'lcq', 'lcs', 'lda', 'ldb', 'ldd', 'ldg', 'ldh', 'ldi', 'ldj', 'ldk', 'ldl', 'ldm', 'ldn', 'ldo', 'ldp', 'ldq', 'lea', 'leb', 'lec', 'led', 'lee', 'lef', 'leg', 'leh', 'lei', 'lej', 'lek', 'lel', 'lem', 'len', 'leo', 'lep', 'leq', 'ler', 'les', 'let', 'leu', 'lev', 'lew', 'lex', 'ley', 'lez', 'lfa', 'lfn', 'lga', 'lgb', 'lgg', 'lgh', 'lgi', 'lgk', 'lgl', 'lgm', 'lgn', 'lgq', 'lgr', 'lgt', 'lgu', 'lgz', 'lha', 'lhh', 'lhi', 'lhl', 'lhm', 'lhn', 'lhp', 'lhs', 'lht', 'lhu', 'lia', 'lib', 'lic', 'lid', 'lie', 'lif', 'lig', 'lih', 'lii', 'lij', 'lik', 'lil', 'lio', 'lip', 'liq', 'lir', 'lis', 'liu', 'liv', 'liw', 'lix', 'liy', 'liz', 'lja', 'lje', 'lji', 'ljl', 'ljp', 'ljw', 'ljx', 'lka', 'lkb', 'lkc', 'lkd', 'lke', 'lkh', 'lki', 'lkj', 'lkl', 'lkm', 'lkn', 'lko', 'lkr', 'lks', 'lkt', 'lku', 'lky', 'lla', 'llb', 'llc', 'lld', 'lle', 'llf', 'llg', 'llh', 'lli', 'llj', 'llk', 'lll', 'llm', 'lln', 'llo', 'llp', 'llq', 'lls', 'llu', 'llx', 'lma', 'lmb', 'lmc', 'lmd', 'lme', 'lmf', 'lmg', 'lmh', 'lmi', 'lmj', 'lmk', 'lml', 'lmm', 'lmn', 'lmo', 'lmp', 'lmq', 'lmr', 'lmu', 'lmv', 'lmw', 'lmx', 'lmy', 'lmz', 'lna', 'lnb', 'lnd', 'lng', 'lnh', 'lni', 'lnj', 'lnl', 'lnm', 'lnn', 'lno', 'lns', 'lnu', 'lnw', 'lnz', 'loa', 'lob', 'loc', 'loe', 'lof', 'log', 'loh', 'loi', 'loj', 'lok', 'lol', 'lom', 'lon', 'loo', 'lop', 'loq', 'lor', 'los', 'lot', 'lou', 'lov', 'low', 'lox', 'loy', 'loz', 'lpa', 'lpe', 'lpn', 'lpo', 'lpx', 'lra', 'lrc', 'lre', 'lrg', 'lri', 'lrk', 'lrl', 'lrm', 'lrn', 'lro', 'lrr', 'lrt', 'lrv', 'lrz', 'lsa', 'lsd', 'lse', 'lsg', 'lsh', 'lsi', 'lsl', 'lsm', 'lso', 'lsp', 'lsr', 'lss', 'lst', 'lsy', 'ltc', 'ltg', 'lth', 'lti', 'ltn', 'lto', 'lts', 'ltu', 'lua', 'luc', 'lud', 'lue', 'luf', 'lui', 'luj', 'luk', 'lul', 'lum', 'lun', 'luo', 'lup', 'luq', 'lur', 'lus', 'lut', 'luu', 'luv', 'luw', 'luy', 'luz', 'lva', 'lvk', 'lvs', 'lvu', 'lwa', 'lwe', 'lwg', 'lwh', 'lwl', 'lwm', 'lwo', 'lwt', 'lwu', 'lww', 'lya', 'lyg', 'lyn', 'lzh', 'lzl', 'lzn', 'lzz', 'maa', 'mab', 'mad', 'mae', 'maf', 'mag', 'mai', 'maj', 'mak', 'mam', 'man', 'map', 'maq', 'mas', 'mat', 'mau', 'mav', 'maw', 'max', 'maz', 'mba', 'mbb', 'mbc', 'mbd', 'mbe', 'mbf', 'mbh', 'mbi', 'mbj', 'mbk', 'mbl', 'mbm', 'mbn', 'mbo', 'mbp', 'mbq', 'mbr', 'mbs', 'mbt', 'mbu', 'mbv', 'mbw', 'mbx', 'mby', 'mbz', 'mca', 'mcb', 'mcc', 'mcd', 'mce', 'mcf', 'mcg', 'mch', 'mci', 'mcj', 'mck', 'mcl', 'mcm', 'mcn', 'mco', 'mcp', 'mcq', 'mcr', 'mcs', 'mct', 'mcu', 'mcv', 'mcw', 'mcx', 'mcy', 'mcz', 'mda', 'mdb', 'mdc', 'mdd', 'mde', 'mdf', 'mdg', 'mdh', 'mdi', 'mdj', 'mdk', 'mdl', 'mdm', 'mdn', 'mdp', 'mdq', 'mdr', 'mds', 'mdt', 'mdu', 'mdv', 'mdw', 'mdx', 'mdy', 'mdz', 'mea', 'meb', 'mec', 'med', 'mee', 'mef', 'meg', 'meh', 'mei', 'mej', 'mek', 'mel', 'mem', 'men', 'meo', 'mep', 'meq', 'mer', 'mes', 'met', 'meu', 'mev', 'mew', 'mey', 'mez', 'mfa', 'mfb', 'mfc', 'mfd', 'mfe', 'mff', 'mfg', 'mfh', 'mfi', 'mfj', 'mfk', 'mfl', 'mfm', 'mfn', 'mfo', 'mfp', 'mfq', 'mfr', 'mfs', 'mft', 'mfu', 'mfv', 'mfw', 'mfx', 'mfy', 'mfz', 'mga', 'mgb', 'mgc', 'mgd', 'mge', 'mgf', 'mgg', 'mgh', 'mgi', 'mgj', 'mgk', 'mgl', 'mgm', 'mgn', 'mgo', 'mgp', 'mgq', 'mgr', 'mgs', 'mgt', 'mgu', 'mgv', 'mgw', 'mgx', 'mgy', 'mgz', 'mha', 'mhb', 'mhc', 'mhd', 'mhe', 'mhf', 'mhg', 'mhh', 'mhi', 'mhj', 'mhk', 'mhl', 'mhm', 'mhn', 'mho', 'mhp', 'mhq', 'mhr', 'mhs', 'mht', 'mhu', 'mhw', 'mhx', 'mhy', 'mhz', 'mia', 'mib', 'mic', 'mid', 'mie', 'mif', 'mig', 'mih', 'mii', 'mij', 'mik', 'mil', 'mim', 'min', 'mio', 'mip', 'miq', 'mir', 'mis', 'mit', 'miu', 'miw', 'mix', 'miy', 'miz', 'mja', 'mjb', 'mjc', 'mjd', 'mje', 'mjg', 'mjh', 'mji', 'mjj', 'mjk', 'mjl', 'mjm', 'mjn', 'mjo', 'mjp', 'mjq', 'mjr', 'mjs', 'mjt', 'mju', 'mjv', 'mjw', 'mjx', 'mjy', 'mjz', 'mka', 'mkb', 'mkc', 'mke', 'mkf', 'mkg', 'mkh', 'mki', 'mkj', 'mkk', 'mkl', 'mkm', 'mkn', 'mko', 'mkp', 'mkq', 'mkr', 'mks', 'mkt', 'mku', 'mkv', 'mkw', 'mkx', 'mky', 'mkz', 'mla', 'mlb', 'mlc', 'mld', 'mle', 'mlf', 'mlh', 'mli', 'mlj', 'mlk', 'mll', 'mlm', 'mln', 'mlo', 'mlp', 'mlq', 'mlr', 'mls', 'mlu', 'mlv', 'mlw', 'mlx', 'mlz', 'mma', 'mmb', 'mmc', 'mmd', 'mme', 'mmf', 'mmg', 'mmh', 'mmi', 'mmj', 'mmk', 'mml', 'mmm', 'mmn', 'mmo', 'mmp', 'mmq', 'mmr', 'mmt', 'mmu', 'mmv', 'mmw', 'mmx', 'mmy', 'mmz', 'mna', 'mnb', 'mnc', 'mnd', 'mne', 'mnf', 'mng', 'mnh', 'mni', 'mnj', 'mnk', 'mnl', 'mnm', 'mnn', 'mno', 'mnp', 'mnq', 'mnr', 'mns', 'mnt', 'mnu', 'mnv', 'mnw', 'mnx', 'mny', 'mnz', 'moa', 'moc', 'mod', 'moe', 'mof', 'mog', 'moh', 'moi', 'moj', 'mok', 'mom', 'moo', 'mop', 'moq', 'mor', 'mos', 'mot', 'mou', 'mov', 'mow', 'mox', 'moy', 'moz', 'mpa', 'mpb', 'mpc', 'mpd', 'mpe', 'mpg', 'mph', 'mpi', 'mpj', 'mpk', 'mpl', 'mpm', 'mpn', 'mpo', 'mpp', 'mpq', 'mpr', 'mps', 'mpt', 'mpu', 'mpv', 'mpw', 'mpx', 'mpy', 'mpz', 'mqa', 'mqb', 'mqc', 'mqe', 'mqf', 'mqg', 'mqh', 'mqi', 'mqj', 'mqk', 'mql', 'mqm', 'mqn', 'mqo', 'mqp', 'mqq', 'mqr', 'mqs', 'mqt', 'mqu', 'mqv', 'mqw', 'mqx', 'mqy', 'mqz', 'mra', 'mrb', 'mrc', 'mrd', 'mre', 'mrf', 'mrg', 'mrh', 'mrj', 'mrk', 'mrl', 'mrm', 'mrn', 'mro', 'mrp', 'mrq', 'mrr', 'mrs', 'mrt', 'mru', 'mrv', 'mrw', 'mrx', 'mry', 'mrz', 'msb', 'msc', 'msd', 'mse', 'msf', 'msg', 'msh', 'msi', 'msj', 'msk', 'msl', 'msm', 'msn', 'mso', 'msp', 'msq', 'msr', 'mss', 'mst', 'msu', 'msv', 'msw', 'msx', 'msy', 'msz', 'mta', 'mtb', 'mtc', 'mtd', 'mte', 'mtf', 'mtg', 'mth', 'mti', 'mtj', 'mtk', 'mtl', 'mtm', 'mtn', 'mto', 'mtp', 'mtq', 'mtr', 'mts', 'mtt', 'mtu', 'mtv', 'mtw', 'mtx', 'mty', 'mua', 'mub', 'muc', 'mud', 'mue', 'mug', 'muh', 'mui', 'muj', 'muk', 'mul', 'mum', 'mun', 'muo', 'mup', 'muq', 'mur', 'mus', 'mut', 'muu', 'muv', 'mux', 'muy', 'muz', 'mva', 'mvb', 'mvd', 'mve', 'mvf', 'mvg', 'mvh', 'mvi', 'mvk', 'mvl', 'mvm', 'mvn', 'mvo', 'mvp', 'mvq', 'mvr', 'mvs', 'mvt', 'mvu', 'mvv', 'mvw', 'mvx', 'mvy', 'mvz', 'mwa', 'mwb', 'mwc', 'mwd', 'mwe', 'mwf', 'mwg', 'mwh', 'mwi', 'mwj', 'mwk', 'mwl', 'mwm', 'mwn', 'mwo', 'mwp', 'mwq', 'mwr', 'mws', 'mwt', 'mwu', 'mwv', 'mww', 'mwx', 'mwy', 'mwz', 'mxa', 'mxb', 'mxc', 'mxd', 'mxe', 'mxf', 'mxg', 'mxh', 'mxi', 'mxj', 'mxk', 'mxl', 'mxm', 'mxn', 'mxo', 'mxp', 'mxq', 'mxr', 'mxs', 'mxt', 'mxu', 'mxv', 'mxw', 'mxx', 'mxy', 'mxz', 'myb', 'myc', 'myd', 'mye', 'myf', 'myg', 'myh', 'myi', 'myj', 'myk', 'myl', 'mym', 'myn', 'myo', 'myp', 'myq', 'myr', 'mys', 'myt', 'myu', 'myv', 'myw', 'myx', 'myy', 'myz', 'mza', 'mzb', 'mzc', 'mzd', 'mze', 'mzg', 'mzh', 'mzi', 'mzj', 'mzk', 'mzl', 'mzm', 'mzn', 'mzo', 'mzp', 'mzq', 'mzr', 'mzs', 'mzt', 'mzu', 'mzv', 'mzw', 'mzx', 'mzy', 'mzz', 'naa', 'nab', 'nac', 'nad', 'nae', 'naf', 'nag', 'nah', 'nai', 'naj', 'nak', 'nal', 'nam', 'nan', 'nao', 'nap', 'naq', 'nar', 'nas', 'nat', 'naw', 'nax', 'nay', 'naz', 'nba', 'nbb', 'nbc', 'nbd', 'nbe', 'nbf', 'nbg', 'nbh', 'nbi', 'nbj', 'nbk', 'nbm', 'nbn', 'nbo', 'nbp', 'nbq', 'nbr', 'nbs', 'nbt', 'nbu', 'nbv', 'nbw', 'nbx', 'nby', 'nca', 'ncb', 'ncc', 'ncd', 'nce', 'ncf', 'ncg', 'nch', 'nci', 'ncj', 'nck', 'ncl', 'ncm', 'ncn', 'nco', 'ncp', 'ncq', 'ncr', 'ncs', 'nct', 'ncu', 'ncx', 'ncz', 'nda', 'ndb', 'ndc', 'ndd', 'ndf', 'ndg', 'ndh', 'ndi', 'ndj', 'ndk', 'ndl', 'ndm', 'ndn', 'ndp', 'ndq', 'ndr', 'nds', 'ndt', 'ndu', 'ndv', 'ndw', 'ndx', 'ndy', 'ndz', 'nea', 'neb', 'nec', 'ned', 'nee', 'nef', 'neg', 'neh', 'nei', 'nej', 'nek', 'nem', 'nen', 'neo', 'neq', 'ner', 'nes', 'net', 'neu', 'nev', 'new', 'nex', 'ney', 'nez', 'nfa', 'nfd', 'nfl', 'nfr', 'nfu', 'nga', 'ngb', 'ngc', 'ngd', 'nge', 'ngf', 'ngg', 'ngh', 'ngi', 'ngj', 'ngk', 'ngl', 'ngm', 'ngn', 'ngo', 'ngp', 'ngq', 'ngr', 'ngs', 'ngt', 'ngu', 'ngv', 'ngw', 'ngx', 'ngy', 'ngz', 'nha', 'nhb', 'nhc', 'nhd', 'nhe', 'nhf', 'nhg', 'nhh', 'nhi', 'nhk', 'nhm', 'nhn', 'nho', 'nhp', 'nhq', 'nhr', 'nht', 'nhu', 'nhv', 'nhw', 'nhx', 'nhy', 'nhz', 'nia', 'nib', 'nic', 'nid', 'nie', 'nif', 'nig', 'nih', 'nii', 'nij', 'nik', 'nil', 'nim', 'nin', 'nio', 'niq', 'nir', 'nis', 'nit', 'niu', 'niv', 'niw', 'nix', 'niy', 'niz', 'nja', 'njb', 'njd', 'njh', 'nji', 'njj', 'njl', 'njm', 'njn', 'njo', 'njr', 'njs', 'njt', 'nju', 'njx', 'njy', 'njz', 'nka', 'nkb', 'nkc', 'nkd', 'nke', 'nkf', 'nkg', 'nkh', 'nki', 'nkj', 'nkk', 'nkm', 'nkn', 'nko', 'nkp', 'nkq', 'nkr', 'nks', 'nkt', 'nku', 'nkv', 'nkw', 'nkx', 'nkz', 'nla', 'nlc', 'nle', 'nlg', 'nli', 'nlj', 'nlk', 'nll', 'nln', 'nlo', 'nlq', 'nlr', 'nlu', 'nlv', 'nlw', 'nlx', 'nly', 'nlz', 'nma', 'nmb', 'nmc', 'nmd', 'nme', 'nmf', 'nmg', 'nmh', 'nmi', 'nmj', 'nmk', 'nml', 'nmm', 'nmn', 'nmo', 'nmp', 'nmq', 'nmr', 'nms', 'nmt', 'nmu', 'nmv', 'nmw', 'nmx', 'nmy', 'nmz', 'nna', 'nnb', 'nnc', 'nnd', 'nne', 'nnf', 'nng', 'nnh', 'nni', 'nnj', 'nnk', 'nnl', 'nnm', 'nnn', 'nnp', 'nnq', 'nnr', 'nns', 'nnt', 'nnu', 'nnv', 'nnw', 'nnx', 'nny', 'nnz', 'noa', 'noc', 'nod', 'noe', 'nof', 'nog', 'noh', 'noi', 'noj', 'nok', 'nol', 'nom', 'non', 'noo', 'nop', 'noq', 'nos', 'not', 'nou', 'nov', 'now', 'noy', 'noz', 'npa', 'npb', 'npg', 'nph', 'npi', 'npl', 'npn', 'npo', 'nps', 'npu', 'npx', 'npy', 'nqg', 'nqk', 'nql', 'nqm', 'nqn', 'nqo', 'nqq', 'nqy', 'nra', 'nrb', 'nrc', 'nre', 'nrf', 'nrg', 'nri', 'nrk', 'nrl', 'nrm', 'nrn', 'nrp', 'nrr', 'nrt', 'nru', 'nrx', 'nrz', 'nsa', 'nsc', 'nsd', 'nse', 'nsf', 'nsg', 'nsh', 'nsi', 'nsk', 'nsl', 'nsm', 'nsn', 'nso', 'nsp', 'nsq', 'nsr', 'nss', 'nst', 'nsu', 'nsv', 'nsw', 'nsx', 'nsy', 'nsz', 'ntd', 'nte', 'ntg', 'nti', 'ntj', 'ntk', 'ntm', 'nto', 'ntp', 'ntr', 'nts', 'ntu', 'ntw', 'ntx', 'nty', 'ntz', 'nua', 'nub', 'nuc', 'nud', 'nue', 'nuf', 'nug', 'nuh', 'nui', 'nuj', 'nuk', 'nul', 'num', 'nun', 'nuo', 'nup', 'nuq', 'nur', 'nus', 'nut', 'nuu', 'nuv', 'nuw', 'nux', 'nuy', 'nuz', 'nvh', 'nvm', 'nvo', 'nwa', 'nwb', 'nwc', 'nwe', 'nwg', 'nwi', 'nwm', 'nwo', 'nwr', 'nwx', 'nwy', 'nxa', 'nxd', 'nxe', 'nxg', 'nxi', 'nxk', 'nxl', 'nxm', 'nxn', 'nxo', 'nxq', 'nxr', 'nxu', 'nxx', 'nyb', 'nyc', 'nyd', 'nye', 'nyf', 'nyg', 'nyh', 'nyi', 'nyj', 'nyk', 'nyl', 'nym', 'nyn', 'nyo', 'nyp', 'nyq', 'nyr', 'nys', 'nyt', 'nyu', 'nyv', 'nyw', 'nyx', 'nyy', 'nza', 'nzb', 'nzi', 'nzk', 'nzm', 'nzs', 'nzu', 'nzy', 'nzz', 'oaa', 'oac', 'oar', 'oav', 'obi', 'obk', 'obl', 'obm', 'obo', 'obr', 'obt', 'obu', 'oca', 'och', 'oco', 'ocu', 'oda', 'odk', 'odt', 'odu', 'ofo', 'ofs', 'ofu', 'ogb', 'ogc', 'oge', 'ogg', 'ogo', 'ogu', 'oht', 'ohu', 'oia', 'oin', 'ojb', 'ojc', 'ojg', 'ojp', 'ojs', 'ojv', 'ojw', 'oka', 'okb', 'okd', 'oke', 'okg', 'okh', 'oki', 'okj', 'okk', 'okl', 'okm', 'okn', 'oko', 'okr', 'oks', 'oku', 'okv', 'okx', 'ola', 'old', 'ole', 'olk', 'olm', 'olo', 'olr', 'olt', 'olu', 'oma', 'omb', 'omc', 'ome', 'omg', 'omi', 'omk', 'oml', 'omn', 'omo', 'omp', 'omq', 'omr', 'omt', 'omu', 'omv', 'omw', 'omx', 'ona', 'onb', 'one', 'ong', 'oni', 'onj', 'onk', 'onn', 'ono', 'onp', 'onr', 'ons', 'ont', 'onu', 'onw', 'onx', 'ood', 'oog', 'oon', 'oor', 'oos', 'opa', 'opk', 'opm', 'opo', 'opt', 'opy', 'ora', 'orc', 'ore', 'org', 'orh', 'orn', 'oro', 'orr', 'ors', 'ort', 'oru', 'orv', 'orw', 'orx', 'ory', 'orz', 'osa', 'osc', 'osi', 'oso', 'osp', 'ost', 'osu', 'osx', 'ota', 'otb', 'otd', 'ote', 'oti', 'otk', 'otl', 'otm', 'otn', 'oto', 'otq', 'otr', 'ots', 'ott', 'otu', 'otw', 'otx', 'oty', 'otz', 'oua', 'oub', 'oue', 'oui', 'oum', 'oun', 'ovd', 'owi', 'owl', 'oyb', 'oyd', 'oym', 'oyy', 'ozm', 'paa', 'pab', 'pac', 'pad', 'pae', 'paf', 'pag', 'pah', 'pai', 'pak', 'pal', 'pam', 'pao', 'pap', 'paq', 'par', 'pas', 'pat', 'pau', 'pav', 'paw', 'pax', 'pay', 'paz', 'pbb', 'pbc', 'pbe', 'pbf', 'pbg', 'pbh', 'pbi', 'pbl', 'pbn', 'pbo', 'pbp', 'pbr', 'pbs', 'pbt', 'pbu', 'pbv', 'pby', 'pbz', 'pca', 'pcb', 'pcc', 'pcd', 'pce', 'pcf', 'pcg', 'pch', 'pci', 'pcj', 'pck', 'pcl', 'pcm', 'pcn', 'pcp', 'pcr', 'pcw', 'pda', 'pdc', 'pdi', 'pdn', 'pdo', 'pdt', 'pdu', 'pea', 'peb', 'ped', 'pee', 'pef', 'peg', 'peh', 'pei', 'pej', 'pek', 'pel', 'pem', 'peo', 'pep', 'peq', 'pes', 'pev', 'pex', 'pey', 'pez', 'pfa', 'pfe', 'pfl', 'pga', 'pgd', 'pgg', 'pgi', 'pgk', 'pgl', 'pgn', 'pgs', 'pgu', 'pgy', 'pgz', 'pha', 'phd', 'phg', 'phh', 'phi', 'phk', 'phl', 'phm', 'phn', 'pho', 'phq', 'phr', 'pht', 'phu', 'phv', 'phw', 'pia', 'pib', 'pic', 'pid', 'pie', 'pif', 'pig', 'pih', 'pii', 'pij', 'pil', 'pim', 'pin', 'pio', 'pip', 'pir', 'pis', 'pit', 'piu', 'piv', 'piw', 'pix', 'piy', 'piz', 'pjt', 'pka', 'pkb', 'pkc', 'pkg', 'pkh', 'pkn', 'pko', 'pkp', 'pkr', 'pks', 'pkt', 'pku', 'pla', 'plb', 'plc', 'pld', 'ple', 'plf', 'plg', 'plh', 'plj', 'plk', 'pll', 'pln', 'plo', 'plp', 'plq', 'plr', 'pls', 'plt', 'plu', 'plv', 'plw', 'ply', 'plz', 'pma', 'pmb', 'pmc', 'pmd', 'pme', 'pmf', 'pmh', 'pmi', 'pmj', 'pmk', 'pml', 'pmm', 'pmn', 'pmo', 'pmq', 'pmr', 'pms', 'pmt', 'pmu', 'pmw', 'pmx', 'pmy', 'pmz', 'pna', 'pnb', 'pnc', 'pne', 'png', 'pnh', 'pni', 'pnj', 'pnk', 'pnl', 'pnm', 'pnn', 'pno', 'pnp', 'pnq', 'pnr', 'pns', 'pnt', 'pnu', 'pnv', 'pnw', 'pnx', 'pny', 'pnz', 'poc', 'pod', 'poe', 'pof', 'pog', 'poh', 'poi', 'pok', 'pom', 'pon', 'poo', 'pop', 'poq', 'pos', 'pot', 'pov', 'pow', 'pox', 'poy', 'poz', 'ppa', 'ppe', 'ppi', 'ppk', 'ppl', 'ppm', 'ppn', 'ppo', 'ppp', 'ppq', 'ppr', 'pps', 'ppt', 'ppu', 'pqa', 'pqe', 'pqm', 'pqw', 'pra', 'prb', 'prc', 'prd', 'pre', 'prf', 'prg', 'prh', 'pri', 'prk', 'prl', 'prm', 'prn', 'pro', 'prp', 'prq', 'prr', 'prs', 'prt', 'pru', 'prw', 'prx', 'pry', 'prz', 'psa', 'psc', 'psd', 'pse', 'psg', 'psh', 'psi', 'psl', 'psm', 'psn', 'pso', 'psp', 'psq', 'psr', 'pss', 'pst', 'psu', 'psw', 'psy', 'pta', 'pth', 'pti', 'ptn', 'pto', 'ptp', 'ptq', 'ptr', 'ptt', 'ptu', 'ptv', 'ptw', 'pty', 'pua', 'pub', 'puc', 'pud', 'pue', 'puf', 'pug', 'pui', 'puj', 'puk', 'pum', 'puo', 'pup', 'puq', 'pur', 'put', 'puu', 'puw', 'pux', 'puy', 'puz', 'pwa', 'pwb', 'pwg', 'pwi', 'pwm', 'pwn', 'pwo', 'pwr', 'pww', 'pxm', 'pye', 'pym', 'pyn', 'pys', 'pyu', 'pyx', 'pyy', 'pzn', 'qaa..qtz', 'qua', 'qub', 'quc', 'qud', 'quf', 'qug', 'quh', 'qui', 'quk', 'qul', 'qum', 'qun', 'qup', 'quq', 'qur', 'qus', 'quv', 'quw', 'qux', 'quy', 'quz', 'qva', 'qvc', 'qve', 'qvh', 'qvi', 'qvj', 'qvl', 'qvm', 'qvn', 'qvo', 'qvp', 'qvs', 'qvw', 'qvy', 'qvz', 'qwa', 'qwc', 'qwe', 'qwh', 'qwm', 'qws', 'qwt', 'qxa', 'qxc', 'qxh', 'qxl', 'qxn', 'qxo', 'qxp', 'qxq', 'qxr', 'qxs', 'qxt', 'qxu', 'qxw', 'qya', 'qyp', 'raa', 'rab', 'rac', 'rad', 'raf', 'rag', 'rah', 'rai', 'raj', 'rak', 'ral', 'ram', 'ran', 'rao', 'rap', 'raq', 'rar', 'ras', 'rat', 'rau', 'rav', 'raw', 'rax', 'ray', 'raz', 'rbb', 'rbk', 'rbl', 'rbp', 'rcf', 'rdb', 'rea', 'reb', 'ree', 'reg', 'rei', 'rej', 'rel', 'rem', 'ren', 'rer', 'res', 'ret', 'rey', 'rga', 'rge', 'rgk', 'rgn', 'rgr', 'rgs', 'rgu', 'rhg', 'rhp', 'ria', 'rie', 'rif', 'ril', 'rim', 'rin', 'rir', 'rit', 'riu', 'rjg', 'rji', 'rjs', 'rka', 'rkb', 'rkh', 'rki', 'rkm', 'rkt', 'rkw', 'rma', 'rmb', 'rmc', 'rmd', 'rme', 'rmf', 'rmg', 'rmh', 'rmi', 'rmk', 'rml', 'rmm', 'rmn', 'rmo', 'rmp', 'rmq', 'rmr', 'rms', 'rmt', 'rmu', 'rmv', 'rmw', 'rmx', 'rmy', 'rmz', 'rna', 'rnd', 'rng', 'rnl', 'rnn', 'rnp', 'rnr', 'rnw', 'roa', 'rob', 'roc', 'rod', 'roe', 'rof', 'rog', 'rol', 'rom', 'roo', 'rop', 'ror', 'rou', 'row', 'rpn', 'rpt', 'rri', 'rro', 'rrt', 'rsb', 'rsi', 'rsl', 'rsm', 'rtc', 'rth', 'rtm', 'rts', 'rtw', 'rub', 'ruc', 'rue', 'ruf', 'rug', 'ruh', 'rui', 'ruk', 'ruo', 'rup', 'ruq', 'rut', 'ruu', 'ruy', 'ruz', 'rwa', 'rwk', 'rwm', 'rwo', 'rwr', 'rxd', 'rxw', 'ryn', 'rys', 'ryu', 'rzh', 'saa', 'sab', 'sac', 'sad', 'sae', 'saf', 'sah', 'sai', 'saj', 'sak', 'sal', 'sam', 'sao', 'sap', 'saq', 'sar', 'sas', 'sat', 'sau', 'sav', 'saw', 'sax', 'say', 'saz', 'sba', 'sbb', 'sbc', 'sbd', 'sbe', 'sbf', 'sbg', 'sbh', 'sbi', 'sbj', 'sbk', 'sbl', 'sbm', 'sbn', 'sbo', 'sbp', 'sbq', 'sbr', 'sbs', 'sbt', 'sbu', 'sbv', 'sbw', 'sbx', 'sby', 'sbz', 'sca', 'scb', 'sce', 'scf', 'scg', 'sch', 'sci', 'sck', 'scl', 'scn', 'sco', 'scp', 'scq', 'scs', 'sct', 'scu', 'scv', 'scw', 'scx', 'sda', 'sdb', 'sdc', 'sde', 'sdf', 'sdg', 'sdh', 'sdj', 'sdk', 'sdl', 'sdm', 'sdn', 'sdo', 'sdp', 'sdr', 'sds', 'sdt', 'sdu', 'sdv', 'sdx', 'sdz', 'sea', 'seb', 'sec', 'sed', 'see', 'sef', 'seg', 'seh', 'sei', 'sej', 'sek', 'sel', 'sem', 'sen', 'seo', 'sep', 'seq', 'ser', 'ses', 'set', 'seu', 'sev', 'sew', 'sey', 'sez', 'sfb', 'sfe', 'sfm', 'sfs', 'sfw', 'sga', 'sgb', 'sgc', 'sgd', 'sge', 'sgg', 'sgh', 'sgi', 'sgj', 'sgk', 'sgl', 'sgm', 'sgn', 'sgo', 'sgp', 'sgr', 'sgs', 'sgt', 'sgu', 'sgw', 'sgx', 'sgy', 'sgz', 'sha', 'shb', 'shc', 'shd', 'she', 'shg', 'shh', 'shi', 'shj', 'shk', 'shl', 'shm', 'shn', 'sho', 'shp', 'shq', 'shr', 'shs', 'sht', 'shu', 'shv', 'shw', 'shx', 'shy', 'shz', 'sia', 'sib', 'sid', 'sie', 'sif', 'sig', 'sih', 'sii', 'sij', 'sik', 'sil', 'sim', 'sio', 'sip', 'siq', 'sir', 'sis', 'sit', 'siu', 'siv', 'siw', 'six', 'siy', 'siz', 'sja', 'sjb', 'sjd', 'sje', 'sjg', 'sjk', 'sjl', 'sjm', 'sjn', 'sjo', 'sjp', 'sjr', 'sjs', 'sjt', 'sju', 'sjw', 'ska', 'skb', 'skc', 'skd', 'ske', 'skf', 'skg', 'skh', 'ski', 'skj', 'skk', 'skm', 'skn', 'sko', 'skp', 'skq', 'skr', 'sks', 'skt', 'sku', 'skv', 'skw', 'skx', 'sky', 'skz', 'sla', 'slc', 'sld', 'sle', 'slf', 'slg', 'slh', 'sli', 'slj', 'sll', 'slm', 'sln', 'slp', 'slq', 'slr', 'sls', 'slt', 'slu', 'slw', 'slx', 'sly', 'slz', 'sma', 'smb', 'smc', 'smd', 'smf', 'smg', 'smh', 'smi', 'smj', 'smk', 'sml', 'smm', 'smn', 'smp', 'smq', 'smr', 'sms', 'smt', 'smu', 'smv', 'smw', 'smx', 'smy', 'smz', 'snb', 'snc', 'sne', 'snf', 'sng', 'snh', 'sni', 'snj', 'snk', 'snl', 'snm', 'snn', 'sno', 'snp', 'snq', 'snr', 'sns', 'snu', 'snv', 'snw', 'snx', 'sny', 'snz', 'soa', 'sob', 'soc', 'sod', 'soe', 'sog', 'soh', 'soi', 'soj', 'sok', 'sol', 'son', 'soo', 'sop', 'soq', 'sor', 'sos', 'sou', 'sov', 'sow', 'sox', 'soy', 'soz', 'spb', 'spc', 'spd', 'spe', 'spg', 'spi', 'spk', 'spl', 'spm', 'spn', 'spo', 'spp', 'spq', 'spr', 'sps', 'spt', 'spu', 'spv', 'spx', 'spy', 'sqa', 'sqh', 'sqj', 'sqk', 'sqm', 'sqn', 'sqo', 'sqq', 'sqr', 'sqs', 'sqt', 'squ', 'sra', 'srb', 'src', 'sre', 'srf', 'srg', 'srh', 'sri', 'srk', 'srl', 'srm', 'srn', 'sro', 'srq', 'srr', 'srs', 'srt', 'sru', 'srv', 'srw', 'srx', 'sry', 'srz', 'ssa', 'ssb', 'ssc', 'ssd', 'sse', 'ssf', 'ssg', 'ssh', 'ssi', 'ssj', 'ssk', 'ssl', 'ssm', 'ssn', 'sso', 'ssp', 'ssq', 'ssr', 'sss', 'sst', 'ssu', 'ssv', 'ssx', 'ssy', 'ssz', 'sta', 'stb', 'std', 'ste', 'stf', 'stg', 'sth', 'sti', 'stj', 'stk', 'stl', 'stm', 'stn', 'sto', 'stp', 'stq', 'str', 'sts', 'stt', 'stu', 'stv', 'stw', 'sty', 'sua', 'sub', 'suc', 'sue', 'sug', 'sui', 'suj', 'suk', 'sul', 'sum', 'suq', 'sur', 'sus', 'sut', 'suv', 'suw', 'sux', 'suy', 'suz', 'sva', 'svb', 'svc', 'sve', 'svk', 'svm', 'svr', 'svs', 'svx', 'swb', 'swc', 'swf', 'swg', 'swh', 'swi', 'swj', 'swk', 'swl', 'swm', 'swn', 'swo', 'swp', 'swq', 'swr', 'sws', 'swt', 'swu', 'swv', 'sww', 'swx', 'swy', 'sxb', 'sxc', 'sxe', 'sxg', 'sxk', 'sxl', 'sxm', 'sxn', 'sxo', 'sxr', 'sxs', 'sxu', 'sxw', 'sya', 'syb', 'syc', 'syd', 'syi', 'syk', 'syl', 'sym', 'syn', 'syo', 'syr', 'sys', 'syw', 'syx', 'syy', 'sza', 'szb', 'szc', 'szd', 'sze', 'szg', 'szl', 'szn', 'szp', 'szs', 'szv', 'szw', 'taa', 'tab', 'tac', 'tad', 'tae', 'taf', 'tag', 'tai', 'taj', 'tak', 'tal', 'tan', 'tao', 'tap', 'taq', 'tar', 'tas', 'tau', 'tav', 'taw', 'tax', 'tay', 'taz', 'tba', 'tbb', 'tbc', 'tbd', 'tbe', 'tbf', 'tbg', 'tbh', 'tbi', 'tbj', 'tbk', 'tbl', 'tbm', 'tbn', 'tbo', 'tbp', 'tbq', 'tbr', 'tbs', 'tbt', 'tbu', 'tbv', 'tbw', 'tbx', 'tby', 'tbz', 'tca', 'tcb', 'tcc', 'tcd', 'tce', 'tcf', 'tcg', 'tch', 'tci', 'tck', 'tcl', 'tcm', 'tcn', 'tco', 'tcp', 'tcq', 'tcs', 'tct', 'tcu', 'tcw', 'tcx', 'tcy', 'tcz', 'tda', 'tdb', 'tdc', 'tdd', 'tde', 'tdf', 'tdg', 'tdh', 'tdi', 'tdj', 'tdk', 'tdl', 'tdm', 'tdn', 'tdo', 'tdq', 'tdr', 'tds', 'tdt', 'tdu', 'tdv', 'tdx', 'tdy', 'tea', 'teb', 'tec', 'ted', 'tee', 'tef', 'teg', 'teh', 'tei', 'tek', 'tem', 'ten', 'teo', 'tep', 'teq', 'ter', 'tes', 'tet', 'teu', 'tev', 'tew', 'tex', 'tey', 'tfi', 'tfn', 'tfo', 'tfr', 'tft', 'tga', 'tgb', 'tgc', 'tgd', 'tge', 'tgf', 'tgg', 'tgh', 'tgi', 'tgj', 'tgn', 'tgo', 'tgp', 'tgq', 'tgr', 'tgs', 'tgt', 'tgu', 'tgv', 'tgw', 'tgx', 'tgy', 'tgz', 'thc', 'thd', 'the', 'thf', 'thh', 'thi', 'thk', 'thl', 'thm', 'thn', 'thp', 'thq', 'thr', 'ths', 'tht', 'thu', 'thv', 'thw', 'thx', 'thy', 'thz', 'tia', 'tic', 'tid', 'tie', 'tif', 'tig', 'tih', 'tii', 'tij', 'tik', 'til', 'tim', 'tin', 'tio', 'tip', 'tiq', 'tis', 'tit', 'tiu', 'tiv', 'tiw', 'tix', 'tiy', 'tiz', 'tja', 'tjg', 'tji', 'tjl', 'tjm', 'tjn', 'tjo', 'tjs', 'tju', 'tjw', 'tka', 'tkb', 'tkd', 'tke', 'tkf', 'tkg', 'tkk', 'tkl', 'tkm', 'tkn', 'tkp', 'tkq', 'tkr', 'tks', 'tkt', 'tku', 'tkv', 'tkw', 'tkx', 'tkz', 'tla', 'tlb', 'tlc', 'tld', 'tlf', 'tlg', 'tlh', 'tli', 'tlj', 'tlk', 'tll', 'tlm', 'tln', 'tlo', 'tlp', 'tlq', 'tlr', 'tls', 'tlt', 'tlu', 'tlv', 'tlw', 'tlx', 'tly', 'tma', 'tmb', 'tmc', 'tmd', 'tme', 'tmf', 'tmg', 'tmh', 'tmi', 'tmj', 'tmk', 'tml', 'tmm', 'tmn', 'tmo', 'tmp', 'tmq', 'tmr', 'tms', 'tmt', 'tmu', 'tmv', 'tmw', 'tmy', 'tmz', 'tna', 'tnb', 'tnc', 'tnd', 'tne', 'tnf', 'tng', 'tnh', 'tni', 'tnk', 'tnl', 'tnm', 'tnn', 'tno', 'tnp', 'tnq', 'tnr', 'tns', 'tnt', 'tnu', 'tnv', 'tnw', 'tnx', 'tny', 'tnz', 'tob', 'toc', 'tod', 'toe', 'tof', 'tog', 'toh', 'toi', 'toj', 'tol', 'tom', 'too', 'top', 'toq', 'tor', 'tos', 'tou', 'tov', 'tow', 'tox', 'toy', 'toz', 'tpa', 'tpc', 'tpe', 'tpf', 'tpg', 'tpi', 'tpj', 'tpk', 'tpl', 'tpm', 'tpn', 'tpo', 'tpp', 'tpq', 'tpr', 'tpt', 'tpu', 'tpv', 'tpw', 'tpx', 'tpy', 'tpz', 'tqb', 'tql', 'tqm', 'tqn', 'tqo', 'tqp', 'tqq', 'tqr', 'tqt', 'tqu', 'tqw', 'tra', 'trb', 'trc', 'trd', 'tre', 'trf', 'trg', 'trh', 'tri', 'trj', 'trk', 'trl', 'trm', 'trn', 'tro', 'trp', 'trq', 'trr', 'trs', 'trt', 'tru', 'trv', 'trw', 'trx', 'try', 'trz', 'tsa', 'tsb', 'tsc', 'tsd', 'tse', 'tsf', 'tsg', 'tsh', 'tsi', 'tsj', 'tsk', 'tsl', 'tsm', 'tsp', 'tsq', 'tsr', 'tss', 'tst', 'tsu', 'tsv', 'tsw', 'tsx', 'tsy', 'tsz', 'tta', 'ttb', 'ttc', 'ttd', 'tte', 'ttf', 'ttg', 'tth', 'tti', 'ttj', 'ttk', 'ttl', 'ttm', 'ttn', 'tto', 'ttp', 'ttq', 'ttr', 'tts', 'ttt', 'ttu', 'ttv', 'ttw', 'tty', 'ttz', 'tua', 'tub', 'tuc', 'tud', 'tue', 'tuf', 'tug', 'tuh', 'tui', 'tuj', 'tul', 'tum', 'tun', 'tuo', 'tup', 'tuq', 'tus', 'tut', 'tuu', 'tuv', 'tuw', 'tux', 'tuy', 'tuz', 'tva', 'tvd', 'tve', 'tvk', 'tvl', 'tvm', 'tvn', 'tvo', 'tvs', 'tvt', 'tvu', 'tvw', 'tvy', 'twa', 'twb', 'twc', 'twd', 'twe', 'twf', 'twg', 'twh', 'twl', 'twm', 'twn', 'two', 'twp', 'twq', 'twr', 'twt', 'twu', 'tww', 'twx', 'twy', 'txa', 'txb', 'txc', 'txe', 'txg', 'txh', 'txi', 'txj', 'txm', 'txn', 'txo', 'txq', 'txr', 'txs', 'txt', 'txu', 'txx', 'txy', 'tya', 'tye', 'tyh', 'tyi', 'tyj', 'tyl', 'tyn', 'typ', 'tyr', 'tys', 'tyt', 'tyu', 'tyv', 'tyx', 'tyz', 'tza', 'tzh', 'tzj', 'tzl', 'tzm', 'tzn', 'tzo', 'tzx', 'uam', 'uan', 'uar', 'uba', 'ubi', 'ubl', 'ubr', 'ubu', 'uby', 'uda', 'ude', 'udg', 'udi', 'udj', 'udl', 'udm', 'udu', 'ues', 'ufi', 'uga', 'ugb', 'uge', 'ugn', 'ugo', 'ugy', 'uha', 'uhn', 'uis', 'uiv', 'uji', 'uka', 'ukg', 'ukh', 'ukk', 'ukl', 'ukp', 'ukq', 'uks', 'uku', 'ukw', 'uky', 'ula', 'ulb', 'ulc', 'ule', 'ulf', 'uli', 'ulk', 'ull', 'ulm', 'uln', 'ulu', 'ulw', 'uma', 'umb', 'umc', 'umd', 'umg', 'umi', 'umm', 'umn', 'umo', 'ump', 'umr', 'ums', 'umu', 'una', 'und', 'une', 'ung', 'unk', 'unm', 'unn', 'unp', 'unr', 'unu', 'unx', 'unz', 'uok', 'upi', 'upv', 'ura', 'urb', 'urc', 'ure', 'urf', 'urg', 'urh', 'uri', 'urj', 'urk', 'url', 'urm', 'urn', 'uro', 'urp', 'urr', 'urt', 'uru', 'urv', 'urw', 'urx', 'ury', 'urz', 'usa', 'ush', 'usi', 'usk', 'usp', 'usu', 'uta', 'ute', 'utp', 'utr', 'utu', 'uum', 'uun', 'uur', 'uuu', 'uve', 'uvh', 'uvl', 'uwa', 'uya', 'uzn', 'uzs', 'vaa', 'vae', 'vaf', 'vag', 'vah', 'vai', 'vaj', 'val', 'vam', 'van', 'vao', 'vap', 'var', 'vas', 'vau', 'vav', 'vay', 'vbb', 'vbk', 'vec', 'ved', 'vel', 'vem', 'veo', 'vep', 'ver', 'vgr', 'vgt', 'vic', 'vid', 'vif', 'vig', 'vil', 'vin', 'vis', 'vit', 'viv', 'vka', 'vki', 'vkj', 'vkk', 'vkl', 'vkm', 'vko', 'vkp', 'vkt', 'vku', 'vlp', 'vls', 'vma', 'vmb', 'vmc', 'vmd', 'vme', 'vmf', 'vmg', 'vmh', 'vmi', 'vmj', 'vmk', 'vml', 'vmm', 'vmp', 'vmq', 'vmr', 'vms', 'vmu', 'vmv', 'vmw', 'vmx', 'vmy', 'vmz', 'vnk', 'vnm', 'vnp', 'vor', 'vot', 'vra', 'vro', 'vrs', 'vrt', 'vsi', 'vsl', 'vsv', 'vto', 'vum', 'vun', 'vut', 'vwa', 'waa', 'wab', 'wac', 'wad', 'wae', 'waf', 'wag', 'wah', 'wai', 'waj', 'wak', 'wal', 'wam', 'wan', 'wao', 'wap', 'waq', 'war', 'was', 'wat', 'wau', 'wav', 'waw', 'wax', 'way', 'waz', 'wba', 'wbb', 'wbe', 'wbf', 'wbh', 'wbi', 'wbj', 'wbk', 'wbl', 'wbm', 'wbp', 'wbq', 'wbr', 'wbs', 'wbt', 'wbv', 'wbw', 'wca', 'wci', 'wdd', 'wdg', 'wdj', 'wdk', 'wdu', 'wdy', 'wea', 'wec', 'wed', 'weg', 'weh', 'wei', 'wem', 'wen', 'weo', 'wep', 'wer', 'wes', 'wet', 'weu', 'wew', 'wfg', 'wga', 'wgb', 'wgg', 'wgi', 'wgo', 'wgu', 'wgw', 'wgy', 'wha', 'whg', 'whk', 'whu', 'wib', 'wic', 'wie', 'wif', 'wig', 'wih', 'wii', 'wij', 'wik', 'wil', 'wim', 'win', 'wir', 'wit', 'wiu', 'wiv', 'wiw', 'wiy', 'wja', 'wji', 'wka', 'wkb', 'wkd', 'wkl', 'wku', 'wkw', 'wky', 'wla', 'wlc', 'wle', 'wlg', 'wli', 'wlk', 'wll', 'wlm', 'wlo', 'wlr', 'wls', 'wlu', 'wlv', 'wlw', 'wlx', 'wly', 'wma', 'wmb', 'wmc', 'wmd', 'wme', 'wmh', 'wmi', 'wmm', 'wmn', 'wmo', 'wms', 'wmt', 'wmw', 'wmx', 'wnb', 'wnc', 'wnd', 'wne', 'wng', 'wni', 'wnk', 'wnm', 'wnn', 'wno', 'wnp', 'wnu', 'wnw', 'wny', 'woa', 'wob', 'woc', 'wod', 'woe', 'wof', 'wog', 'woi', 'wok', 'wom', 'won', 'woo', 'wor', 'wos', 'wow', 'woy', 'wpc', 'wra', 'wrb', 'wrd', 'wrg', 'wrh', 'wri', 'wrk', 'wrl', 'wrm', 'wrn', 'wro', 'wrp', 'wrr', 'wrs', 'wru', 'wrv', 'wrw', 'wrx', 'wry', 'wrz', 'wsa', 'wsg', 'wsi', 'wsk', 'wsr', 'wss', 'wsu', 'wsv', 'wtf', 'wth', 'wti', 'wtk', 'wtm', 'wtw', 'wua', 'wub', 'wud', 'wuh', 'wul', 'wum', 'wun', 'wur', 'wut', 'wuu', 'wuv', 'wux', 'wuy', 'wwa', 'wwb', 'wwo', 'wwr', 'www', 'wxa', 'wxw', 'wya', 'wyb', 'wyi', 'wym', 'wyr', 'wyy', 'xaa', 'xab', 'xac', 'xad', 'xae', 'xag', 'xai', 'xaj', 'xak', 'xal', 'xam', 'xan', 'xao', 'xap', 'xaq', 'xar', 'xas', 'xat', 'xau', 'xav', 'xaw', 'xay', 'xba', 'xbb', 'xbc', 'xbd', 'xbe', 'xbg', 'xbi', 'xbj', 'xbm', 'xbn', 'xbo', 'xbp', 'xbr', 'xbw', 'xbx', 'xby', 'xcb', 'xcc', 'xce', 'xcg', 'xch', 'xcl', 'xcm', 'xcn', 'xco', 'xcr', 'xct', 'xcu', 'xcv', 'xcw', 'xcy', 'xda', 'xdc', 'xdk', 'xdm', 'xdo', 'xdy', 'xeb', 'xed', 'xeg', 'xel', 'xem', 'xep', 'xer', 'xes', 'xet', 'xeu', 'xfa', 'xga', 'xgb', 'xgd', 'xgf', 'xgg', 'xgi', 'xgl', 'xgm', 'xgn', 'xgr', 'xgu', 'xgw', 'xha', 'xhc', 'xhd', 'xhe', 'xhr', 'xht', 'xhu', 'xhv', 'xia', 'xib', 'xii', 'xil', 'xin', 'xip', 'xir', 'xis', 'xiv', 'xiy', 'xjb', 'xjt', 'xka', 'xkb', 'xkc', 'xkd', 'xke', 'xkf', 'xkg', 'xkh', 'xki', 'xkj', 'xkk', 'xkl', 'xkn', 'xko', 'xkp', 'xkq', 'xkr', 'xks', 'xkt', 'xku', 'xkv', 'xkw', 'xkx', 'xky', 'xkz', 'xla', 'xlb', 'xlc', 'xld', 'xle', 'xlg', 'xli', 'xln', 'xlo', 'xlp', 'xls', 'xlu', 'xly', 'xma', 'xmb', 'xmc', 'xmd', 'xme', 'xmf', 'xmg', 'xmh', 'xmj', 'xmk', 'xml', 'xmm', 'xmn', 'xmo', 'xmp', 'xmq', 'xmr', 'xms', 'xmt', 'xmu', 'xmv', 'xmw', 'xmx', 'xmy', 'xmz', 'xna', 'xnb', 'xnd', 'xng', 'xnh', 'xni', 'xnk', 'xnn', 'xno', 'xnr', 'xns', 'xnt', 'xnu', 'xny', 'xnz', 'xoc', 'xod', 'xog', 'xoi', 'xok', 'xom', 'xon', 'xoo', 'xop', 'xor', 'xow', 'xpa', 'xpc', 'xpe', 'xpg', 'xpi', 'xpj', 'xpk', 'xpm', 'xpn', 'xpo', 'xpp', 'xpq', 'xpr', 'xps', 'xpt', 'xpu', 'xpy', 'xqa', 'xqt', 'xra', 'xrb', 'xrd', 'xre', 'xrg', 'xri', 'xrm', 'xrn', 'xrq', 'xrr', 'xrt', 'xru', 'xrw', 'xsa', 'xsb', 'xsc', 'xsd', 'xse', 'xsh', 'xsi', 'xsj', 'xsl', 'xsm', 'xsn', 'xso', 'xsp', 'xsq', 'xsr', 'xss', 'xsu', 'xsv', 'xsy', 'xta', 'xtb', 'xtc', 'xtd', 'xte', 'xtg', 'xth', 'xti', 'xtj', 'xtl', 'xtm', 'xtn', 'xto', 'xtp', 'xtq', 'xtr', 'xts', 'xtt', 'xtu', 'xtv', 'xtw', 'xty', 'xtz', 'xua', 'xub', 'xud', 'xug', 'xuj', 'xul', 'xum', 'xun', 'xuo', 'xup', 'xur', 'xut', 'xuu', 'xve', 'xvi', 'xvn', 'xvo', 'xvs', 'xwa', 'xwc', 'xwd', 'xwe', 'xwg', 'xwj', 'xwk', 'xwl', 'xwo', 'xwr', 'xwt', 'xww', 'xxb', 'xxk', 'xxm', 'xxr', 'xxt', 'xya', 'xyb', 'xyj', 'xyk', 'xyl', 'xyt', 'xyy', 'xzh', 'xzm', 'xzp', 'yaa', 'yab', 'yac', 'yad', 'yae', 'yaf', 'yag', 'yah', 'yai', 'yaj', 'yak', 'yal', 'yam', 'yan', 'yao', 'yap', 'yaq', 'yar', 'yas', 'yat', 'yau', 'yav', 'yaw', 'yax', 'yay', 'yaz', 'yba', 'ybb', 'ybd', 'ybe', 'ybh', 'ybi', 'ybj', 'ybk', 'ybl', 'ybm', 'ybn', 'ybo', 'ybx', 'yby', 'ych', 'ycl', 'ycn', 'ycp', 'yda', 'ydd', 'yde', 'ydg', 'ydk', 'yds', 'yea', 'yec', 'yee', 'yei', 'yej', 'yel', 'yen', 'yer', 'yes', 'yet', 'yeu', 'yev', 'yey', 'yga', 'ygi', 'ygl', 'ygm', 'ygp', 'ygr', 'ygs', 'ygu', 'ygw', 'yha', 'yhd', 'yhl', 'yhs', 'yia', 'yif', 'yig', 'yih', 'yii', 'yij', 'yik', 'yil', 'yim', 'yin', 'yip', 'yiq', 'yir', 'yis', 'yit', 'yiu', 'yiv', 'yix', 'yiy', 'yiz', 'yka', 'ykg', 'yki', 'ykk', 'ykl', 'ykm', 'ykn', 'yko', 'ykr', 'ykt', 'yku', 'yky', 'yla', 'ylb', 'yle', 'ylg', 'yli', 'yll', 'ylm', 'yln', 'ylo', 'ylr', 'ylu', 'yly', 'yma', 'ymb', 'ymc', 'ymd', 'yme', 'ymg', 'ymh', 'ymi', 'ymk', 'yml', 'ymm', 'ymn', 'ymo', 'ymp', 'ymq', 'ymr', 'yms', 'ymt', 'ymx', 'ymz', 'yna', 'ynd', 'yne', 'yng', 'ynh', 'ynk', 'ynl', 'ynn', 'yno', 'ynq', 'yns', 'ynu', 'yob', 'yog', 'yoi', 'yok', 'yol', 'yom', 'yon', 'yos', 'yot', 'yox', 'yoy', 'ypa', 'ypb', 'ypg', 'yph', 'ypk', 'ypm', 'ypn', 'ypo', 'ypp', 'ypz', 'yra', 'yrb', 'yre', 'yri', 'yrk', 'yrl', 'yrm', 'yrn', 'yro', 'yrs', 'yrw', 'yry', 'ysc', 'ysd', 'ysg', 'ysl', 'ysn', 'yso', 'ysp', 'ysr', 'yss', 'ysy', 'yta', 'ytl', 'ytp', 'ytw', 'yty', 'yua', 'yub', 'yuc', 'yud', 'yue', 'yuf', 'yug', 'yui', 'yuj', 'yuk', 'yul', 'yum', 'yun', 'yup', 'yuq', 'yur', 'yut', 'yuu', 'yuw', 'yux', 'yuy', 'yuz', 'yva', 'yvt', 'ywa', 'ywg', 'ywl', 'ywn', 'ywq', 'ywr', 'ywt', 'ywu', 'yww', 'yxa', 'yxg', 'yxl', 'yxm', 'yxu', 'yxy', 'yyr', 'yyu', 'yyz', 'yzg', 'yzk', 'zaa', 'zab', 'zac', 'zad', 'zae', 'zaf', 'zag', 'zah', 'zai', 'zaj', 'zak', 'zal', 'zam', 'zao', 'zap', 'zaq', 'zar', 'zas', 'zat', 'zau', 'zav', 'zaw', 'zax', 'zay', 'zaz', 'zbc', 'zbe', 'zbl', 'zbt', 'zbw', 'zca', 'zch', 'zdj', 'zea', 'zeg', 'zeh', 'zen', 'zga', 'zgb', 'zgh', 'zgm', 'zgn', 'zgr', 'zhb', 'zhd', 'zhi', 'zhn', 'zhw', 'zhx', 'zia', 'zib', 'zik', 'zil', 'zim', 'zin', 'zir', 'ziw', 'ziz', 'zka', 'zkb', 'zkd', 'zkg', 'zkh', 'zkk', 'zkn', 'zko', 'zkp', 'zkr', 'zkt', 'zku', 'zkv', 'zkz', 'zle', 'zlj', 'zlm', 'zln', 'zlq', 'zls', 'zlw', 'zma', 'zmb', 'zmc', 'zmd', 'zme', 'zmf', 'zmg', 'zmh', 'zmi', 'zmj', 'zmk', 'zml', 'zmm', 'zmn', 'zmo', 'zmp', 'zmq', 'zmr', 'zms', 'zmt', 'zmu', 'zmv', 'zmw', 'zmx', 'zmy', 'zmz', 'zna', 'znd', 'zne', 'zng', 'znk', 'zns', 'zoc', 'zoh', 'zom', 'zoo', 'zoq', 'zor', 'zos', 'zpa', 'zpb', 'zpc', 'zpd', 'zpe', 'zpf', 'zpg', 'zph', 'zpi', 'zpj', 'zpk', 'zpl', 'zpm', 'zpn', 'zpo', 'zpp', 'zpq', 'zpr', 'zps', 'zpt', 'zpu', 'zpv', 'zpw', 'zpx', 'zpy', 'zpz', 'zqe', 'zra', 'zrg', 'zrn', 'zro', 'zrp', 'zrs', 'zsa', 'zsk', 'zsl', 'zsm', 'zsr', 'zsu', 'zte', 'ztg', 'ztl', 'ztm', 'ztn', 'ztp', 'ztq', 'zts', 'ztt', 'ztu', 'ztx', 'zty', 'zua', 'zuh', 'zum', 'zun', 'zuy', 'zwa', 'zxx', 'zyb', 'zyg', 'zyj', 'zyn', 'zyp', 'zza', 'zzj' ];
-      axe.utils.validLangs = function() {
-        'use strict';
-        return langs;
+      text.visible = function(element, screenReader, noRecursing) {
+        element = axe.utils.getNodeFromTree(element);
+        return text.visibleVirtual(element, screenReader, noRecursing);
       };
       return commons;
     }()
diff --git a/third_party/axe-core/axe.min.js b/third_party/axe-core/axe.min.js
index a06be242..91b00bf 100644
--- a/third_party/axe-core/axe.min.js
+++ b/third_party/axe-core/axe.min.js
@@ -1,5 +1,5 @@
-/*! aXe v3.0.0-alpha-1
- * Copyright (c) 2017 Deque Systems, Inc.
+/*! axe v3.3.2
+ * Copyright (c) 2019 Deque Systems, Inc.
  *
  * Your use of this Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -9,34 +9,4 @@
  * distribute or in any file that contains substantial portions of this source
  * code.
  */
-!function a(window){function b(a){this.name="SupportError",this.cause=a.cause,this.message="`"+a.cause+"` - feature unsupported in your environment.",a.ruleId&&(this.ruleId=a.ruleId,this.message+=" Skipping "+this.ruleId+" rule."),this.stack=(new Error).stack}function c(a){"use strict";var b;return a?(b=axe.utils.clone(a),b.commons=a.commons):b={},b.reporter=b.reporter||null,b.rules=b.rules||[],b.checks=b.checks||[],b.data=Object.assign({checks:{},rules:{}},b.data),b}function d(a,b,c){"use strict";var d,e;for(d=0,e=a.length;d<e;d++)b[c](a[d])}function e(a){this.brand="axe",this.application="axeAPI",this.tagExclude=["experimental"],this.defaultConfig=a,this._init()}function f(a,b,c){var d=a.brand,e=a.application;return axe.constants.helpUrlBase+d+"/"+(c||axe.version.substring(0,axe.version.lastIndexOf(".")))+"/"+b+"?application="+e}function g(a){"use strict";this.id=a.id,this.data=null,this.relatedNodes=[],this.result=null}function h(a){"use strict";return"string"==typeof a?new Function("return "+a+";")():a}function i(a){a&&(this.id=a.id,this.configure(a))}function j(a,b){"use strict";if(!axe.utils.isHidden(b)){axe.utils.findBy(a,"node",b)||a.push({node:b,include:[],exclude:[]})}}function k(a,b,c){"use strict";a.frames=a.frames||[];var d,e,f=document.querySelectorAll(c.shift());a:for(var g=0,h=f.length;g<h;g++){e=f[g];for(var i=0,j=a.frames.length;i<j;i++)if(a.frames[i].node===e){a.frames[i][b].push(c);break a}d={node:e,include:[],exclude:[]},c&&d[b].push(c),a.frames.push(d)}}function l(a){"use strict";if(a&&"object"===(void 0===a?"undefined":ta(a))||a instanceof NodeList){if(a instanceof Node)return{include:[a],exclude:[]};if(a.hasOwnProperty("include")||a.hasOwnProperty("exclude"))return{include:a.include&&+a.include.length?a.include:[document],exclude:a.exclude||[]};if(a.length===+a.length)return{include:a,exclude:[]}}return"string"==typeof a?{include:[a],exclude:[]}:{include:[document],exclude:[]}}function m(a,b){"use strict";for(var c,d,e=[],f=0,g=a[b].length;f<g;f++){if("string"==typeof(c=a[b][f])){d=Array.from(document.querySelectorAll(c)),e=e.concat(d.map(function(a){return axe.utils.getFlattenedTree(a)[0]}));break}!c||!c.length||c instanceof Node?c instanceof Node&&e.push(axe.utils.getFlattenedTree(c)[0]):c.length>1?k(a,b,c):(d=Array.from(document.querySelectorAll(c[0])),e=e.concat(d.map(function(a){return axe.utils.getFlattenedTree(a)[0]})))}return e.filter(function(a){return a})}function n(a){"use strict";if(0===a.include.length){if(0===a.frames.length){var b=axe.utils.respondable.isInFrame()?"frame":"page";return new Error("No elements found for include in "+b+" Context")}a.frames.forEach(function(a,b){if(0===a.include.length)return new Error("No elements found for include in Context of frame "+b)})}}function o(a){"use strict";var b=this;this.frames=[],this.initiator=!a||"boolean"!=typeof a.initiator||a.initiator,this.page=!1,a=l(a),this.exclude=a.exclude,this.include=a.include,this.include=m(this,"include"),this.exclude=m(this,"exclude"),axe.utils.select("frame, iframe",this).forEach(function(a){ra(a,b)&&j(b.frames,a.actualNode)}),1===this.include.length&&this.include[0].actualNode===document.documentElement&&(this.page=!0);var c=n(this);if(c instanceof Error)throw c}function p(a){"use strict";this.id=a.id,this.result=axe.constants.NA,this.pageLevel=a.pageLevel,this.impact=null,this.nodes=[]}function q(a,b){"use strict";this._audit=b,this.id=a.id,this.selector=a.selector||"*",this.excludeHidden="boolean"!=typeof a.excludeHidden||a.excludeHidden,this.enabled="boolean"!=typeof a.enabled||a.enabled,this.pageLevel="boolean"==typeof a.pageLevel&&a.pageLevel,this.any=a.any||[],this.all=a.all||[],this.none=a.none||[],this.tags=a.tags||[],a.matches&&(this.matches=h(a.matches))}function r(a){"use strict";return axe.utils.getAllChecks(a).map(function(b){var c=a._audit.checks[b.id||b];return c&&"function"==typeof c.after?c:null}).filter(Boolean)}function s(a,b){"use strict";var c=[];return a.forEach(function(a){axe.utils.getAllChecks(a).forEach(function(a){a.id===b&&c.push(a)})}),c}function t(a){"use strict";return a.filter(function(a){return!0!==a.filtered})}function u(a){"use strict";var b=["any","all","none"],c=a.nodes.filter(function(a){var c=0;return b.forEach(function(b){a[b]=t(a[b]),c+=a[b].length}),c>0});return a.pageLevel&&c.length&&(c=[c.reduce(function(a,c){if(a)return b.forEach(function(b){a[b].push.apply(a[b],c[b])}),a})]),c}function v(a,b){"use strict";if(!axe._audit)throw new Error("No audit configured");var c=axe.utils.queue(),d=[];Object.keys(axe.plugins).forEach(function(a){c.defer(function(b){var c=function(a){d.push(a),b()};try{axe.plugins[a].cleanup(b,c)}catch(a){c(a)}})}),axe.utils.toArray(document.querySelectorAll("frame, iframe")).forEach(function(a){c.defer(function(b,c){return axe.utils.sendCommandToFrame(a,{command:"cleanup-plugin"},b,c)})}),c.then(function(c){0===d.length?a(c):b(d)}).catch(b)}function w(a){"use strict";var b;if(!(b=axe._audit))throw new Error("No audit configured");a.reporter&&("function"==typeof a.reporter||wa[a.reporter])&&(b.reporter=a.reporter),a.checks&&a.checks.forEach(function(a){b.addCheck(a)}),a.rules&&a.rules.forEach(function(a){b.addRule(a)}),void 0!==a.branding?b.setBranding(a.branding):b._constructHelpUrls(),a.tagExclude&&(b.tagExclude=a.tagExclude)}function x(a,b,c){"use strict";var d=c,e=function(a){a instanceof Error==!1&&(a=new Error(a)),c(a)},f=a&&a.context||{};f.include&&!f.include.length&&(f.include=[document]);var g=a&&a.options||{};switch(a.command){case"rules":return A(f,g,d,e);case"cleanup-plugin":return v(d,e);default:if(axe._audit&&axe._audit.commands&&axe._audit.commands[a.command])return axe._audit.commands[a.command](a,c)}}function y(a){"use strict";this._run=a.run,this._collect=a.collect,this._registry={},a.commands.forEach(function(a){axe._audit.registerCommand(a)})}function z(){"use strict";var a=axe._audit;if(!a)throw new Error("No audit configured");a.resetRulesAndChecks()}function A(a,b,c,d){"use strict";try{a=new o(a)}catch(a){return d(a)}var e=axe.utils.queue(),f=axe._audit;b.performanceTimer&&axe.utils.performanceTimer.auditStart(),a.frames.length&&!1!==b.iframes&&e.defer(function(c,d){axe.utils.collectResultsFromFrames(a,b,"rules",null,c,d)}),e.defer(function(c,d){if(b.restoreScroll){var e=axe.utils.getScrollState();f.run(a,b,c,d),axe.utils.setScrollState(e)}else f.run(a,b,c,d)}),e.then(function(e){try{b.performanceTimer&&axe.utils.performanceTimer.auditEnd();var g=axe.utils.mergeResults(e.map(function(a){return{results:a}}));a.initiator&&(g=f.after(g,b),g.forEach(axe.utils.publishMetaData),g=g.map(axe.utils.finalizeRuleResult));try{c(g)}catch(a){axe.log(a)}}catch(a){d(a)}}).catch(d)}function B(a){"use strict";switch(!0){case"string"==typeof a:case Array.isArray(a):case Node&&a instanceof Node:case NodeList&&a instanceof NodeList:return!0;case"object"!==(void 0===a?"undefined":ta(a)):return!1;case void 0!==a.include:case void 0!==a.exclude:case"number"==typeof a.length:return!0;default:return!1}}function C(a,b,c){"use strict";var d=new TypeError("axe.run arguments are invalid");if(!B(a)){if(void 0!==c)throw d;c=b,b=a,a=document}if("object"!==(void 0===b?"undefined":ta(b))){if(void 0!==c)throw d;c=b,b={}}if("function"!=typeof c&&void 0!==c)throw d;return{context:a,options:b,callback:c||xa}}function D(a,b){"use strict";["any","all","none"].forEach(function(c){Array.isArray(a[c])&&a[c].filter(function(a){return Array.isArray(a.relatedNodes)}).forEach(function(a){a.relatedNodes=a.relatedNodes.map(function(a){var c={html:a.source};return b.elementRef&&!a.fromFrame&&(c.element=a.element),(!1!==b.selectors||a.fromFrame)&&(c.target=a.selector),b.xpath&&(c.xpath=a.xpath),c})})})}function E(a,b){return Aa.reduce(function(c,d){return c[d]=(a[d]||[]).map(function(a){return b(a,d)}),c},{})}function F(a,b,c){var d=Object.assign({},b);d.nodes=(d[c]||[]).concat(),axe.constants.resultGroups.forEach(function(a){delete d[a]}),a[c].push(d)}function G(a,b,c){"use strict";var d=window.getComputedStyle(a,null),e=!1;return!!d&&(b.forEach(function(a){d.getPropertyValue(a.property)===a.value&&(e=!0)}),!!e||!(a.nodeName.toUpperCase()===c.toUpperCase()||!a.parentNode)&&G(a.parentNode,b,c))}function H(a,b){"use strict";return new Error(a+": "+axe.utils.getSelector(b))}function I(a,b,c,d,e,f){"use strict";var g=axe.utils.queue();a.frames.forEach(function(e){var f={options:b,command:c,parameter:d,context:{initiator:!1,page:a.page,include:e.include||[],exclude:e.exclude||[]}};g.defer(function(a,b){var c=e.node;axe.utils.sendCommandToFrame(c,f,function(b){if(b)return a({results:b,frameElement:c,frame:axe.utils.getSelector(c)});a(null)},b)})}),g.then(function(a){e(axe.utils.mergeResults(a,b))}).catch(f)}function J(a,b){if(b=b||300,a.length>b){var c=a.indexOf(">");a=a.substring(0,c+1)}return a}function K(a){var b=a.outerHTML;return b||"function"!=typeof XMLSerializer||(b=(new XMLSerializer).serializeToString(a)),J(b||"")}function L(a,b,c){this._fromFrame=!!c,this.spec=c||{},b&&b.absolutePaths&&(this._options={toRoot:!0}),this.source=void 0!==this.spec.source?this.spec.source:K(a),this._element=a}function M(a,b){return{shadowId:b,children:[],actualNode:a}}function N(a){var b=[];for(a=a.firstChild;a;)b.push(a),a=a.nextSibling;return b}function O(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"";return 0!==a.length&&(a.match(/[0-9]/g)||"").length>=a.length/2}function P(a,b){return[a.substring(0,b),a.substring(b)]}function Q(a){var b=a,c="",d="",e="",f="",g="",h="";if(a.includes("#")){var i=P(a,a.indexOf("#")),j=Ba(i,2);a=j[0],h=j[1]}if(a.includes("?")){var k=P(a,a.indexOf("?")),l=Ba(k,2);a=l[0],g=l[1]}if(a.includes("://")){var m=a.split("://"),n=Ba(m,2);c=n[0],a=n[1];var o=P(a,a.indexOf("/")),p=Ba(o,2);d=p[0],a=p[1]}else if("//"===a.substr(0,2)){a=a.substr(2);var q=P(a,a.indexOf("/")),r=Ba(q,2);d=r[0],a=r[1]}if("www."===d.substr(0,4)&&(d=d.substr(4)),d&&d.includes(":")){var s=P(d,d.indexOf(":")),t=Ba(s,2);d=t[0],e=t[1]}return f=a,{original:b,protocol:c,domain:d,port:e,path:f,query:g,hash:h}}function R(a){if(Array.isArray(a)){for(var b=0,c=Array(a.length);b<a.length;b++)c[b]=a[b];return c}return Array.from(a)}function S(a){return!["focus","hover","hidden","visible","dirty","touched","valid","disable","enable","active","col-"].find(function(b){return a.includes(b)})}function T(a){return a.classList&&0!==a.classList.length?(a.parentNode&&Array.from(a.parentNode.children||"")||[]).reduce(function(b,c){return a===c?b:b.filter(function(a){return!c.classList.contains(a)})},Array.from(a.classList).filter(S)):[]}function U(a,b){var c=a.parentNode&&Array.from(a.parentNode.children||"")||[];if(c.find(function(c){return c!==a&&axe.utils.matchesSelector(c,b)}))return":nth-child("+(1+c.indexOf(a))+")";return""}function V(a,b){var c=a.nodeName.toLowerCase(),d=Array.from(a.classList)||[],e={nodeName:c,classList:d,isCustomElm:c.includes("-"),isCommonElm:Da.includes(c),distinctClassList:T(a)};return[Ea.getCustomElm,Ea.getElmRoleProp,Ea.getUncommonElm,Ea.getElmNameProp,Ea.getDistinctClass,Ea.getFileRefProp,Ea.getCommonName].reduce(function(c,d){if(c.length===b)return c;var f=d(a,e);return f&&(f[0].match(/[a-z]/)?c.unshift(f):c.push(f)),c},[])}function W(a,b,c){var d=void 0,e=void 0,f=b.isUnique,g=void 0!==f&&f,h=Ea.getElmId(a),i=b.featureCount,j=void 0===i?2:i,k=b.minDepth,l=void 0===k?1:k,m=b.toRoot,n=void 0!==m&&m,o=b.childSelectors,p=void 0===o?[]:o;h?(d=h,g=!0):(d=V(a,j).join(""),d+=U(a,d),g=b.isUnique||1===c.querySelectorAll(d).length,g||a!==document.documentElement||(d+=":root"),e=0!==l||!g);var q=[d].concat(R(p));return a.parentElement&&11!==a.parentElement.nodeType&&(n||e)?W(a.parentNode,{toRoot:n,isUnique:g,childSelectors:q,featureCount:1,minDepth:l-1},c):q.join(" > ")}function X(a,b){var c,d;if(!a)return[];if(!b&&9===a.nodeType)return b=[{str:"html"}];if(b=b||[],a.parentNode&&a.parentNode!==a&&(b=X(a.parentNode,b)),a.previousSibling){d=1,c=a.previousSibling;do{1===c.nodeType&&c.nodeName===a.nodeName&&d++,c=c.previousSibling}while(c);1===d&&(d=null)}else if(a.nextSibling){c=a.nextSibling;do{1===c.nodeType&&c.nodeName===a.nodeName?(d=1,c=null):(d=null,c=c.previousSibling)}while(c)}if(1===a.nodeType){var e={};e.str=a.nodeName.toLowerCase();var f=a.getAttribute&&axe.utils.escapeSelector(a.getAttribute("id"));f&&1===a.ownerDocument.querySelectorAll("#"+f).length&&(e.id=a.getAttribute("id")),d>1&&(e.count=d),b.push(e)}return b}function Y(a){return a.reduce(function(a,b){return b.id?"/"+b.str+"[@id='"+b.id+"']":a+"/"+b.str+(b.count>0?"["+b.count+"]":"")},"")}function Z(a){"use strict";if(Fa&&Fa.parentNode)return void 0===Fa.styleSheet?Fa.appendChild(document.createTextNode(a)):Fa.styleSheet.cssText+=a,Fa;if(a){var b=document.head||document.getElementsByTagName("head")[0];return Fa=document.createElement("style"),Fa.type="text/css",void 0===Fa.styleSheet?Fa.appendChild(document.createTextNode(a)):Fa.styleSheet.cssText=a,b.appendChild(Fa),Fa}}function $(a,b,c,d){"use strict";var e=axe.utils.getXpath(c),f={element:c,selector:d,xpath:e};a.forEach(function(a){a.node=axe.utils.DqElement.fromFrame(a.node,b,f);var c=axe.utils.getAllChecks(a);c.length&&c.forEach(function(a){a.relatedNodes=a.relatedNodes.map(function(a){return axe.utils.DqElement.fromFrame(a,b,f)})})})}function _(a,b){"use strict";for(var c,d,e=b[0].node,f=0,g=a.length;f<g;f++)if(d=a[f].node,(c=axe.utils.nodeSorter({actualNode:d.element},{actualNode:e.element}))>0||0===c&&e.selector.length<d.selector.length)return void a.splice.apply(a,[f,0].concat(b));a.push.apply(a,b)}function aa(a){"use strict";return a&&a.results?Array.isArray(a.results)?a.results.length?a.results:null:[a.results]:null}function ba(a,b){function c(a){return a.incomplete&&a.incomplete.default?a.incomplete.default:ua.incompleteFallbackMessage()}if(!a||!a.missingData)return c(b);try{var d=b.incomplete[a.missingData[0].reason];if(!d)throw new Error;return d}catch(d){return"string"==typeof a.missingData?b.incomplete[a.missingData]:c(b)}}function ca(a,b){"use strict";return function(c){var d=a[c.id]||{},e=d.messages||{},f=Object.assign({},d);delete f.messages,void 0===c.result?"object"===ta(e.incomplete)?f.message=function(){return ba(c.data,e)}:f.message=e.incomplete:f.message=c.result===b?e.pass:e.fail,axe.utils.extendMetaData(c,f)}}function da(a,b){return 1===a.nodeType&&("*"===b.tag||a.nodeName.toLowerCase()===b.tag)}function ea(a,b){return!b.classes||b.classes.reduce(function(b,c){return b&&a.className&&a.className.match(c.regexp)},!0)}function fa(a,b){return!b.attributes||b.attributes.reduce(function(b,c){var d=a.getAttribute(c.key);return b&&null!==d&&(!c.value||c.test(d))},!0)}function ga(a,b){return!b.id||a.id===b.id}function ha(a,b){return!(b.pseudos&&!b.pseudos.reduce(function(b,c){if("not"===c.name)return b&&!Ha([a],c.expressions,!1).length;throw new Error("the pseudo selector "+c.name+" has not yet been implemented")},!0))}function ia(a,b,c){var d=[];return a=Array.isArray(a)?a:[a],a.forEach(function(a){da(a.actualNode,b)&&ea(a.actualNode,b)&&fa(a.actualNode,b)&&ga(a.actualNode,b)&&ha(a,b)&&d.push(a),c&&(d=d.concat(ia(a.children.filter(function(c){return!b.id||c.shadowId===a.shadowId}),b,c)))}),d}function ja(a){/*! Credit Mootools Copyright Mootools, MIT License */
-if(a)return a.map(function(a){var b,c,d=a.name.replace(Ja,""),e=(a.value||"").replace(Ja,"");switch(a.operator){case"^=":c=new RegExp("^"+Ia(e));break;case"$=":c=new RegExp(Ia(e)+"$");break;case"~=":c=new RegExp("(^|\\s)"+Ia(e)+"(\\s|$)");break;case"|=":c=new RegExp("^"+Ia(e)+"(-|$)");break;case"=":b=function(a){return e===a};break;case"*=":b=function(a){return a&&a.indexOf(e)>-1};break;case"!=":b=function(a){return e!==a};break;default:b=function(a){return!!a}}return""===e&&/^[*$^]=$/.test(a.operator)&&(b=function(){return!1}),b||(b=function(a){return a&&c.test(a)}),{key:d,value:e,test:b}})}function ka(a){if(a)return a.map(function(a){return a=a.replace(Ja,""),{value:a,regexp:new RegExp("(^|\\s)"+Ia(a)+"(\\s|$)")}})}function la(a){if(a)return a.map(function(a){var b;return"not"===a.name&&(b=axe.utils.cssParser.parse(a.value),b=b.selectors?b.selectors:[b],b=Ga(b)),{name:a.name,expressions:b,value:a.value}})}function ma(a,b){"use strict";var c,d,e=axe._audit&&axe._audit.tagExclude?axe._audit.tagExclude:[];return b.include||b.exclude?(c=b.include||[],c=Array.isArray(c)?c:[c],d=b.exclude||[],d=Array.isArray(d)?d:[d],d=d.concat(e.filter(function(a){return-1===c.indexOf(a)}))):(c=Array.isArray(b)?b:[b],d=e.filter(function(a){return-1===c.indexOf(a)})),!!(c.some(function(b){return-1!==a.tags.indexOf(b)})||0===c.length&&!1!==a.enabled)&&d.every(function(b){return-1===a.tags.indexOf(b)})}function na(a){var b=window.getComputedStyle(a),c="visible"===b.getPropertyValue("overflow-y"),d="visible"===b.getPropertyValue("overflow-x");if(!c&&a.scrollHeight>a.clientHeight||!d&&a.scrollWidth>a.clientWidth)return{elm:a,top:a.scrollTop,left:a.scrollLeft}}function oa(a,b,c){if(a===window)return a.scroll(b,c);a.scrollTop=b,a.scrollLeft=c}function pa(a){return Array.from(a.children).reduce(function(a,b){var c=na(b);return c&&a.push(c),a.concat(pa(b))},[])}function qa(a){"use strict";return a.sort(function(a,b){return axe.utils.contains(a,b)?1:-1})[0]}function ra(a,b){"use strict";var c=b.include&&qa(b.include.filter(function(b){return axe.utils.contains(b,a)})),d=b.exclude&&qa(b.exclude.filter(function(b){return axe.utils.contains(b,a)}));return!!(!d&&c||d&&axe.utils.contains(d,c))}function sa(a,b,c){"use strict";for(var d=0,e=b.length;d<e;d++)!a.find(function(a){return a.actualNode===b[d].actualNode})&&ra(b[d],c)&&a.push(b[d])}var document=window.document,ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},axe=axe||{};axe.version="3.0.0-alpha-1","function"==typeof define&&define.amd&&define([],function(){"use strict";return axe}),"object"===("undefined"==typeof module?"undefined":ta(module))&&module.exports&&"function"==typeof a.toString&&(axe.source="("+a.toString()+')(typeof window === "object" ? window : this);',module.exports=axe),"function"==typeof window.getComputedStyle&&(window.axe=axe);var commons;b.prototype=Object.create(Error.prototype),b.prototype.constructor=b;var utils=axe.utils={},ua={},ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};e.prototype._init=function(){var a=c(this.defaultConfig);axe.commons=commons=a.commons,this.reporter=a.reporter,this.commands={},this.rules=[],this.checks={},d(a.rules,this,"addRule"),d(a.checks,this,"addCheck"),this.data={},this.data.checks=a.data&&a.data.checks||{},this.data.rules=a.data&&a.data.rules||{},this.data.failureSummaries=a.data&&a.data.failureSummaries||{},this.data.incompleteFallbackMessage=a.data&&a.data.incompleteFallbackMessage||"",this._constructHelpUrls()},e.prototype.registerCommand=function(a){"use strict";this.commands[a.id]=a.callback},e.prototype.addRule=function(a){"use strict";a.metadata&&(this.data.rules[a.id]=a.metadata);var b=this.getRule(a.id);b?b.configure(a):this.rules.push(new q(a,this))},e.prototype.addCheck=function(a){"use strict";var b=a.metadata;"object"===(void 0===b?"undefined":ta(b))&&(this.data.checks[a.id]=b,"object"===ta(b.messages)&&Object.keys(b.messages).filter(function(a){return b.messages.hasOwnProperty(a)&&"string"==typeof b.messages[a]}).forEach(function(a){0===b.messages[a].indexOf("function")&&(b.messages[a]=new Function("return "+b.messages[a]+";")())})),this.checks[a.id]?this.checks[a.id].configure(a):this.checks[a.id]=new i(a)},e.prototype.run=function(a,b,c,d){"use strict";this.validateOptions(b),axe._tree=axe.utils.getFlattenedTree(document.documentElement);var e=axe.utils.queue();this.rules.forEach(function(c){if(axe.utils.ruleShouldRun(c,a,b)){if(b.performanceTimer){var d="mark_rule_end_"+c.id,f="mark_rule_start_"+c.id;axe.utils.performanceTimer.mark(f)}e.defer(function(e,g){c.run(a,b,function(a){b.performanceTimer&&(axe.utils.performanceTimer.mark(d),axe.utils.performanceTimer.measure("rule_"+c.id,f,d)),e(a)},function(a){if(b.debug)g(a);else{var d=Object.assign(new p(c),{result:axe.constants.CANTTELL,description:"An error occured while running this rule",message:a.message,stack:a.stack,error:a});e(d)}})})}}),e.then(function(a){axe._tree=void 0,c(a.filter(function(a){return!!a}))}).catch(d)},e.prototype.after=function(a,b){"use strict";var c=this.rules;return a.map(function(a){return axe.utils.findBy(c,"id",a.id).after(a,b)})},e.prototype.getRule=function(a){return this.rules.find(function(b){return b.id===a})},e.prototype.validateOptions=function(a){"use strict";var b=this;if("object"===ta(a.runOnly)){var c=a.runOnly;if("rule"===c.type&&Array.isArray(c.value))c.value.forEach(function(a){if(!b.getRule(a))throw new Error("unknown rule `"+a+"` in options.runOnly")});else if(Array.isArray(c.value)&&c.value.length>0){var d=[].concat(c.value);if(b.rules.forEach(function(a){var b,c,e;if(d)for(c=0,e=a.tags.length;c<e;c++)-1!==(b=d.indexOf(a.tags[c]))&&d.splice(b,1)}),0!==d.length)throw new Error("could not find tags `"+d.join("`, `")+"`")}}return"object"===ta(a.rules)&&Object.keys(a.rules).forEach(function(a){if(!b.getRule(a))throw new Error("unknown rule `"+a+"` in options.rules")}),a},e.prototype.setBranding=function(a){"use strict";var b={brand:this.brand,application:this.application};a&&a.hasOwnProperty("brand")&&a.brand&&"string"==typeof a.brand&&(this.brand=a.brand),a&&a.hasOwnProperty("application")&&a.application&&"string"==typeof a.application&&(this.application=a.application),this._constructHelpUrls(b)},e.prototype._constructHelpUrls=function(){var a=this,b=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,c=axe.version.substring(0,axe.version.lastIndexOf("."));this.rules.forEach(function(d){a.data.rules[d.id]||(a.data.rules[d.id]={});var e=a.data.rules[d.id];("string"!=typeof e.helpUrl||b&&e.helpUrl===f(b,d.id,c))&&(e.helpUrl=f(a,d.id,c))})},e.prototype.resetRulesAndChecks=function(){"use strict";this._init()},i.prototype.enabled=!0,i.prototype.run=function(a,b,c,d){"use strict";b=b||{};var e=b.hasOwnProperty("enabled")?b.enabled:this.enabled,f=b.options||this.options;if(e){var h,i=new g(this),j=axe.utils.checkHelper(i,b,c,d);try{h=this.evaluate.call(j,a.actualNode,f,a)}catch(a){return void d(a)}j.isAsync||(i.result=h,setTimeout(function(){c(i)},0))}else c(null)},i.prototype.configure=function(a){var b=this;["options","enabled"].filter(function(b){return a.hasOwnProperty(b)}).forEach(function(c){return b[c]=a[c]}),["evaluate","after"].filter(function(b){return a.hasOwnProperty(b)}).forEach(function(c){return b[c]=h(a[c])})};var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};q.prototype.matches=function(){"use strict";return!0},q.prototype.gather=function(a){"use strict";var b=axe.utils.select(this.selector,a);return this.excludeHidden?b.filter(function(a){return!axe.utils.isHidden(a.actualNode)}):b},q.prototype.runChecks=function(a,b,c,d,e){"use strict";var f=this,g=axe.utils.queue();this[a].forEach(function(a){var d=f._audit.checks[a.id||a],e=axe.utils.getCheckOption(d,f.id,c);g.defer(function(a,c){d.run(b,e,a,c)})}),g.then(function(b){b=b.filter(function(a){return a}),d({type:a,results:b})}).catch(e)},q.prototype.run=function(a,c,d,e){var f=this,g=axe.utils.queue(),h=new p(this),i=void 0;try{i=this.gather(a).filter(function(a){return f.matches(a.actualNode,a)})}catch(a){return void e(new b({cause:a,ruleId:this.id}))}c.performanceTimer&&axe.log("gather (",i.length,"):",axe.utils.performanceTimer.timeElapsed()+"ms"),i.forEach(function(a){g.defer(function(b,d){var e=axe.utils.queue();e.defer(function(b,d){f.runChecks("any",a,c,b,d)}),e.defer(function(b,d){f.runChecks("all",a,c,b,d)}),e.defer(function(b,d){f.runChecks("none",a,c,b,d)}),e.then(function(d){if(d.length){var e=!1,f={};d.forEach(function(a){var b=a.results.filter(function(a){return a});f[a.type]=b,b.length&&(e=!0)}),e&&(f.node=new axe.utils.DqElement(a.actualNode,c),h.nodes.push(f))}b()}).catch(function(a){return d(a)})})}),g.then(function(){return d(h)}).catch(function(a){return e(a)})},q.prototype.after=function(a,b){"use strict";var c=r(this),d=this.id;return c.forEach(function(c){var e=s(a.nodes,c.id),f=axe.utils.getCheckOption(c,d,b),g=c.after(e,f);e.forEach(function(a){-1===g.indexOf(a)&&(a.filtered=!0)})}),a.nodes=u(a),a},q.prototype.configure=function(a){"use strict";a.hasOwnProperty("selector")&&(this.selector=a.selector),a.hasOwnProperty("excludeHidden")&&(this.excludeHidden="boolean"!=typeof a.excludeHidden||a.excludeHidden),a.hasOwnProperty("enabled")&&(this.enabled="boolean"!=typeof a.enabled||a.enabled),a.hasOwnProperty("pageLevel")&&(this.pageLevel="boolean"==typeof a.pageLevel&&a.pageLevel),a.hasOwnProperty("any")&&(this.any=a.any),a.hasOwnProperty("all")&&(this.all=a.all),a.hasOwnProperty("none")&&(this.none=a.none),a.hasOwnProperty("tags")&&(this.tags=a.tags),a.hasOwnProperty("matches")&&("string"==typeof a.matches?this.matches=new Function("return "+a.matches+";")():this.matches=a.matches)},function(axe){var a=[{name:"NA",value:"inapplicable",priority:0,group:"inapplicable"},{name:"PASS",value:"passed",priority:1,group:"passes"},{name:"CANTTELL",value:"cantTell",priority:2,group:"incomplete"},{name:"FAIL",value:"failed",priority:3,group:"violations"}],b={helpUrlBase:"https://dequeuniversity.com/rules/",results:[],resultGroups:[],resultGroupMap:{},impact:Object.freeze(["minor","moderate","serious","critical"])};a.forEach(function(a){var c=a.name,d=a.value,e=a.priority,f=a.group;b[c]=d,b[c+"_PRIO"]=e,b[c+"_GROUP"]=f,b.results[e]=d,b.resultGroups[e]=f,b.resultGroupMap[d]=f}),Object.freeze(b.results),Object.freeze(b.resultGroups),Object.freeze(b.resultGroupMap),Object.freeze(b),Object.defineProperty(axe,"constants",{value:b,enumerable:!0,configurable:!1,writable:!1})}(axe);var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};axe.log=function(){"use strict";"object"===("undefined"==typeof console?"undefined":ta(console))&&console.log&&Function.prototype.apply.call(console.log,console,arguments)};var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};axe.a11yCheck=function(a,b,c){"use strict";"function"==typeof b&&(c=b,b={}),b&&"object"===(void 0===b?"undefined":ta(b))||(b={});var d=axe._audit;if(!d)throw new Error("No audit configured");b.reporter=b.reporter||d.reporter||"v2",b.performanceTimer&&axe.utils.performanceTimer.start();var e=axe.getReporter(b.reporter);axe._runRules(a,b,function(a){var d=e(a,b,c);void 0!==d&&(b.performanceTimer&&axe.utils.performanceTimer.end(),c(d))},axe.log)},axe.cleanup=v,axe.configure=w,axe.getRules=function(a){"use strict";a=a||[];var b=a.length?axe._audit.rules.filter(function(b){return!!a.filter(function(a){return-1!==b.tags.indexOf(a)}).length}):axe._audit.rules,c=axe._audit.data.rules||{};return b.map(function(a){var b=c[a.id]||{};return{ruleId:a.id,description:b.description,help:b.help,helpUrl:b.helpUrl,tags:a.tags}})},axe._load=function(a){"use strict";axe.utils.respondable.subscribe("axe.ping",function(a,b,c){c({axe:!0})}),axe.utils.respondable.subscribe("axe.start",x),axe._audit=new e(a)};var axe=axe||{};axe.plugins={},y.prototype.run=function(){"use strict";return this._run.apply(this,arguments)},y.prototype.collect=function(){"use strict";return this._collect.apply(this,arguments)},y.prototype.cleanup=function(a){"use strict";var b=axe.utils.queue(),c=this;Object.keys(this._registry).forEach(function(a){b.defer(function(b){c._registry[a].cleanup(b)})}),b.then(function(){a()})},y.prototype.add=function(a){"use strict";this._registry[a.id]=a},axe.registerPlugin=function(a){"use strict";axe.plugins[a.id]=new y(a)};var va,wa={};axe.getReporter=function(a){"use strict";return"string"==typeof a&&wa[a]?wa[a]:"function"==typeof a?a:va},axe.addReporter=function(a,b,c){"use strict";wa[a]=b,c&&(va=b)},axe.reset=z,axe._runRules=A;var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},xa=function(){};axe.run=function(a,b,c){"use strict";if(!axe._audit)throw new Error("No audit configured");var d=C(a,b,c);a=d.context,b=d.options,c=d.callback,b.reporter=b.reporter||axe._audit.reporter||"v1",b.performanceTimer&&axe.utils.performanceTimer.start();var e=void 0,f=xa,g=xa;return window.Promise&&c===xa&&(e=new Promise(function(a,b){f=b,g=a})),axe._runRules(a,b,function(a){var d=function(a){try{c(null,a)}catch(a){axe.log(a)}g(a)};b.performanceTimer&&axe.utils.performanceTimer.end();try{var e=axe.getReporter(b.reporter),h=e(a,b,d);void 0!==h&&d(h)}catch(a){c(a),f(a)}},function(a){c(a),f(a)}),e},ua.failureSummary=function(a){"use strict";var b={};return b.none=a.none.concat(a.all),b.any=a.any,Object.keys(b).map(function(a){if(b[a].length){var c=axe._audit.data.failureSummaries[a];return c&&"function"==typeof c.failureMessage?c.failureMessage(b[a].map(function(a){return a.message||""})):void 0}}).filter(function(a){return void 0!==a}).join("\n\n")},ua.incompleteFallbackMessage=function(){"use strict";return axe._audit.data.incompleteFallbackMessage()};var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a},ya=axe.constants.resultGroups;ua.processAggregate=function(a,b){var c=axe.utils.aggregateResult(a);return c.timestamp=(new Date).toISOString(),c.url=window.location.href,ya.forEach(function(a){c[a]=(c[a]||[]).map(function(a){return a=Object.assign({},a),Array.isArray(a.nodes)&&a.nodes.length>0&&(a.nodes=a.nodes.map(function(a){return"object"===ta(a.node)&&(a.html=a.node.source,b.elementRef&&!a.node.fromFrame&&(a.element=a.node.element),(!1!==b.selectors||a.node.fromFrame)&&(a.target=a.node.selector),b.xpath&&(a.xpath=a.node.xpath)),delete a.result,delete a.node,D(a,b),a})),ya.forEach(function(b){return delete a[b]}),delete a.pageLevel,delete a.result,a})}),c},axe.addReporter("na",function(a,b,c){"use strict";"function"==typeof b&&(c=b,b={});var d=ua.processAggregate(a,b);c({violations:d.violations,passes:d.passes,incomplete:d.incomplete,inapplicable:d.inapplicable,timestamp:d.timestamp,url:d.url})}),axe.addReporter("no-passes",function(a,b,c){"use strict";"function"==typeof b&&(c=b,b={});var d=ua.processAggregate(a,b);c({violations:d.violations,timestamp:d.timestamp,url:d.url})}),axe.addReporter("raw",function(a,b,c){"use strict";"function"==typeof b&&(c=b,b={}),c(a)}),axe.addReporter("v1",function(a,b,c){"use strict";"function"==typeof b&&(c=b,b={});var d=ua.processAggregate(a,b);d.violations.forEach(function(a){return a.nodes.forEach(function(a){a.failureSummary=ua.failureSummary(a)})}),c({violations:d.violations,passes:d.passes,incomplete:d.incomplete,inapplicable:d.inapplicable,timestamp:d.timestamp,url:d.url})}),axe.addReporter("v2",function(a,b,c){"use strict";"function"==typeof b&&(c=b,b={});var d=ua.processAggregate(a,b);c({violations:d.violations,passes:d.passes,incomplete:d.incomplete,inapplicable:d.inapplicable,timestamp:d.timestamp,url:d.url})},!0),axe.utils.aggregate=function(a,b,c){b=b.slice(),c&&b.push(c);var d=b.map(function(b){return a.indexOf(b)}).sort();return a[d.pop()]};var za=[];za[axe.constants.PASS_PRIO]=!0,za[axe.constants.CANTTELL_PRIO]=null,za[axe.constants.FAIL_PRIO]=!1;var Aa=["any","all","none"];axe.utils.aggregateChecks=function(a){var b=Object.assign({},a);E(b,function(a,b){var c=za.indexOf(a.result);a.priority=-1!==c?c:axe.constants.CANTTELL_PRIO,"none"===b&&(a.priority=4-a.priority)});var c=E(b,function(a){return a.priority});b.priority=Math.max(c.all.reduce(function(a,b){return Math.max(a,b)},0),c.none.reduce(function(a,b){return Math.max(a,b)},0),c.any.reduce(function(a,b){return Math.min(a,b)},4)%4);var d=[];return Aa.forEach(function(a){b[a]=b[a].filter(function(a){return a.priority===b.priority}),b[a].forEach(function(a){return d.push(a.impact)})}),b.priority===axe.constants.FAIL_PRIO?b.impact=axe.utils.aggregate(axe.constants.impact,d):b.impact=null,E(b,function(a){delete a.result,delete a.priority}),b.result=axe.constants.results[b.priority],delete b.priority,b},axe.utils.aggregateResult=function(a){var b={};return axe.constants.resultGroups.forEach(function(a){return b[a]=[]}),a.forEach(function(a){a.error?F(b,a,axe.constants.CANTTELL_GROUP):a.result===axe.constants.NA?F(b,a,axe.constants.NA_GROUP):axe.constants.resultGroups.forEach(function(c){Array.isArray(a[c])&&a[c].length>0&&F(b,a,c)})}),b},function(){axe.utils.aggregateRule=function(a){var b={};a=a.map(function(a){if(a.any&&a.all&&a.none)return axe.utils.aggregateChecks(a);if(Array.isArray(a.node))return axe.utils.finalizeRuleResult(a);throw new TypeError("Invalid Result type")});var c=a.map(function(a){return a.result});b.result=axe.utils.aggregate(axe.constants.results,c,b.result),axe.constants.resultGroups.forEach(function(a){return b[a]=[]}),a.forEach(function(a){var c=axe.constants.resultGroupMap[a.result];b[c].push(a)});var d=axe.constants.FAIL_GROUP;if(b[d].length>0){var e=b[d].map(function(a){return a.impact});b.impact=axe.utils.aggregate(axe.constants.impact,e)||null}else b.impact=null;return b}}(),axe.utils.areStylesSet=G,axe.utils.checkHelper=function(a,b,c,d){"use strict";return{isAsync:!1,async:function(){return this.isAsync=!0,function(b){b instanceof Error==!1?(a.value=b,c(a)):d(b)}},data:function(b){a.data=b},relatedNodes:function(c){c=c instanceof Node?[c]:axe.utils.toArray(c),a.relatedNodes=c.map(function(a){return new axe.utils.DqElement(a,b)})}}};var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};axe.utils.clone=function(a){"use strict";var b,c,d=a;if(null!==a&&"object"===(void 0===a?"undefined":ta(a)))if(Array.isArray(a))for(d=[],b=0,c=a.length;b<c;b++)d[b]=axe.utils.clone(a[b]);else{d={};for(b in a)d[b]=axe.utils.clone(a[b])}return d},axe.utils.sendCommandToFrame=function(a,b,c,d){"use strict";var e=a.contentWindow;if(!e)return axe.log("Frame does not have a content window",a),void c(null);var f=setTimeout(function(){f=setTimeout(function(){var e=H("No response from frame",a);b.debug?d(e):(axe.log(e),c(null))},0)},500);axe.utils.respondable(e,"axe.ping",null,void 0,function(){clearTimeout(f),f=setTimeout(function(){d(H("Axe in frame timed out",a))},3e4),axe.utils.respondable(e,"axe.start",b,void 0,function(a){clearTimeout(f),a instanceof Error==!1?c(a):d(a)})})},axe.utils.collectResultsFromFrames=I,axe.utils.contains=function(a,b){"use strict";function c(a,b){return a.shadowId===b.shadowId||!!a.children.find(function(a){return c(a,b)})}return a.shadowId||b.shadowId?c(a,b):"function"==typeof a.actualNode.contains?a.actualNode.contains(b.actualNode):!!(16&a.actualNode.compareDocumentPosition(b.actualNode))},function(axe){/*!
-  * The copyright below covers the code within this function block only
-  *
-  * Copyright (c) 2013 Dulin Marat
-  * 
-  * Permission is hereby granted, free of charge, to any person obtaining a copy
-  * of this software and associated documentation files (the "Software"), to deal
-  * in the Software without restriction, including without limitation the rights
-  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-  * copies of the Software, and to permit persons to whom the Software is
-  * furnished to do so, subject to the following conditions:
-  * 
-  * The above copyright notice and this permission notice shall be included in
-  * all copies or substantial portions of the Software.
-  * 
-  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-  * THE SOFTWARE.
-  */
-function a(){this.pseudos={},this.attrEqualityMods={},this.ruleNestingOperators={},this.substitutesEnabled=!1}function b(a){return a>="a"&&a<="z"||a>="A"&&a<="Z"||"-"===a||"_"===a}function c(a){return a>="a"&&a<="z"||a>="A"&&a<="Z"||a>="0"&&a<="9"||"-"===a||"_"===a}function d(a){return a>="a"&&a<="f"||a>="A"&&a<="F"||a>="0"&&a<="9"}function e(a,e,g,j,k,l){var m,n,o,p,q;return p=a.length,m=null,o=function(b,c){var f,g,h;for(h="",e++,m=a.charAt(e);e<p;){if(m===b)return e++,h;if("\\"===m)if(e++,(m=a.charAt(e))===b)h+=b;else if(f=c[m])h+=f;else{if(d(m)){for(g=m,e++,m=a.charAt(e);d(m);)g+=m,e++,m=a.charAt(e);" "===m&&(e++,m=a.charAt(e)),h+=String.fromCharCode(parseInt(g,16));continue}h+=m}else h+=m;e++,m=a.charAt(e)}return h},n=function(){var b="";for(m=a.charAt(e);e<p;){if(c(m))b+=m;else{if("\\"!==m)return b;if(++e>=p)throw Error("Expected symbol but end of file reached.");if(m=a.charAt(e),f[m])b+=m;else{if(d(m)){var g=m;for(e++,m=a.charAt(e);d(m);)g+=m,e++,m=a.charAt(e);" "===m&&(e++,m=a.charAt(e)),b+=String.fromCharCode(parseInt(g,16));continue}b+=m}}e++,m=a.charAt(e)}return b},q=function(){m=a.charAt(e);for(var b=!1;" "===m||"\t"===m||"\n"===m||"\r"===m||"\f"===m;)b=!0,e++,m=a.charAt(e);return b},this.parse=function(){var b=this.parseSelector();if(e<p)throw Error('Rule expected but "'+a.charAt(e)+'" found.');return b},this.parseSelector=function(){var b,c=b=this.parseSingleSelector();for(m=a.charAt(e);","===m;){if(e++,q(),"selectors"!==b.type&&(b={type:"selectors",selectors:[c]}),!(c=this.parseSingleSelector()))throw Error('Rule expected after ",".');b.selectors.push(c)}return b},this.parseSingleSelector=function(){q();var b={type:"ruleSet"},c=this.parseRule();if(!c)return null;for(var d=b;c&&(c.type="rule",d.rule=c,d=c,q(),m=a.charAt(e),!(e>=p||","===m||")"===m));)if(k[m]){var f=m;if(e++,q(),!(c=this.parseRule()))throw Error('Rule expected after "'+f+'".');c.nestingOperator=f}else(c=this.parseRule())&&(c.nestingOperator=null);return b},this.parseRule=function(){for(var c=null;e<p;)if("*"===(m=a.charAt(e)))e++,(c=c||{}).tagName="*";else if(b(m)||"\\"===m)(c=c||{}).tagName=n();else if("."===m)e++,c=c||{},(c.classNames=c.classNames||[]).push(n());else if("#"===m)e++,(c=c||{}).id=n();else if("["===m){e++,q();var d={name:n()};if(q(),"]"===m)e++;else{var f="";if(j[m]&&(f=m,e++,m=a.charAt(e)),e>=p)throw Error('Expected "=" but end of file reached.');if("="!==m)throw Error('Expected "=" but "'+m+'" found.');d.operator=f+"=",e++,q();var k="";if(d.valueType="string",'"'===m)k=o('"',i);else if("'"===m)k=o("'",h);else if(l&&"$"===m)e++,k=n(),d.valueType="substitute";else{for(;e<p&&"]"!==m;)k+=m,e++,m=a.charAt(e);k=k.trim()}if(q(),e>=p)throw Error('Expected "]" but end of file reached.');if("]"!==m)throw Error('Expected "]" but "'+m+'" found.');e++,d.value=k}c=c||{},(c.attrs=c.attrs||[]).push(d)}else{if(":"!==m)break;e++;var r=n(),s={name:r};if("("===m){e++;var t="";if(q(),"selector"===g[r])s.valueType="selector",t=this.parseSelector();else{if(s.valueType=g[r]||"string",'"'===m)t=o('"',i);else if("'"===m)t=o("'",h);else if(l&&"$"===m)e++,t=n(),s.valueType="substitute";else{for(;e<p&&")"!==m;)t+=m,e++,m=a.charAt(e);t=t.trim()}q()}if(e>=p)throw Error('Expected ")" but end of file reached.');if(")"!==m)throw Error('Expected ")" but "'+m+'" found.');e++,s.value=t}c=c||{},(c.pseudos=c.pseudos||[]).push(s)}return c},this}a.prototype.registerSelectorPseudos=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],this.pseudos[a]="selector";return this},a.prototype.unregisterSelectorPseudos=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],delete this.pseudos[a];return this},a.prototype.registerNumericPseudos=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],this.pseudos[a]="numeric";return this},a.prototype.unregisterNumericPseudos=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],delete this.pseudos[a];return this},a.prototype.registerNestingOperators=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],this.ruleNestingOperators[a]=!0;return this},a.prototype.unregisterNestingOperators=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],delete this.ruleNestingOperators[a];return this},a.prototype.registerAttrEqualityMods=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],this.attrEqualityMods[a]=!0;return this},a.prototype.unregisterAttrEqualityMods=function(a){for(var b=0,c=arguments.length;b<c;b++)a=arguments[b],delete this.attrEqualityMods[a];return this},a.prototype.enableSubstitutes=function(){return this.substitutesEnabled=!0,this},a.prototype.disableSubstitutes=function(){return this.substitutesEnabled=!1,this};var f={"!":!0,'"':!0,"#":!0,$:!0,"%":!0,"&":!0,"'":!0,"(":!0,")":!0,"*":!0,"+":!0,",":!0,".":!0,"/":!0,";":!0,"<":!0,"=":!0,">":!0,"?":!0,"@":!0,"[":!0,"\\":!0,"]":!0,"^":!0,"`":!0,"{":!0,"|":!0,"}":!0,"~":!0},g={"\n":"\\n","\r":"\\r","\t":"\\t","\f":"\\f","\v":"\\v"},h={n:"\n",r:"\r",t:"\t",f:"\f","\\":"\\","'":"'"},i={n:"\n",r:"\r",t:"\t",f:"\f","\\":"\\",'"':'"'};a.prototype.parse=function(a){return new e(a,0,this.pseudos,this.attrEqualityMods,this.ruleNestingOperators,this.substitutesEnabled).parse()},a.prototype.escapeIdentifier=function(a){for(var b="",c=0,d=a.length;c<d;){var e=a.charAt(c);if(f[e])b+="\\"+e;else if("_"===e||"-"===e||e>="A"&&e<="Z"||e>="a"&&e<="z"||0!==c&&e>="0"&&e<="9")b+=e;else{var g=e.charCodeAt(0);if(55296==(63488&g)){var h=a.charCodeAt(c++);if(55296!=(64512&g)||56320!=(64512&h))throw Error("UCS-2(decode): illegal sequence");g=((1023&g)<<10)+(1023&h)+65536}b+="\\"+g.toString(16)+" "}c++}return b},a.prototype.escapeStr=function(a){for(var b,c,d="",e=0,f=a.length;e<f;)b=a.charAt(e),'"'===b?b='\\"':"\\"===b?b="\\\\":(c=g[b])&&(b=c),d+=b,e++;return'"'+d+'"'},a.prototype.render=function(a){return this._renderEntity(a).trim()},a.prototype._renderEntity=function(a){var b,c,d;switch(d="",a.type){case"ruleSet":for(b=a.rule,c=[];b;)b.nestingOperator&&c.push(b.nestingOperator),c.push(this._renderEntity(b)),b=b.rule;d=c.join(" ");break;case"selectors":d=a.selectors.map(this._renderEntity,this).join(", ");break;case"rule":a.tagName&&(d="*"===a.tagName?"*":this.escapeIdentifier(a.tagName)),a.id&&(d+="#"+this.escapeIdentifier(a.id)),a.classNames&&(d+=a.classNames.map(function(a){return"."+this.escapeIdentifier(a)},this).join("")),a.attrs&&(d+=a.attrs.map(function(a){return a.operator?"substitute"===a.valueType?"["+this.escapeIdentifier(a.name)+a.operator+"$"+a.value+"]":"["+this.escapeIdentifier(a.name)+a.operator+this.escapeStr(a.value)+"]":"["+this.escapeIdentifier(a.name)+"]"},this).join("")),a.pseudos&&(d+=a.pseudos.map(function(a){return a.valueType?"selector"===a.valueType?":"+this.escapeIdentifier(a.name)+"("+this._renderEntity(a.value)+")":"substitute"===a.valueType?":"+this.escapeIdentifier(a.name)+"($"+a.value+")":"numeric"===a.valueType?":"+this.escapeIdentifier(a.name)+"("+a.value+")":":"+this.escapeIdentifier(a.name)+"("+this.escapeIdentifier(a.value)+")":":"+this.escapeIdentifier(a.name)},this).join(""));break;default:throw Error('Unknown entity type: "'+a.type(NaN))}return d};var j=new a;j.registerNestingOperators(">"),axe.utils.cssParser=j}(axe),L.prototype={get selector(){return this.spec.selector||[axe.utils.getSelector(this.element,this._options)]},get xpath(){return this.spec.xpath||[axe.utils.getXpath(this.element)]},get element(){return this._element},get fromFrame(){return this._fromFrame},toJSON:function(){"use strict";return{selector:this.selector,source:this.source,xpath:this.xpath}}},L.fromFrame=function(a,b,c){return a.selector.unshift(c.selector),a.xpath.unshift(c.xpath),new axe.utils.DqElement(c.element,b,a)},axe.utils.DqElement=L,axe.utils.matchesSelector=function(){"use strict";function a(a){var b,c,d=a.Element.prototype,e=["matches","matchesSelector","mozMatchesSelector","webkitMatchesSelector","msMatchesSelector"],f=e.length;for(b=0;b<f;b++)if(c=e[b],d[c])return c}var b;return function(c,d){return b&&c[b]||(b=a(c.ownerDocument.defaultView)),c[b](d)}}(),axe.utils.escapeSelector=function(a){"use strict";for(var b,c=String(a),d=c.length,e=-1,f="",g=c.charCodeAt(0);++e<d;){if(0==(b=c.charCodeAt(e)))throw new Error("INVALID_CHARACTER_ERR");b>=1&&b<=31||b>=127&&b<=159||0==e&&b>=48&&b<=57||1==e&&b>=48&&b<=57&&45==g?f+="\\"+b.toString(16)+" ":f+=(1!=e||45!=b||45!=g)&&(b>=128||45==b||95==b||b>=48&&b<=57||b>=65&&b<=90||b>=97&&b<=122)?c.charAt(e):"\\"+c.charAt(e)}return f},axe.utils.extendMetaData=function(a,b){Object.assign(a,b),Object.keys(b).filter(function(a){return"function"==typeof b[a]}).forEach(function(c){a[c]=null;try{a[c]=b[c](a)}catch(a){}})},axe.utils.finalizeRuleResult=function(a){return Object.assign(a,axe.utils.aggregateRule(a.nodes)),delete a.nodes,a};var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};axe.utils.findBy=function(a,b,c){if(Array.isArray(a))return a.find(function(a){return"object"===(void 0===a?"undefined":ta(a))&&a[b]===c})};var axe=axe||{utils:{}};axe.utils.getFlattenedTree=function(a,b){function c(a,c){var d=axe.utils.getFlattenedTree(c,b);return d&&(a=a.concat(d)),a}var d,e,f;if(a.documentElement&&(a=a.documentElement),f=a.nodeName.toLowerCase(),a.shadowRoot&&"marquee"!==f)return d=M(a,b),b="a"+Math.random().toString().substring(2),e=Array.from(a.shadowRoot.childNodes),d.children=e.reduce(c,[]),[d];if("content"===f)return e=Array.from(a.getDistributedNodes()),e.reduce(c,[]);if("slot"===f){e=Array.from(a.assignedNodes()),e.length||(e=N(a));window.getComputedStyle(a);return e.reduce(c,[])}return 1===a.nodeType?(d=M(a,b),e=Array.from(a.childNodes),d.children=e.reduce(c,[]),[d]):3===a.nodeType?[M(a)]:void 0},axe.utils.getNodeFromTree=function(a,b){var c;return a.actualNode===b?a:(a.children.forEach(function(a){var d;a.actualNode===b?c=a:(d=axe.utils.getNodeFromTree(a,b))&&(c=d)}),c)},axe.utils.getAllChecks=function(a){"use strict";return[].concat(a.any||[]).concat(a.all||[]).concat(a.none||[])},axe.utils.getCheckOption=function(a,b,c){var d=((c.rules&&c.rules[b]||{}).checks||{})[a.id],e=(c.checks||{})[a.id],f=a.enabled,g=a.options;return e&&(e.hasOwnProperty("enabled")&&(f=e.enabled),e.hasOwnProperty("options")&&(g=e.options)),d&&(d.hasOwnProperty("enabled")&&(f=d.enabled),d.hasOwnProperty("options")&&(g=d.options)),{enabled:f,options:g,absolutePaths:c.absolutePaths}};var Ba=function(){function a(a,b){var c=[],d=!0,e=!1,f=void 0;try{for(var g,h=a[Symbol.iterator]();!(d=(g=h.next()).done)&&(c.push(g.value),!b||c.length!==b);d=!0);}catch(a){e=!0,f=a}finally{try{!d&&h.return&&h.return()}finally{if(e)throw f}}return c}return function(b,c){if(Array.isArray(b))return b;if(Symbol.iterator in Object(b))return a(b,c);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();axe.utils.getFriendlyUriEnd=function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!(a.length<=1||"data:"===a.substr(0,5)||"javascript:"===a.substr(0,11)||a.includes("?"))){var c=b.currentDomain,d=b.maxLength,e=void 0===d?25:d,f=Q(a),g=f.path,h=f.domain,i=f.hash,j=g.substr(g.substr(0,g.length-2).lastIndexOf("/")+1);if(i)return j&&(j+i).length<=e?j+i:j.length<2&&i.length>2&&i.length<=e?i:void 0;if(h&&h.length<e&&g.length<=1)return h+g;if(g==="/"+j&&h&&c&&h!==c&&(h+g).length<=e)return h+g;var k=j.lastIndexOf(".");return(-1===k||k>1)&&(-1!==k||j.length>2)&&j.length<=e&&!j.match(/index(\.[a-zA-Z]{2-4})?/)&&!O(j)?j:void 0}};var Ca=axe.utils.escapeSelector,Da=["div","span","p","b","i","u","strong","em","h2","h3"],Ea={getElmId:function(a){if(a.getAttribute("id")){var b=a.getRootNode&&a.getRootNode()||document,c="#"+Ca(a.getAttribute("id")||"");return c.match(/player_uid_/)||1!==b.querySelectorAll(c).length?void 0:c}},getCustomElm:function(a,b){var c=b.isCustomElm,d=b.nodeName;if(c)return d},getElmRoleProp:function(a){if(a.hasAttribute("role"))return'[role="'+Ca(a.getAttribute("role"))+'"]'},getUncommonElm:function(a,b){var c=b.isCommonElm,d=b.isCustomElm,e=b.nodeName;if(!c&&!d)return e=Ca(e),"input"===e&&a.hasAttribute("type")&&(e+='[type="'+a.type+'"]'),e},getElmNameProp:function(a){if(!a.hasAttribute("id")&&a.name)return'[name="'+Ca(a.name)+'"]'},getDistinctClass:function(a,b){var c=b.distinctClassList;if(c.length>0&&c.length<3)return"."+c.map(Ca).join(".")},getFileRefProp:function(a){var b=void 0;if(a.hasAttribute("href"))b="href";else{if(!a.hasAttribute("src"))return;b="src"}var c=axe.utils.getFriendlyUriEnd(a.getAttribute(b));if(c)return"["+b+'$="'+encodeURI(c)+'"]'},getCommonName:function(a,b){var c=b.nodeName;if(b.isCommonElm)return c}};axe.utils.getSelector=function(a){var b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!a)return"";var c=a.getRootNode&&a.getRootNode()||document;if(11===c.nodeType){for(var d=[];11===c.nodeType;)d.push({elm:a,doc:c}),a=c.host,c=a.getRootNode();return d.push({elm:a,doc:c}),d.reverse().map(function(a){return W(a.elm,b,a.doc)})}return W(a,b,c)},axe.utils.getXpath=function(a){return Y(X(a))};var Fa;axe.utils.injectStyle=Z,axe.utils.isHidden=function(a,b){"use strict";var c;if(9===a.nodeType)return!1;11===a.nodeType&&(a=a.host);var d=window.getComputedStyle(a,null);return!d||!a.parentNode||"none"===d.getPropertyValue("display")||!b&&"hidden"===d.getPropertyValue("visibility")||"true"===a.getAttribute("aria-hidden")||(c=a.assignedSlot?a.assignedSlot:a.parentNode,axe.utils.isHidden(c,!0))},axe.utils.mergeResults=function(a,b){"use strict";var c=[];return a.forEach(function(a){var d=aa(a);d&&d.length&&d.forEach(function(d){d.nodes&&a.frame&&$(d.nodes,b,a.frameElement,a.frame);var e=axe.utils.findBy(c,"id",d.id);e?d.nodes.length&&_(e.nodes,d.nodes):c.push(d)})}),c},axe.utils.nodeSorter=function(a,b){"use strict";return a.actualNode===b.actualNode?0:4&a.actualNode.compareDocumentPosition(b.actualNode)?-1:1},utils.performanceTimer=function(){"use strict";function a(){if(window.performance&&window.performance)return window.performance.now()}var b=null,c=a();return{start:function(){this.mark("mark_axe_start")},end:function(){this.mark("mark_axe_end"),this.measure("axe","mark_axe_start","mark_axe_end"),this.logMeasures("axe")},auditStart:function(){this.mark("mark_audit_start")},auditEnd:function(){this.mark("mark_audit_end"),this.measure("audit_start_to_end","mark_audit_start","mark_audit_end"),this.logMeasures()},mark:function(a){window.performance&&void 0!==window.performance.mark&&window.performance.mark(a)},measure:function(a,b,c){window.performance&&void 0!==window.performance.measure&&window.performance.measure(a,b,c)},logMeasures:function(a){function b(a){axe.log("Measure "+a.name+" took "+a.duration+"ms")}if(window.performance&&void 0!==window.performance.getEntriesByType)for(var c=window.performance.getEntriesByType("measure"),d=0;d<c.length;++d){var e=c[d];if(e.name===a)return void b(e);b(e)}},timeElapsed:function(){return a()-c},reset:function(){b||(b=a()),c=a()}}}(),"function"!=typeof Object.assign&&function(){Object.assign=function(a){"use strict";if(void 0===a||null===a)throw new TypeError("Cannot convert undefined or null to object");for(var b=Object(a),c=1;c<arguments.length;c++){var d=arguments[c];if(void 0!==d&&null!==d)for(var e in d)d.hasOwnProperty(e)&&(b[e]=d[e])}return b}}(),Array.prototype.find||(Array.prototype.find=function(a){if(null===this)throw new TypeError("Array.prototype.find called on null or undefined");if("function"!=typeof a)throw new TypeError("predicate must be a function");for(var b,c=Object(this),d=c.length>>>0,e=arguments[1],f=0;f<d;f++)if(b=c[f],a.call(e,b,f,c))return b}),axe.utils.pollyfillElementsFromPoint=function(){if(document.elementsFromPoint)return document.elementsFromPoint;if(document.msElementsFromPoint)return document.msElementsFromPoint;var a=function(){var a=document.createElement("x");return a.style.cssText="pointer-events:auto","auto"===a.style.pointerEvents}(),b=a?"pointer-events":"visibility",c=a?"none":"hidden",d=document.createElement("style");return d.innerHTML=a?"* { pointer-events: all }":"* { visibility: visible }",function(a,e){var f,g,h,i=[],j=[];for(document.head.appendChild(d);(f=document.elementFromPoint(a,e))&&-1===i.indexOf(f);)i.push(f),j.push({value:f.style.getPropertyValue(b),priority:f.style.getPropertyPriority(b)}),f.style.setProperty(b,c,"important");for(g=j.length;h=j[--g];)i[g].style.setProperty(b,h.value?h.value:"",h.priority);return document.head.removeChild(d),i}},"function"==typeof window.addEventListener&&(document.elementsFromPoint=axe.utils.pollyfillElementsFromPoint()),Array.prototype.includes||(Array.prototype.includes=function(a){"use strict";var b=Object(this),c=parseInt(b.length,10)||0;if(0===c)return!1;var d,e=parseInt(arguments[1],10)||0;e>=0?d=e:(d=c+e)<0&&(d=0);for(var f;d<c;){if(f=b[d],a===f||a!==a&&f!==f)return!0;d++}return!1}),Array.prototype.some||(Array.prototype.some=function(a){"use strict";if(null==this)throw new TypeError("Array.prototype.some called on null or undefined");if("function"!=typeof a)throw new TypeError;for(var b=Object(this),c=b.length>>>0,d=arguments.length>=2?arguments[1]:void 0,e=0;e<c;e++)if(e in b&&a.call(d,b[e],e,b))return!0;return!1}),Array.from||(Array.from=function(){var a=Object.prototype.toString,b=function(b){return"function"==typeof b||"[object Function]"===a.call(b)},c=function(a){var b=Number(a);return isNaN(b)?0:0!==b&&isFinite(b)?(b>0?1:-1)*Math.floor(Math.abs(b)):b},d=Math.pow(2,53)-1,e=function(a){var b=c(a);return Math.min(Math.max(b,0),d)};return function(a){var c=this,d=Object(a);if(null==a)throw new TypeError("Array.from requires an array-like object - not null or undefined");var f,g=arguments.length>1?arguments[1]:void 0;if(void 0!==g){if(!b(g))throw new TypeError("Array.from: when provided, the second argument must be a function");arguments.length>2&&(f=arguments[2])}for(var h,i=e(d.length),j=b(c)?Object(new c(i)):new Array(i),k=0;k<i;)h=d[k],j[k]=g?void 0===f?g(h,k):g.call(f,h,k):h,k+=1;return j.length=i,j}}()),String.prototype.includes||(String.prototype.includes=function(a,b){return"number"!=typeof b&&(b=0),!(b+a.length>this.length)&&-1!==this.indexOf(a,b)});var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};axe.utils.publishMetaData=function(a){"use strict";var b=axe._audit.data.checks||{},c=axe._audit.data.rules||{},d=axe.utils.findBy(axe._audit.rules,"id",a.id)||{};a.tags=axe.utils.clone(d.tags||[]);var e=ca(b,!0),f=ca(b,!1);a.nodes.forEach(function(a){a.any.forEach(e),a.all.forEach(e),a.none.forEach(f)}),axe.utils.extendMetaData(a,axe.utils.clone(c[a.id]||{}))};var Ga=function(){},Ha=function(){},Ia=function(){/*! Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License */
-var a=/(?=[\-\[\]{}()*+?.\\\^$|,#\s])/g;return function(b){return b.replace(a,"\\")}}(),Ja=/\\/g;Ga=function(a){return a.map(function(a){for(var b=[],c=a.rule;c;)b.push({tag:c.tagName?c.tagName.toLowerCase():"*",combinator:c.nestingOperator?c.nestingOperator:" ",id:c.id,attributes:ja(c.attrs),classes:ka(c.classNames),pseudos:la(c.pseudos)}),c=c.rule;return b})},Ha=function(a,b,c){return b.reduce(function(b,d){var e=a;return d.forEach(function(a,b){if(c=">"!==a.combinator&&c,-1===[" ",">"].indexOf(a.combinator))throw new Error("axe.utils.querySelectorAll does not support the combinator: "+a.combinator);e=e.reduce(function(d,e){return d.concat(ia(b?e.children:e,a,c))},[])}),b.concat(e)},[])},axe.utils.querySelectorAll=function(a,b){a=Array.isArray(a)?a:[a];var c=axe.utils.cssParser.parse(b);return c=c.selectors?c.selectors:[c],c=Ga(c),Ha(a,c,!0)};var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};!function(){"use strict";function a(){}function b(a){if("function"!=typeof a)throw new TypeError("Queue methods require functions as arguments")}function c(){function c(b){return function(c){g[b]=c,(i-=1)||j===a||(k=!0,j(g))}}function d(b){return j=a,m(b),g}function e(){for(var a=g.length;h<a;h++){var b=g[h];try{b.call(null,c(h),d)}catch(a){d(a)}}}var f,g=[],h=0,i=0,j=a,k=!1,l=function(a){f=a,setTimeout(function(){void 0!==f&&null!==f&&axe.log("Uncaught error (of queue)",f)},1)},m=l,n={defer:function(a){if("object"===(void 0===a?"undefined":ta(a))&&a.then&&a.catch){var c=a;a=function(a,b){c.then(a).catch(b)}}if(b(a),void 0===f){if(k)throw new Error("Queue already completed");return g.push(a),++i,e(),n}},then:function(c){if(b(c),j!==a)throw new Error("queue `then` already set");return f||(j=c,i||(k=!0,j(g))),n},catch:function(a){if(b(a),m!==l)throw new Error("queue `catch` already set");return f?(a(f),f=null):m=a,n},abort:d};return n}axe.utils.queue=c}();var ta="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(a){return typeof a}:function(a){return a&&"function"==typeof Symbol&&a.constructor===Symbol&&a!==Symbol.prototype?"symbol":typeof a};!function(a){"use strict";function b(){var a="axe",b="";return void 0!==axe&&axe._audit&&!axe._audit.application&&(a=axe._audit.application),void 0!==axe&&(b=axe.version),a+"."+b}function c(a){if("object"===(void 0===a?"undefined":ta(a))&&"string"==typeof a.uuid&&!0===a._respondable){var c=b();return a._source===c||"axe.x.y.z"===a._source||"axe.x.y.z"===c}return!1}function d(a,c,d,e,f,g){var h;d instanceof Error&&(h={name:d.name,message:d.message,stack:d.stack},d=void 0);var i={uuid:e,topic:c,message:d,error:h,_respondable:!0,_source:b(),_keepalive:f};"function"==typeof g&&(j[e]=g),a.postMessage(JSON.stringify(i),"*")}function e(a,b,c,e,f){d(a,b,c,Ka.v1(),e,f)}function f(a,b,c){return function(e,f,g){d(a,b,e,c,f,g)}}function g(a,b,c){var d=b.topic,e=k[d];if(e){var g=f(a,null,b.uuid);e(b.message,c,g)}}function h(a){var b=a.message||"Unknown error occurred",c=window[a.name]||Error;return a.stack&&(b+="\n"+a.stack.replace(a.message,"")),new c(b)}function i(a){var b;if("string"==typeof a){try{b=JSON.parse(a)}catch(a){}if(c(b))return"object"===ta(b.error)?b.error=h(b.error):b.error=void 0,b}}var j={},k={};e.subscribe=function(a,b){k[a]=b},e.isInFrame=function(a){return a=a||window,!!a.frameElement},"function"==typeof window.addEventListener&&window.addEventListener("message",function(a){var b=i(a.data);if(b){var c=b.uuid,e=b._keepalive,h=j[c];if(h){h(b.error||b.message,e,f(a.source,b.topic,c)),e||delete j[c]}if(!b.error)try{g(a.source,b,e)}catch(e){d(a.source,b.topic,e,c,!1)}}},!1),a.respondable=e}(utils),axe.utils.ruleShouldRun=function(a,b,c){"use strict";var d=c.runOnly||{},e=(c.rules||{})[a.id];return!(a.pageLevel&&!b.page)&&("rule"===d.type?-1!==d.values.indexOf(a.id):e&&"boolean"==typeof e.enabled?e.enabled:"tag"===d.type&&d.values?ma(a,d.values):ma(a,[]))},axe.utils.getScrollState=function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:window,b=a.document.documentElement;return[void 0!==a.pageXOffset?{elm:a,top:a.pageYOffset,left:a.pageXOffset}:{elm:b,top:b.scrollTop,left:b.scrollLeft}].concat(pa(document.body))},axe.utils.setScrollState=function(a){a.forEach(function(a){return oa(a.elm,a.top,a.left)})},axe.utils.select=function(a,b){"use strict";for(var c,d=[],e=0,f=b.include.length;e<f;e++)c=b.include[e],c.actualNode.nodeType===c.actualNode.ELEMENT_NODE&&axe.utils.matchesSelector(c.actualNode,a)&&sa(d,[c],b),sa(d,axe.utils.querySelectorAll(c,a),b);return d.sort(axe.utils.nodeSorter)},axe.utils.toArray=function(a){"use strict";return Array.prototype.slice.call(a)};var Ka;!function(a){function b(a,b,c){var d=b&&c||0,e=0;for(b=b||[],a.toLowerCase().replace(/[0-9a-f]{2}/g,function(a){e<16&&(b[d+e++]=l[a])});e<16;)b[d+e++]=0;return b}function c(a,b){var c=b||0,d=k;return d[a[c++]]+d[a[c++]]+d[a[c++]]+d[a[c++]]+"-"+d[a[c++]]+d[a[c++]]+"-"+d[a[c++]]+d[a[c++]]+"-"+d[a[c++]]+d[a[c++]]+"-"+d[a[c++]]+d[a[c++]]+d[a[c++]]+d[a[c++]]+d[a[c++]]+d[a[c++]]}function d(a,b,d){var e=b&&d||0,f=b||[];a=a||{};var g=null!=a.clockseq?a.clockseq:p,h=null!=a.msecs?a.msecs:(new Date).getTime(),i=null!=a.nsecs?a.nsecs:r+1,j=h-q+(i-r)/1e4;if(j<0&&null==a.clockseq&&(g=g+1&16383),(j<0||h>q)&&null==a.nsecs&&(i=0),i>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");q=h,r=i,p=g,h+=122192928e5;var k=(1e4*(268435455&h)+i)%4294967296;f[e++]=k>>>24&255,f[e++]=k>>>16&255,f[e++]=k>>>8&255,f[e++]=255&k;var l=h/4294967296*1e4&268435455;f[e++]=l>>>8&255,f[e++]=255&l,f[e++]=l>>>24&15|16,f[e++]=l>>>16&255,f[e++]=g>>>8|128,f[e++]=255&g;for(var m=a.node||o,n=0;n<6;n++)f[e+n]=m[n];return b||c(f)}function e(a,b,d){var e=b&&d||0;"string"==typeof a&&(b="binary"==a?new j(16):null,a=null),a=a||{};var g=a.random||(a.rng||f)();if(g[6]=15&g[6]|64,g[8]=63&g[8]|128,b)for(var h=0;h<16;h++)b[e+h]=g[h];return b||c(g)}var f,g=a.crypto||a.msCrypto;if(!f&&g&&g.getRandomValues){var h=new Uint8Array(16);f=function(){return g.getRandomValues(h),h}}if(!f){var i=new Array(16);f=function(){for(var a,b=0;b<16;b++)0==(3&b)&&(a=4294967296*Math.random()),i[b]=a>>>((3&b)<<3)&255;return i}}for(var j="function"==typeof a.Buffer?a.Buffer:Array,k=[],l={},m=0;m<256;m++)k[m]=(m+256).toString(16).substr(1),l[k[m]]=m;var n=f(),o=[1|n[0],n[1],n[2],n[3],n[4],n[5]],p=16383&(n[6]<<8|n[7]),q=0,r=0;Ka=e,Ka.v1=d,Ka.v4=e,Ka.parse=b,Ka.unparse=c,Ka.BufferClass=j}(window),axe._load({data:{rules:{accesskeys:{description:"Ensures every accesskey attribute value is unique",help:"accesskey attribute value must be unique"},"area-alt":{description:"Ensures <area> elements of image maps have alternate text",help:"Active <area> elements must have alternate text"},"aria-allowed-attr":{description:"Ensures ARIA attributes are allowed for an element's role",help:"Elements must only use allowed ARIA attributes"},"aria-hidden-body":{description:"Ensures aria-hidden='true' is not present on the document body.",help:"aria-hidden='true' must not be present on the document body"},"aria-required-attr":{description:"Ensures elements with ARIA roles have all required ARIA attributes",help:"Required ARIA attributes must be provided"},"aria-required-children":{description:"Ensures elements with an ARIA role that require child roles contain them",help:"Certain ARIA roles must contain particular children"},"aria-required-parent":{description:"Ensures elements with an ARIA role that require parent roles are contained by them",help:"Certain ARIA roles must be contained by particular parents"},"aria-roles":{description:"Ensures all elements with a role attribute use a valid value",help:"ARIA roles used must conform to valid values"},"aria-valid-attr-value":{description:"Ensures all ARIA attributes have valid values",help:"ARIA attributes must conform to valid values"},"aria-valid-attr":{description:"Ensures attributes that begin with aria- are valid ARIA attributes",help:"ARIA attributes must conform to valid names"},"audio-caption":{description:"Ensures <audio> elements have captions",help:"<audio> elements must have a captions track"},blink:{description:"Ensures <blink> elements are not used",help:"<blink> elements are deprecated and must not be used"},"button-name":{description:"Ensures buttons have discernible text",help:"Buttons must have discernible text"},bypass:{description:"Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content",help:"Page must have means to bypass repeated blocks"},checkboxgroup:{description:'Ensures related <input type="checkbox"> elements have a group and that that group designation is consistent',help:"Checkbox inputs with the same name attribute value must be part of a group"},"color-contrast":{description:"Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds",help:"Elements must have sufficient color contrast"},"definition-list":{description:"Ensures <dl> elements are structured correctly",help:"<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script> or <template> elements"},dlitem:{description:"Ensures <dt> and <dd> elements are contained by a <dl>",help:"<dt> and <dd> elements must be contained by a <dl>"},"document-title":{description:"Ensures each HTML document contains a non-empty <title> element",help:"Documents must have <title> element to aid in navigation"},"duplicate-id":{description:"Ensures every id attribute value is unique",help:"id attribute value must be unique"},"empty-heading":{description:"Ensures headings have discernible text",help:"Headings must not be empty"},"frame-title-unique":{description:"Ensures <iframe> and <frame> elements contain a unique title attribute",help:"Frames must have a unique title attribute"},"frame-title":{description:"Ensures <iframe> and <frame> elements contain a non-empty title attribute",help:"Frames must have title attribute"},"heading-order":{description:"Ensures the order of headings is semantically correct",help:"Heading levels should only increase by one"},"hidden-content":{description:"Informs users about hidden content.",help:"Hidden content on the page cannot be analyzed"},"href-no-hash":{description:"Ensures that href values are valid link references to promote only using anchors as links",help:"Anchors must only be used as links with valid URLs or URL fragments"},"html-has-lang":{description:"Ensures every HTML document has a lang attribute",help:"<html> element must have a lang attribute"},"html-lang-valid":{description:"Ensures the lang attribute of the <html> element has a valid value",help:"<html> element must have a valid value for the lang attribute"},"image-alt":{description:"Ensures <img> elements have alternate text or a role of none or presentation",help:"Images must have alternate text"},"image-redundant-alt":{description:"Ensure button and link text is not repeated as image alternative",help:"Text of buttons and links should not be repeated in the image alternative"},"input-image-alt":{description:'Ensures <input type="image"> elements have alternate text',help:"Image buttons must have alternate text"},"label-title-only":{description:"Ensures that every form element is not solely labeled using the title or aria-describedby attributes",help:"Form elements should have a visible label"},label:{description:"Ensures every form element has a label",help:"Form elements must have labels"},"layout-table":{description:"Ensures presentational <table> elements do not use <th>, <caption> elements or the summary attribute",help:"Layout tables must not use data table elements"},"link-in-text-block":{description:"Links can be distinguished without relying on color",help:"Links must be distinguished from surrounding text in a way that does not rely on color"},"link-name":{description:"Ensures links have discernible text",help:"Links must have discernible text"},list:{description:"Ensures that lists are structured correctly",help:"<ul> and <ol> must only directly contain <li>, <script> or <template> elements"},listitem:{description:"Ensures <li> elements are used semantically",help:"<li> elements must be contained in a <ul> or <ol>"},marquee:{description:"Ensures <marquee> elements are not used",help:"<marquee> elements are deprecated and must not be used"},"meta-refresh":{description:'Ensures <meta http-equiv="refresh"> is not used',help:"Timed refresh must not exist"},"meta-viewport-large":{description:'Ensures <meta name="viewport"> can scale a significant amount',help:"Users should be able to zoom and scale the text up to 500%"},"meta-viewport":{description:'Ensures <meta name="viewport"> does not disable text scaling and zooming',help:"Zooming and scaling must not be disabled"},"object-alt":{description:"Ensures <object> elements have alternate text",help:"<object> elements must have alternate text"},"p-as-heading":{description:"Ensure p elements are not used to style headings",help:"Bold, italic text and font-size are not used to style p elements as a heading"},radiogroup:{description:'Ensures related <input type="radio"> elements have a group and that the group designation is consistent',help:"Radio inputs with the same name attribute value must be part of a group"},region:{description:"Ensures all content is contained within a landmark region",help:"Content should be contained in a landmark region"},"scope-attr-valid":{description:"Ensures the scope attribute is used correctly on tables",help:"scope attribute should be used correctly"},"server-side-image-map":{description:"Ensures that server-side image maps are not used",help:"Server-side image maps must not be used"},"skip-link":{description:"Ensures the first link on the page is a skip link",help:"The page should have a skip link as its first link"},tabindex:{description:"Ensures tabindex attribute values are not greater than 0",help:"Elements should not have tabindex greater than zero"},"table-duplicate-name":{description:"Ensure that tables do not have the same summary and caption",help:"The <caption> element should not contain the same text as the summary attribute"},"table-fake-caption":{description:"Ensure that tables with a caption use the <caption> element.",help:"Data or header cells should not be used to give caption to a data table."},"td-has-header":{description:"Ensure that each non-empty data cell in a large table has one or more table headers",help:"All non-empty td element in table larger than 3 by 3 must have an associated table header"},"td-headers-attr":{description:"Ensure that each cell in a table using the headers refers to another cell in that table",help:"All cells in a table element that use the headers attribute must only refer to other cells of that same table"},"th-has-data-cells":{description:"Ensure that each table header in a data table refers to data cells",help:"All th element and elements with role=columnheader/rowheader must data cells which it describes"},"valid-lang":{description:"Ensures lang attributes have valid values",help:"lang attribute must have a valid value"},"video-caption":{description:"Ensures <video> elements have captions",help:"<video> elements must have captions"},"video-description":{description:"Ensures <video> elements have audio descriptions",help:"<video> elements must have an audio description track"}},checks:{accesskeys:{impact:"serious",messages:{pass:function(a){return"Accesskey attribute value is unique"},fail:function(a){return"Document has multiple elements with the same accesskey"}}},"non-empty-alt":{impact:"critical",messages:{pass:function(a){return"Element has a non-empty alt attribute"},fail:function(a){return"Element has no alt attribute or the alt attribute is empty"}}},"non-empty-title":{impact:"serious",messages:{pass:function(a){return"Element has a title attribute"},fail:function(a){return"Element has no title attribute or the title attribute is empty"}}},"aria-label":{impact:"serious",messages:{pass:function(a){return"aria-label attribute exists and is not empty"},fail:function(a){return"aria-label attribute does not exist or is empty"}}},"aria-labelledby":{impact:"serious",messages:{pass:function(a){return"aria-labelledby attribute exists and references elements that are visible to screen readers"},fail:function(a){return"aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty or not visible"}}},"aria-allowed-attr":{impact:"critical",messages:{pass:function(a){return"ARIA attributes are used correctly for the defined role"},fail:function(a){var b="ARIA attribute"+(a.data&&a.data.length>1?"s are":" is")+" not allowed:",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=" "+d;return b}}},"aria-hidden-body":{impact:"critical",messages:{pass:function(a){return"No aria-hidden attribute is present on document body"},fail:function(a){return"aria-hidden=true should not be present on the document body"}}},"aria-required-attr":{impact:"critical",messages:{pass:function(a){return"All required ARIA attributes are present"},fail:function(a){var b="Required ARIA attribute"+(a.data&&a.data.length>1?"s":"")+" not present:",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=" "+d;return b}}},"aria-required-children":{impact:"critical",messages:{pass:function(a){return"Required ARIA children are present"},fail:function(a){var b="Required ARIA "+(a.data&&a.data.length>1?"children":"child")+" role not present:",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=" "+d;return b}}},"aria-required-parent":{impact:"critical",messages:{pass:function(a){return"Required ARIA parent role present"},fail:function(a){var b="Required ARIA parent"+(a.data&&a.data.length>1?"s":"")+" role not present:",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=" "+d;return b}}},invalidrole:{impact:"critical",messages:{pass:function(a){return"ARIA role is valid"},fail:function(a){return"Role must be one of the valid ARIA roles"}}},abstractrole:{impact:"serious",messages:{pass:function(a){return"Abstract roles are not used"},fail:function(a){return"Abstract roles cannot be directly used"}}},"aria-valid-attr-value":{impact:"critical",messages:{pass:function(a){return"ARIA attribute values are valid"},fail:function(a){var b="Invalid ARIA attribute value"+(a.data&&a.data.length>1?"s":"")+":",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=" "+d;return b}}},"aria-valid-attr":{impact:"critical",messages:{pass:function(a){return"ARIA attribute name"+(a.data&&a.data.length>1?"s":"")+" are valid"},fail:function(a){var b="Invalid ARIA attribute name"+(a.data&&a.data.length>1?"s":"")+":",c=a.data;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+=" "+d;return b}}},caption:{impact:"critical",messages:{pass:function(a){return"The multimedia element has a captions track"},fail:function(a){return"The multimedia element does not have a captions track"},incomplete:function(a){return"A captions track for this element could not be found"}}},"is-on-screen":{impact:"serious",messages:{pass:function(a){return"Element is not visible"},fail:function(a){return"Element is visible"}}},"non-empty-if-present":{impact:"critical",messages:{pass:function(a){var b="Element ";return a.data?b+="has a non-empty value attribute":b+="does not have a value attribute",b},fail:function(a){return"Element has a value attribute and the value attribute is empty"}}},"non-empty-value":{impact:"critical",messages:{pass:function(a){return"Element has a non-empty value attribute"},fail:function(a){return"Element has no value attribute or the value attribute is empty"}}},"button-has-visible-text":{impact:"critical",messages:{pass:function(a){return"Element has inner text that is visible to screen readers"},fail:function(a){return"Element does not have inner text that is visible to screen readers"}}},"role-presentation":{impact:"minor",messages:{pass:function(a){return'Element\'s default semantics were overriden with role="presentation"'},fail:function(a){return'Element\'s default semantics were not overridden with role="presentation"'}}},"role-none":{impact:"minor",messages:{pass:function(a){return'Element\'s default semantics were overriden with role="none"'},fail:function(a){return'Element\'s default semantics were not overridden with role="none"'}}},"focusable-no-name":{impact:"serious",messages:{pass:function(a){return"Element is not in tab order or has accessible text"},fail:function(a){return"Element is in tab order and does not have accessible text"}}},"internal-link-present":{impact:"serious",messages:{pass:function(a){return"Valid skip link found"},fail:function(a){return"No valid skip link found"}}},"header-present":{impact:"serious",messages:{pass:function(a){return"Page has a header"},fail:function(a){return"Page does not have a header"}}},landmark:{impact:"serious",messages:{pass:function(a){return"Page has a landmark region"},fail:function(a){return"Page does not have a landmark region"}}},"group-labelledby":{impact:"critical",messages:{pass:function(a){return'All elements with the name "'+a.data.name+'" reference the same element with aria-labelledby'},fail:function(a){return'All elements with the name "'+a.data.name+'" do not reference the same element with aria-labelledby'}}},fieldset:{impact:"critical",messages:{pass:function(a){return"Element is contained in a fieldset"},fail:function(a){var b="",c=a.data&&a.data.failureCode;return b+="no-legend"===c?"Fieldset does not have a legend as its first child":"empty-legend"===c?"Legend does not have text that is visible to screen readers":"mixed-inputs"===c?"Fieldset contains unrelated inputs":"no-group-label"===c?"ARIA group does not have aria-label or aria-labelledby":"group-mixed-inputs"===c?"ARIA group contains unrelated inputs":"Element does not have a containing fieldset or ARIA group"}}},"color-contrast":{impact:"serious",messages:{pass:function(a){return"Element has sufficient color contrast of "+a.data.contrastRatio},fail:function(a){return"Element has insufficient color contrast of "+a.data.contrastRatio+" (foreground color: "+a.data.fgColor+", background color: "+a.data.bgColor+", font size: "+a.data.fontSize+", font weight: "+a.data.fontWeight+")"},incomplete:{bgImage:"Element's background color could not be determined due to a background image",bgGradient:"Element's background color could not be determined due to a background gradient",imgNode:"Element's background color could not be determined because element contains an image node",bgOverlap:"Element's background color could not be determined because it is overlapped by another element",fgAlpha:"Element's foreground color could not be determined because of alpha transparency",elmPartiallyObscured:"Element's background color could not be determined because it's partially obscured by another element",equalRatio:"Element has a 1:1 contrast ratio with the background",default:"Unable to determine contrast ratio"}}},"structured-dlitems":{impact:"serious",messages:{pass:function(a){return"When not empty, element has both <dt> and <dd> elements"},fail:function(a){return"When not empty, element does not have at least one <dt> element followed by at least one <dd> element"}}},"only-dlitems":{impact:"serious",messages:{pass:function(a){return"List element only has direct children that are allowed inside <dt> or <dd> elements"},fail:function(a){return"List element has direct children that are not allowed inside <dt> or <dd> elements"}}},dlitem:{impact:"serious",messages:{pass:function(a){return"Description list item has a <dl> parent element"},fail:function(a){return"Description list item does not have a <dl> parent element"}}},"doc-has-title":{impact:"serious",messages:{pass:function(a){return"Document has a non-empty <title> element"},fail:function(a){return"Document does not have a non-empty <title> element"}}},"duplicate-id":{impact:"moderate",messages:{pass:function(a){return"Document has no elements that share the same id attribute"},fail:function(a){return"Document has multiple elements with the same id attribute: "+a.data}}},"has-visible-text":{impact:"minor",messages:{pass:function(a){return"Element has text that is visible to screen readers"},fail:function(a){return"Element does not have text that is visible to screen readers"}}},"unique-frame-title":{impact:"serious",messages:{pass:function(a){return"Element's title attribute is unique"},fail:function(a){return"Element's title attribute is not unique"}}},"heading-order":{impact:"moderate",messages:{pass:function(a){return"Heading order valid"},fail:function(a){return"Heading order invalid"}}},"hidden-content":{impact:"minor",messages:{pass:function(a){return"All content on the page has been analyzed."},fail:function(a){return"There were problems analyzing the content on this page."},incomplete:function(a){return"There is hidden content on the page that was not analyzed. You will need to trigger the display of this content in order to analyze it."}}},"href-no-hash":{impact:"moderate",messages:{pass:function(a){return"Anchor does not have an href value of #"},fail:function(a){return"Anchor has an href value of #"}}},"has-lang":{impact:"serious",messages:{pass:function(a){return"The <html> element has a lang attribute"},fail:function(a){return"The <html> element does not have a lang attribute"}}},"valid-lang":{impact:"serious",messages:{pass:function(a){return"Value of lang attribute is included in the list of valid languages"},fail:function(a){return"Value of lang attribute not included in the list of valid languages"}}},"has-alt":{impact:"critical",messages:{pass:function(a){return"Element has an alt attribute"},fail:function(a){return"Element does not have an alt attribute"}}},"duplicate-img-label":{impact:"minor",messages:{pass:function(a){return"Element does not duplicate existing text in <img> alt text"},fail:function(a){return"Element contains <img> element with alt text that duplicates existing text"}}},"title-only":{impact:"serious",messages:{pass:function(a){return"Form element does not solely use title attribute for its label"},fail:function(a){return"Only title used to generate label for form element"}}},"implicit-label":{impact:"critical",messages:{pass:function(a){return"Form element has an implicit (wrapped) <label>"},fail:function(a){return"Form element does not have an implicit (wrapped) <label>"}}},"explicit-label":{impact:"critical",messages:{pass:function(a){return"Form element has an explicit <label>"},fail:function(a){return"Form element does not have an explicit <label>"}}},"help-same-as-label":{impact:"minor",messages:{pass:function(a){return"Help text (title or aria-describedby) does not duplicate label text"},fail:function(a){return"Help text (title or aria-describedby) text is the same as the label text"}}},"multiple-label":{impact:"serious",messages:{pass:function(a){return"Form element does not have multiple <label> elements"},fail:function(a){return"Form element has multiple <label> elements"}}},"has-th":{impact:"serious",messages:{pass:function(a){return"Layout table does not use <th> elements"},fail:function(a){return"Layout table uses <th> elements"}}},"has-caption":{impact:"serious",messages:{pass:function(a){return"Layout table does not use <caption> element"},fail:function(a){return"Layout table uses <caption> element"}}},"has-summary":{impact:"serious",messages:{pass:function(a){return"Layout table does not use summary attribute"},fail:function(a){return"Layout table uses summary attribute"}}},"link-in-text-block":{impact:"serious",messages:{pass:function(a){return"Links can be distinguished from surrounding text in a way that does not rely on color"},fail:function(a){return"Links can not be distinguished from surrounding text in a way that does not rely on color"},incomplete:{bgContrast:"Element's contrast ratio could not be determined. Check for a distinct hover/focus style",bgImage:"Element's contrast ratio could not be determined due to a background image",bgGradient:"Element's contrast ratio could not be determined due to a background gradient",imgNode:"Element's contrast ratio could not be determined because element contains an image node",bgOverlap:"Element's contrast ratio could not be determined because of element overlap",default:"Unable to determine contrast ratio"}}},"only-listitems":{impact:"serious",messages:{pass:function(a){return"List element only has direct children that are allowed inside <li> elements"},fail:function(a){return"List element has direct children that are not allowed inside <li> elements"}}},listitem:{impact:"serious",messages:{pass:function(a){return'List item has a <ul>, <ol> or role="list" parent element'},fail:function(a){return'List item does not have a <ul>, <ol> or role="list" parent element'}}},"meta-refresh":{impact:"critical",messages:{pass:function(a){return"<meta> tag does not immediately refresh the page"},fail:function(a){return"<meta> tag forces timed refresh of page"}}},"meta-viewport-large":{impact:"minor",messages:{pass:function(a){return"<meta> tag does not prevent significant zooming on mobile devices"},fail:function(a){return"<meta> tag limits zooming on mobile devices"}}},"meta-viewport":{impact:"critical",messages:{pass:function(a){return"<meta> tag does not disable zooming on mobile devices"},fail:function(a){return"<meta> tag disables zooming on mobile devices"}}},"p-as-heading":{impact:"serious",messages:{pass:function(a){return"<p> elements are not styled as headings"},fail:function(a){return"Heading elements should be used instead of styled p elements"}}},region:{impact:"moderate",messages:{pass:function(a){return"Content contained by ARIA landmark"},fail:function(a){return"Content not contained by an ARIA landmark"}}},"html5-scope":{impact:"moderate",messages:{pass:function(a){return"Scope attribute is only used on table header elements (<th>)"},fail:function(a){return"In HTML 5, scope attributes may only be used on table header elements (<th>)"}}},"scope-value":{impact:"critical",messages:{pass:function(a){return"Scope attribute is used correctly"},fail:function(a){return"The value of the scope attribute may only be 'row' or 'col'"}}},exists:{impact:"minor",messages:{pass:function(a){return"Element does not exist"},fail:function(a){return"Element exists"}}},"skip-link":{impact:"moderate",messages:{pass:function(a){return"Valid skip link found"},fail:function(a){return"No valid skip link found"}}},tabindex:{impact:"serious",messages:{pass:function(a){return"Element does not have a tabindex greater than 0"},fail:function(a){return"Element has a tabindex greater than 0"}}},"same-caption-summary":{impact:"minor",messages:{pass:function(a){return"Content of summary attribute and <caption> are not duplicated"},fail:function(a){return"Content of summary attribute and <caption> element are identical"}}},"caption-faked":{impact:"serious",messages:{pass:function(a){return"The first row of a table is not used as a caption"},fail:function(a){return"The first row of the table should be a caption instead of a table cell"}}},"td-has-header":{impact:"critical",messages:{pass:function(a){return"All non-empty data cells have table headers"},fail:function(a){return"Some non-empty data cells do not have table headers"}}},"td-headers-attr":{impact:"serious",messages:{pass:function(a){return"The headers attribute is exclusively used to refer to other cells in the table"},fail:function(a){return"The headers attribute is not exclusively used to refer to other cells in the table"}}},"th-has-data-cells":{impact:"serious",messages:{pass:function(a){return"All table header cells refer to data cells"},fail:function(a){return"Not all table header cells refer to data cells"},incomplete:function(a){return"Table data cells are missing or empty"}}},description:{impact:"critical",messages:{pass:function(a){
-return"The multimedia element has an audio description track"},fail:function(a){return"The multimedia element does not have an audio description track"},incomplete:function(a){return"An audio description track for this element could not be found"}}}},failureSummaries:{any:{failureMessage:function(a){var b="Fix any of the following:",c=a;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+="\n  "+d.split("\n").join("\n  ");return b}},none:{failureMessage:function(a){var b="Fix all of the following:",c=a;if(c)for(var d,e=-1,f=c.length-1;e<f;)d=c[e+=1],b+="\n  "+d.split("\n").join("\n  ");return b}}},incompleteFallbackMessage:function(a){return"aXe couldn't tell the reason. Time to break out the element inspector!"}},rules:[{id:"accesskeys",selector:"[accesskey]",excludeHidden:!1,tags:["wcag2a","wcag211","cat.keyboard"],all:[],any:[],none:["accesskeys"]},{id:"area-alt",selector:"map area[href]",excludeHidden:!1,tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["non-empty-alt","non-empty-title","aria-label","aria-labelledby"],none:[]},{id:"aria-allowed-attr",matches:function(a,b){var c=a.getAttribute("role");c||(c=axe.commons.aria.implicitRole(a));var d=axe.commons.aria.allowedAttr(c);if(c&&d){var e=/^aria-/;if(a.hasAttributes())for(var f=a.attributes,g=0,h=f.length;g<h;g++)if(e.test(f[g].name))return!0}return!1},tags:["cat.aria","wcag2a","wcag411","wcag412"],all:[],any:["aria-allowed-attr"],none:[]},{id:"aria-hidden-body",selector:"body",excludeHidden:!1,tags:["cat.aria","wcag2a","wcag412"],all:[],any:["aria-hidden-body"],none:[]},{id:"aria-required-attr",selector:"[role]",tags:["cat.aria","wcag2a","wcag411","wcag412"],all:[],any:["aria-required-attr"],none:[]},{id:"aria-required-children",selector:"[role]",tags:["cat.aria","wcag2a","wcag131"],all:[],any:["aria-required-children"],none:[]},{id:"aria-required-parent",selector:"[role]",tags:["cat.aria","wcag2a","wcag131"],all:[],any:["aria-required-parent"],none:[]},{id:"aria-roles",selector:"[role]",tags:["cat.aria","wcag2a","wcag131","wcag411","wcag412"],all:[],any:[],none:["invalidrole","abstractrole"]},{id:"aria-valid-attr-value",matches:function(a,b){var c=/^aria-/;if(a.hasAttributes())for(var d=a.attributes,e=0,f=d.length;e<f;e++)if(c.test(d[e].name))return!0;return!1},tags:["cat.aria","wcag2a","wcag131","wcag411","wcag412"],all:[],any:[{options:[],id:"aria-valid-attr-value"}],none:[]},{id:"aria-valid-attr",matches:function(a,b){var c=/^aria-/;if(a.hasAttributes())for(var d=a.attributes,e=0,f=d.length;e<f;e++)if(c.test(d[e].name))return!0;return!1},tags:["cat.aria","wcag2a","wcag411"],all:[],any:[{options:[],id:"aria-valid-attr"}],none:[]},{id:"audio-caption",selector:"audio",excludeHidden:!1,tags:["cat.time-and-media","wcag2a","wcag122","section508","section508.22.a"],all:[],any:[],none:["caption"]},{id:"blink",selector:"blink",excludeHidden:!1,tags:["cat.time-and-media","wcag2a","wcag222","section508","section508.22.j"],all:[],any:[],none:["is-on-screen"]},{id:"button-name",selector:'button, [role="button"], input[type="button"], input[type="submit"], input[type="reset"]',tags:["cat.name-role-value","wcag2a","wcag412","section508","section508.22.a"],all:[],any:["non-empty-if-present","non-empty-value","button-has-visible-text","aria-label","aria-labelledby","role-presentation","role-none"],none:["focusable-no-name"]},{id:"bypass",selector:"html",pageLevel:!0,matches:function(a,b){return!!a.querySelector("a[href]")},tags:["cat.keyboard","wcag2a","wcag241","section508","section508.22.o"],all:[],any:["internal-link-present","header-present","landmark"],none:[]},{id:"checkboxgroup",selector:"input[type=checkbox][name]",tags:["cat.forms","best-practice"],all:[],any:["group-labelledby","fieldset"],none:[]},{id:"color-contrast",matches:function(a,b){var c=a.nodeName.toUpperCase(),d=a.type;if("true"===a.getAttribute("aria-disabled")||axe.commons.dom.findUp(a,'[aria-disabled="true"]'))return!1;if("INPUT"===c)return-1===["hidden","range","color","checkbox","radio","image"].indexOf(d)&&!a.disabled;if("SELECT"===c)return!!a.options.length&&!a.disabled;if("TEXTAREA"===c)return!a.disabled;if("OPTION"===c)return!1;if("BUTTON"===c&&a.disabled||axe.commons.dom.findUp(a,"button[disabled]"))return!1;if("FIELDSET"===c&&a.disabled||axe.commons.dom.findUp(a,"fieldset[disabled]"))return!1;var e=axe.commons.dom.findUp(a,"label");if("LABEL"===c||e){var f=a;e&&(f=e);var g=axe.commons.dom.getRootNode(f),h=f.htmlFor&&g.getElementById(f.htmlFor);if(h&&h.disabled)return!1;var h=axe.utils.querySelectorAll(b,'input:not([type="hidden"]):not([type="image"]):not([type="button"]):not([type="submit"]):not([type="reset"]), select, textarea');if(h.length&&h[0].actualNode.disabled)return!1}if(a.getAttribute("id")){var i=axe.commons.utils.escapeSelector(a.getAttribute("id")),j=axe.commons.dom.getRootNode(a),h=j.querySelector("[aria-labelledby~="+i+"]");if(h&&h.disabled)return!1}if(""===axe.commons.text.visible(b,!1,!0))return!1;var k,l,m=document.createRange(),n=b.children,o=n.length;for(l=0;l<o;l++)k=n[l],3===k.actualNode.nodeType&&""!==axe.commons.text.sanitize(k.actualNode.nodeValue)&&m.selectNodeContents(k.actualNode);var p=m.getClientRects();for(o=p.length,l=0;l<o;l++)if(axe.commons.dom.visuallyOverlaps(p[l],a))return!0;return!1},excludeHidden:!1,options:{noScroll:!1},tags:["cat.color","wcag2aa","wcag143"],all:[],any:["color-contrast"],none:[]},{id:"definition-list",selector:"dl",matches:function(a,b){return!a.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:[],none:["structured-dlitems","only-dlitems"]},{id:"dlitem",selector:"dd, dt",matches:function(a,b){return!a.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:["dlitem"],none:[]},{id:"document-title",selector:"html",matches:function(a,b){return a.ownerDocument.defaultView.self===a.ownerDocument.defaultView.top},tags:["cat.text-alternatives","wcag2a","wcag242"],all:[],any:["doc-has-title"],none:[]},{id:"duplicate-id",selector:"[id]",excludeHidden:!1,tags:["cat.parsing","wcag2a","wcag411"],all:[],any:["duplicate-id"],none:[]},{id:"empty-heading",selector:'h1, h2, h3, h4, h5, h6, [role="heading"]',enabled:!0,tags:["cat.name-role-value","best-practice"],all:[],any:["has-visible-text","role-presentation","role-none"],none:[]},{id:"frame-title-unique",selector:"frame[title], iframe[title]",matches:function(a,b){var c=a.getAttribute("title");return!!(c?axe.commons.text.sanitize(c).trim():"")},tags:["cat.text-alternatives","best-practice"],all:[],any:[],none:["unique-frame-title"]},{id:"frame-title",selector:"frame, iframe",tags:["cat.text-alternatives","wcag2a","wcag241","section508","section508.22.i"],all:[],any:["aria-label","aria-labelledby","non-empty-title","role-presentation","role-none"],none:[]},{id:"heading-order",selector:"h1,h2,h3,h4,h5,h6,[role=heading]",enabled:!1,tags:["cat.semantics","best-practice"],all:[],any:["heading-order"],none:[]},{id:"hidden-content",selector:"*",excludeHidden:!1,tags:["experimental","review-item"],all:[],any:["hidden-content"],none:[],enabled:!1},{id:"href-no-hash",selector:"a[href]",enabled:!1,tags:["cat.semantics","best-practice"],all:[],any:["href-no-hash"],none:[]},{id:"html-has-lang",selector:"html",tags:["cat.language","wcag2a","wcag311"],all:[],any:["has-lang"],none:[]},{id:"html-lang-valid",selector:"html[lang]",tags:["cat.language","wcag2a","wcag311"],all:[],any:[],none:["valid-lang"]},{id:"image-alt",selector:"img, [role='img']",tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["has-alt","aria-label","aria-labelledby","non-empty-title","role-presentation","role-none"],none:[]},{id:"image-redundant-alt",selector:'button, [role="button"], a[href], p, li, td, th',tags:["cat.text-alternatives","best-practice"],all:[],any:[],none:["duplicate-img-label"]},{id:"input-image-alt",selector:'input[type="image"]',tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["non-empty-alt","aria-label","aria-labelledby","non-empty-title"],none:[]},{id:"label-title-only",selector:"input, select, textarea",matches:function(a,b){if("input"!==a.nodeName.toLowerCase())return!0;var c=a.getAttribute("type").toLowerCase();return"hidden"!==c&&"image"!==c&&"button"!==c&&"submit"!==c&&"reset"!==c},enabled:!1,tags:["cat.forms","best-practice"],all:[],any:[],none:["title-only"]},{id:"label",selector:"input, select, textarea",matches:function(a,b){if("input"!==a.nodeName.toLowerCase())return!0;var c=a.getAttribute("type").toLowerCase();return"hidden"!==c&&"image"!==c&&"button"!==c&&"submit"!==c&&"reset"!==c},tags:["cat.forms","wcag2a","wcag332","wcag131","section508","section508.22.n"],all:[],any:["aria-label","aria-labelledby","implicit-label","explicit-label","non-empty-title"],none:["help-same-as-label","multiple-label"]},{id:"layout-table",selector:"table",matches:function(a,b){return!axe.commons.table.isDataTable(a)},tags:["cat.semantics","wcag2a","wcag131"],all:[],any:[],none:["has-th","has-caption","has-summary"]},{id:"link-in-text-block",selector:"a[href], *[role=link]",matches:function(a,b){var c=axe.commons.text.sanitize(a.textContent),d=a.getAttribute("role");return(!d||"link"===d)&&(!!c&&(!!axe.commons.dom.isVisible(a,!1)&&axe.commons.dom.isInTextBlock(a)))},excludeHidden:!1,tags:["cat.color","experimental","wcag2a","wcag141"],all:["link-in-text-block"],any:[],none:[]},{id:"link-name",selector:"a[href], [role=link][href]",matches:function(a,b){return"button"!==a.getAttribute("role")},tags:["cat.name-role-value","wcag2a","wcag111","wcag412","wcag244","section508","section508.22.a"],all:[],any:["has-visible-text","aria-label","aria-labelledby","role-presentation","role-none"],none:["focusable-no-name"]},{id:"list",selector:"ul, ol",matches:function(a,b){return!a.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:[],none:["only-listitems"]},{id:"listitem",selector:"li",matches:function(a,b){return!a.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:["listitem"],none:[]},{id:"marquee",selector:"marquee",excludeHidden:!1,tags:["cat.parsing","wcag2a","wcag222"],all:[],any:[],none:["is-on-screen"]},{id:"meta-refresh",selector:'meta[http-equiv="refresh"]',excludeHidden:!1,tags:["cat.time","wcag2a","wcag2aaa","wcag221","wcag224","wcag325"],all:[],any:["meta-refresh"],none:[]},{id:"meta-viewport-large",selector:'meta[name="viewport"]',excludeHidden:!1,tags:["cat.sensory-and-visual-cues","best-practice"],all:[],any:[{options:{scaleMinimum:5,lowerBound:2},id:"meta-viewport-large"}],none:[]},{id:"meta-viewport",selector:'meta[name="viewport"]',excludeHidden:!1,tags:["cat.sensory-and-visual-cues","wcag2aa","wcag144"],all:[],any:[{options:{scaleMinimum:2},id:"meta-viewport"}],none:[]},{id:"object-alt",selector:"object",tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["has-visible-text","aria-label","aria-labelledby","non-empty-title"],none:[]},{id:"p-as-heading",selector:"p",matches:function(a,b){var c=Array.from(a.parentNode.childNodes),d=a.textContent.trim(),e=/[.!?:;](?![.!?:;])/g;return!(0===d.length||(d.match(e)||[]).length>=2)&&0!==c.slice(c.indexOf(a)+1).filter(function(a){return"P"===a.nodeName.toUpperCase()&&""!==a.textContent.trim()}).length},tags:["cat.semantics","wcag2a","wcag131","experimental"],all:[{options:{margins:[{weight:150,italic:!0},{weight:150,size:1.15},{italic:!0,size:1.15},{size:1.4}]},id:"p-as-heading"}],any:[],none:[]},{id:"radiogroup",selector:"input[type=radio][name]",tags:["cat.forms","best-practice"],all:[],any:["group-labelledby","fieldset"],none:[]},{id:"region",selector:"html",pageLevel:!0,enabled:!1,tags:["cat.keyboard","best-practice"],all:[],any:["region"],none:[]},{id:"scope-attr-valid",selector:"td[scope], th[scope]",enabled:!0,tags:["cat.tables","best-practice"],all:["html5-scope","scope-value"],any:[],none:[]},{id:"server-side-image-map",selector:"img[ismap]",tags:["cat.text-alternatives","wcag2a","wcag211","section508","section508.22.f"],all:[],any:[],none:["exists"]},{id:"skip-link",selector:"a[href]",pageLevel:!0,enabled:!1,tags:["cat.keyboard","best-practice"],all:[],any:["skip-link"],none:[]},{id:"tabindex",selector:"[tabindex]",tags:["cat.keyboard","best-practice"],all:[],any:["tabindex"],none:[]},{id:"table-duplicate-name",selector:"table",tags:["cat.tables","best-practice"],all:[],any:[],none:["same-caption-summary"]},{id:"table-fake-caption",selector:"table",matches:function(a,b){return axe.commons.table.isDataTable(a)},tags:["cat.tables","experimental","wcag2a","wcag131","section508","section508.22.g"],all:["caption-faked"],any:[],none:[]},{id:"td-has-header",selector:"table",matches:function(a,b){if(axe.commons.table.isDataTable(a)){var c=axe.commons.table.toArray(a);return c.length>=3&&c[0].length>=3&&c[1].length>=3&&c[2].length>=3}return!1},tags:["cat.tables","experimental","wcag2a","wcag131","section508","section508.22.g"],all:["td-has-header"],any:[],none:[]},{id:"td-headers-attr",selector:"table",tags:["cat.tables","wcag2a","wcag131","section508","section508.22.g"],all:["td-headers-attr"],any:[],none:[]},{id:"th-has-data-cells",selector:"table",matches:function(a,b){return axe.commons.table.isDataTable(a)},tags:["cat.tables","wcag2a","wcag131","section508","section508.22.g"],all:["th-has-data-cells"],any:[],none:[]},{id:"valid-lang",selector:"[lang], [xml\\:lang]",matches:function(a,b){return"html"!==a.nodeName.toLowerCase()},tags:["cat.language","wcag2aa","wcag312"],all:[],any:[],none:["valid-lang"]},{id:"video-caption",selector:"video",excludeHidden:!1,tags:["cat.text-alternatives","wcag2a","wcag122","wcag123","section508","section508.22.a"],all:[],any:[],none:["caption"]},{id:"video-description",selector:"video",excludeHidden:!1,tags:["cat.text-alternatives","wcag2aa","wcag125","section508","section508.22.b"],all:[],any:[],none:["description"]}],checks:[{id:"abstractrole",evaluate:function(a,b,c){return"abstract"===axe.commons.aria.getRoleType(a.getAttribute("role"))}},{id:"aria-allowed-attr",evaluate:function(a,b,c){var d,e,f,g=[],h=a.getAttribute("role"),i=a.attributes;if(h||(h=axe.commons.aria.implicitRole(a)),f=axe.commons.aria.allowedAttr(h),h&&f)for(var j=0,k=i.length;j<k;j++)d=i[j],e=d.name,axe.commons.aria.validateAttr(e)&&-1===f.indexOf(e)&&g.push(e+'="'+d.nodeValue+'"');return!g.length||(this.data(g),!1)}},{id:"aria-hidden-body",evaluate:function(a,b,c){return"true"!==a.getAttribute("aria-hidden")}},{id:"invalidrole",evaluate:function(a,b,c){return!axe.commons.aria.isValidRole(a.getAttribute("role"))}},{id:"aria-required-attr",evaluate:function(a,b,c){var d=[];if(a.hasAttributes()){var e,f=a.getAttribute("role"),g=axe.commons.aria.requiredAttr(f);if(f&&g)for(var h=0,i=g.length;h<i;h++)e=g[h],a.getAttribute(e)||d.push(e)}return!d.length||(this.data(d),!1)}},{id:"aria-required-children",evaluate:function(a,b,c){function d(a,b,c,d){if(null===a)return!1;var e=g(c),f=['[role="'+c+'"]'];return e&&(f=f.concat(e)),f=f.join(","),d?h(a,f)||!!axe.utils.querySelectorAll(b,f)[0]:!!axe.utils.querySelectorAll(b,f)[0]}function e(a,b){var c,e;for(c=0,e=a.length;c<e;c++)if(null!==a[c]){var f=axe.utils.getNodeFromTree(axe._tree[0],a[c]);if(d(a[c],f,b,!0))return!0}return!1}var f=axe.commons.aria.requiredOwned,g=axe.commons.aria.implicitNodes,h=axe.commons.utils.matchesSelector,i=axe.commons.dom.idrefs,j=a.getAttribute("role"),k=f(j);if(!k)return!0;var l=!1,m=k.one;if(!m){var l=!0;m=k.all}var n=function(a,b,f){var g,h=b.length,j=[],k=i(a,"aria-owns");for(g=0;g<h;g++){var l=b[g];if(d(a,c,l)||e(k,l)){if(!f)return null}else f&&j.push(l)}return j.length?j:!f&&b.length?b:null}(a,m,l);return!n||(this.data(n),!1)}},{id:"aria-required-parent",evaluate:function(a,b,c){function d(a){return(axe.commons.aria.implicitNodes(a)||[]).concat('[role="'+a+'"]').join(",")}function e(a,b,c){var e,f,g=a.getAttribute("role"),h=[];if(b||(b=axe.commons.aria.requiredContext(g)),!b)return null;for(e=0,f=b.length;e<f;e++){if(c&&axe.utils.matchesSelector(a,d(b[e])))return null;if(axe.commons.dom.findUp(a,d(b[e])))return null;h.push(b[e])}return h}var f=e(a);if(!f)return!0;var g=function(a){for(var b=[],c=null;a;){if(a.getAttribute("id")){var d=axe.commons.utils.escapeSelector(a.getAttribute("id"));c=axe.commons.dom.getRootNode(a).querySelector("[aria-owns~="+d+"]"),c&&b.push(c)}a=a.parentElement}return b.length?b:null}(a);if(g)for(var h=0,i=g.length;h<i;h++)if(!(f=e(g[h],f,!0)))return!0;return this.data(f),!1}},{id:"aria-valid-attr-value",evaluate:function(a,b,c){b=Array.isArray(b)?b:[];for(var d,e,f=[],g=/^aria-/,h=a.attributes,i=0,j=h.length;i<j;i++)d=h[i],e=d.name,-1===b.indexOf(e)&&g.test(e)&&!axe.commons.aria.validateAttrValue(a,e)&&f.push(e+'="'+d.nodeValue+'"');return!f.length||(this.data(f),!1)},options:[]},{id:"aria-valid-attr",evaluate:function(a,b,c){b=Array.isArray(b)?b:[];for(var d,e=[],f=/^aria-/,g=a.attributes,h=0,i=g.length;h<i;h++)d=g[h].name,-1===b.indexOf(d)&&f.test(d)&&!axe.commons.aria.validateAttr(d)&&e.push(d);return!e.length||(this.data(e),!1)},options:[]},{id:"color-contrast",evaluate:function(a,b,c){if(!axe.commons.dom.isVisible(a,!1))return!0;var d,e=!!(b||{}).noScroll,f=[],g=axe.commons.color.getBackgroundColor(a,f,e),h=axe.commons.color.getForegroundColor(a,e),i=window.getComputedStyle(a),j=parseFloat(i.getPropertyValue("font-size")),k=i.getPropertyValue("font-weight"),l=-1!==["bold","bolder","600","700","800","900"].indexOf(k),m=axe.commons.color.hasValidContrastRatio(g,h,j,l),n=Math.floor(100*m.contrastRatio)/100;null===g&&(d=axe.commons.color.incompleteData.get("bgColor"));var o=!1;1===n&&(o=!0,d=axe.commons.color.incompleteData.set("bgColor","equalRatio"));var p={fgColor:h?h.toHexString():void 0,bgColor:g?g.toHexString():void 0,contrastRatio:m?n:void 0,fontSize:(72*j/96).toFixed(1)+"pt",fontWeight:l?"bold":"normal",missingData:d};return this.data(p),null===h||null===g||o?(d=null,axe.commons.color.incompleteData.clear(),void this.relatedNodes(f)):(m.isValid||this.relatedNodes(f),m.isValid)}},{id:"link-in-text-block",evaluate:function(a,b,c){function d(a,b){var c=a.getRelativeLuminance(),d=b.getRelativeLuminance();return(Math.max(c,d)+.05)/(Math.min(c,d)+.05)}function e(a){var b=window.getComputedStyle(a).getPropertyValue("display");return-1!==i.indexOf(b)||"table-"===b.substr(0,6)}var f=axe.commons,g=f.color,h=f.dom,i=["block","list-item","table","flex","grid","inline-block"];if(e(a))return!1;for(var j=h.getComposedParent(a);1===j.nodeType&&!e(j);)j=h.getComposedParent(j);if(this.relatedNodes([j]),g.elementIsDistinct(a,j))return!0;var k,l;if(k=g.getForegroundColor(a),l=g.getForegroundColor(j),k&&l){var m=d(k,l);if(1===m)return!0;if(m>=3)return axe.commons.color.incompleteData.set("fgColor","bgContrast"),this.data({missingData:axe.commons.color.incompleteData.get("fgColor")}),void axe.commons.color.incompleteData.clear();if(k=g.getBackgroundColor(a),l=g.getBackgroundColor(j),!k||!l||d(k,l)>=3){var n=void 0;return n=k&&l?"bgContrast":axe.commons.color.incompleteData.get("bgColor"),axe.commons.color.incompleteData.set("fgColor",n),this.data({missingData:axe.commons.color.incompleteData.get("fgColor")}),void axe.commons.color.incompleteData.clear()}return!1}}},{id:"fieldset",evaluate:function(a,b,c){function d(a,b){return axe.commons.utils.toArray(a.querySelectorAll('select,textarea,button,input:not([name="'+b+'"]):not([type="hidden"])'))}function e(a,b){var c=a.firstElementChild;if(!c||"LEGEND"!==c.nodeName.toUpperCase())return i.relatedNodes([a]),h="no-legend",!1;if(!axe.commons.text.accessibleText(c))return i.relatedNodes([c]),h="empty-legend",!1;var e=d(a,b);return!e.length||(i.relatedNodes(e),h="mixed-inputs",!1)}function f(a,b){var c=axe.commons.dom.idrefs(a,"aria-labelledby").some(function(a){return a&&axe.commons.text.accessibleText(a)}),e=a.getAttribute("aria-label");if(!(c||e&&axe.commons.text.sanitize(e)))return i.relatedNodes(a),h="no-group-label",!1;var f=d(a,b);return!f.length||(i.relatedNodes(f),h="group-mixed-inputs",!1)}function g(a,b){return axe.commons.utils.toArray(a).filter(function(a){return a!==b})}var h,i=this,j={name:a.getAttribute("name"),type:a.getAttribute("type")},k=function(b){var c=axe.commons.utils.escapeSelector(a.name),d=axe.commons.dom.getRootNode(a),j=d.querySelectorAll('input[type="'+axe.commons.utils.escapeSelector(a.type)+'"][name="'+c+'"]');if(j.length<2)return!0;var k=axe.commons.dom.findUp(b,"fieldset"),l=axe.commons.dom.findUp(b,'[role="group"]'+("radio"===a.type?',[role="radiogroup"]':""));return l||k?k?e(k,c):f(l,c):(h="no-group",i.relatedNodes(g(j,b)),!1)}(a);return k||(j.failureCode=h),this.data(j),k},after:function(a,b){var c={};return a.filter(function(a){if(a.result)return!0;var b=a.data;if(b){if(c[b.type]=c[b.type]||{},!c[b.type][b.name])return c[b.type][b.name]=[b],!0;var d=c[b.type][b.name].some(function(a){return a.failureCode===b.failureCode});return d||c[b.type][b.name].push(b),!d}return!1})}},{id:"group-labelledby",evaluate:function(a,b,c){this.data({name:a.getAttribute("name"),type:a.getAttribute("type")});var d=axe.commons.dom.getRootNode(a),e=d.querySelectorAll('input[type="'+axe.commons.utils.escapeSelector(a.type)+'"][name="'+axe.commons.utils.escapeSelector(a.name)+'"]');return e.length<=1||0!==[].map.call(e,function(a){var b=a.getAttribute("aria-labelledby");return b?b.split(/\s+/):[]}).reduce(function(a,b){return a.filter(function(a){return b.includes(a)})}).filter(function(a){var b=d.getElementById(a);return b&&axe.commons.text.accessibleText(b)}).length},after:function(a,b){var c={};return a.filter(function(a){var b=a.data;return!(!b||(c[b.type]=c[b.type]||{},c[b.type][b.name]))&&(c[b.type][b.name]=!0,!0)})}},{id:"accesskeys",evaluate:function(a,b,c){return axe.commons.dom.isVisible(a,!1)&&(this.data(a.getAttribute("accesskey")),this.relatedNodes([a])),!0},after:function(a,b){var c={};return a.filter(function(a){if(!a.data)return!1;var b=a.data.toUpperCase();return c[b]?(c[b].relatedNodes.push(a.relatedNodes[0]),!1):(c[b]=a,a.relatedNodes=[],!0)}).map(function(a){return a.result=!!a.relatedNodes.length,a})}},{id:"focusable-no-name",evaluate:function(a,b,c){var d=a.getAttribute("tabindex");return!!(axe.commons.dom.isFocusable(a)&&d>-1)&&!axe.commons.text.accessibleText(a)}},{id:"tabindex",evaluate:function(a,b,c){return a.tabIndex<=0}},{id:"duplicate-img-label",evaluate:function(a,b,c){var d=axe.commons.text.visible(c,!0).toLowerCase();return""!==d&&axe.utils.querySelectorAll(c,"img").filter(function(a){var b=a.actualNode;return axe.commons.dom.isVisible(b)&&!["none","presentation"].includes(b.getAttribute("role"))}).some(function(a){return d===axe.commons.text.accessibleText(a).toLowerCase()})}},{id:"explicit-label",evaluate:function(a,b,c){if(a.getAttribute("id")){var d=axe.commons.dom.getRootNode(a),e=axe.commons.utils.escapeSelector(a.getAttribute("id")),f=d.querySelector('label[for="'+e+'"]');if(f)return!!axe.commons.text.accessibleText(f)}return!1}},{id:"help-same-as-label",evaluate:function(a,b,c){var d=axe.commons.text.label(c),e=a.getAttribute("title");if(!d)return!1;if(!e&&(e="",a.getAttribute("aria-describedby"))){e=axe.commons.dom.idrefs(a,"aria-describedby").map(function(a){return a?axe.commons.text.accessibleText(a):""}).join("")}return axe.commons.text.sanitize(e)===axe.commons.text.sanitize(d)},enabled:!1},{id:"implicit-label",evaluate:function(a,b,c){var d=axe.commons.dom.findUp(a,"label");return!!d&&!!axe.commons.text.accessibleText(d)}},{id:"multiple-label",evaluate:function(a,b,c){var d=axe.commons.utils.escapeSelector(a.getAttribute("id")),e=Array.from(document.querySelectorAll('label[for="'+d+'"]')),f=a.parentNode;for(e.length&&(e=e.filter(function(a,b){if(0===b&&!axe.commons.dom.isVisible(a,!0)||axe.commons.dom.isVisible(a,!0))return a}));f;)"LABEL"===f.tagName&&-1===e.indexOf(f)&&e.push(f),f=f.parentNode;return this.relatedNodes(e),e.length>1}},{id:"title-only",evaluate:function(a,b,c){return!(axe.commons.text.label(c)||!a.getAttribute("title")&&!a.getAttribute("aria-describedby"))}},{id:"has-lang",evaluate:function(a,b,c){return!!(a.getAttribute("lang")||a.getAttribute("xml:lang")||"").trim()}},{id:"valid-lang",evaluate:function(a,b,c){function d(a){return a.trim().split("-")[0].toLowerCase()}var e,f;return e=(b||axe.commons.utils.validLangs()).map(d),f=["lang","xml:lang"].reduce(function(b,c){var f=a.getAttribute(c);if("string"!=typeof f)return b;var g=d(f);return""!==g&&-1===e.indexOf(g)&&b.push(c+'="'+a.getAttribute(c)+'"'),b},[]),!!f.length&&(this.data(f),!0)}},{id:"dlitem",evaluate:function(a,b,c){return"DL"===axe.commons.dom.getComposedParent(a).nodeName.toUpperCase()}},{id:"has-listitem",evaluate:function(a,b,c){return c.children.every(function(a){return"LI"!==a.actualNode.nodeName.toUpperCase()})}},{id:"listitem",evaluate:function(a,b,c){var d=axe.commons.dom.getComposedParent(a);return["UL","OL"].includes(d.nodeName.toUpperCase())||"list"===(d.getAttribute("role")||"").toLowerCase()}},{id:"only-dlitems",evaluate:function(a,b,c){var d=[],e=["STYLE","META","LINK","MAP","AREA","SCRIPT","DATALIST","TEMPLATE"],f=!1;return c.children.forEach(function(a){var b=a.actualNode,c=b.nodeName.toUpperCase();1===b.nodeType&&"DT"!==c&&"DD"!==c&&-1===e.indexOf(c)?d.push(b):3===b.nodeType&&""!==b.nodeValue.trim()&&(f=!0)}),d.length&&this.relatedNodes(d),!!d.length||f}},{id:"only-listitems",evaluate:function(a,b,c){var d=[],e=["STYLE","META","LINK","MAP","AREA","SCRIPT","DATALIST","TEMPLATE"],f=!1;return c.children.forEach(function(a){var b=a.actualNode,c=b.nodeName.toUpperCase();1===b.nodeType&&"LI"!==c&&-1===e.indexOf(c)?d.push(b):3===b.nodeType&&""!==b.nodeValue.trim()&&(f=!0)}),d.length&&this.relatedNodes(d),!!d.length||f}},{id:"structured-dlitems",evaluate:function(a,b,c){var d=c.children;if(!d||!d.length)return!1;for(var e,f=!1,g=!1,h=0;h<d.length;h++){if(e=d[h].actualNode.nodeName.toUpperCase(),"DT"===e&&(f=!0),f&&"DD"===e)return!1;"DD"===e&&(g=!0)}return f||g}},{id:"caption",evaluate:function(a,b,c){var d=axe.utils.querySelectorAll(c,"track");if(d.length)return!d.some(function(a){return"captions"===(a.actualNode.getAttribute("kind")||"").toLowerCase()})}},{id:"description",evaluate:function(a,b,c){var d=axe.utils.querySelectorAll(c,"track");if(d.length){var e=!d.some(function(a){return"descriptions"===(a.actualNode.getAttribute("kind")||"").toLowerCase()});return axe.log(d.map(function(a){return a.actualNode.getAttribute("kind")}),e),e}}},{id:"meta-viewport-large",evaluate:function(a,b,c){b=b||{};for(var d,e=a.getAttribute("content")||"",f=e.split(/[;,]/),g={},h=b.scaleMinimum||2,i=b.lowerBound||!1,j=0,k=f.length;j<k;j++){d=f[j].split("=");var l=d.shift().toLowerCase();l&&d.length&&(g[l.trim()]=d.shift().trim().toLowerCase())}return!!(i&&g["maximum-scale"]&&parseFloat(g["maximum-scale"])<i)||!(!i&&"no"===g["user-scalable"])&&!(g["maximum-scale"]&&parseFloat(g["maximum-scale"])<h)},options:{scaleMinimum:5,lowerBound:2}},{id:"meta-viewport",evaluate:function(a,b,c){b=b||{};for(var d,e=a.getAttribute("content")||"",f=e.split(/[;,]/),g={},h=b.scaleMinimum||2,i=b.lowerBound||!1,j=0,k=f.length;j<k;j++){d=f[j].split("=");var l=d.shift().toLowerCase();l&&d.length&&(g[l.trim()]=d.shift().trim().toLowerCase())}return!!(i&&g["maximum-scale"]&&parseFloat(g["maximum-scale"])<i)||!(!i&&"no"===g["user-scalable"])&&!(g["maximum-scale"]&&parseFloat(g["maximum-scale"])<h)},options:{scaleMinimum:2}},{id:"header-present",evaluate:function(a,b,c){return!!a.querySelector('h1, h2, h3, h4, h5, h6, [role="heading"]')}},{id:"heading-order",evaluate:function(a,b,c){var d=a.getAttribute("aria-level");if(null!==d)return this.data(parseInt(d,10)),!0;var e=a.tagName.match(/H(\d)/);return!e||(this.data(parseInt(e[1],10)),!0)},after:function(a,b){if(a.length<2)return a;for(var c=a[0].data,d=1;d<a.length;d++)a[d].result&&a[d].data>c+1&&(a[d].result=!1),c=a[d].data;return a}},{id:"href-no-hash",evaluate:function(a,b,c){return"#"!==a.getAttribute("href")}},{id:"internal-link-present",evaluate:function(a,b,c){return!!a.querySelector('a[href^="#"]')}},{id:"landmark",evaluate:function(a,b,c){return axe.utils.querySelectorAll(c,'main, [role="main"]').length>0}},{id:"meta-refresh",evaluate:function(a,b,c){var d=a.getAttribute("content")||"",e=d.split(/[;,]/);return""===d||"0"===e[0]}},{id:"p-as-heading",evaluate:function(a,b,c){function d(a){for(var b=a,c=a.textContent.trim(),d=c;d===c&&void 0!==b;){var e=-1;if(a=b,0===a.children.length)return a;do{e++,d=a.children[e].textContent.trim()}while(""===d&&e+1<a.children.length);b=a.children[e]}return a}function e(a){switch(a){case"lighter":return 100;case"normal":return 400;case"bold":return 700;case"bolder":return 900}return a=parseInt(a),isNaN(a)?400:a}function f(a){var b=window.getComputedStyle(d(a));return{fontWeight:e(b.getPropertyValue("font-weight")),fontSize:parseInt(b.getPropertyValue("font-size")),isItalic:"italic"===b.getPropertyValue("font-style")}}function g(a,b,c){return c.reduce(function(c,d){return c||(!d.size||a.fontSize/d.size>b.fontSize)&&(!d.weight||a.fontWeight-d.weight>b.fontWeight)&&(!d.italic||a.isItalic&&!b.isItalic)},!1)}var h=Array.from(a.parentNode.children),i=h.indexOf(a);b=b||{};var j=b.margins||[],k=h.slice(i+1).find(function(a){return"P"===a.nodeName.toUpperCase()}),l=h.slice(0,i).reverse().find(function(a){return"P"===a.nodeName.toUpperCase()}),m=f(a),n=k?f(k):null,o=l?f(l):null;if(!n||!g(m,n,j))return!0;var p=axe.commons.dom.findUp(a,"blockquote");return!!(p&&"BLOCKQUOTE"===p.nodeName.toUpperCase()||o&&!g(m,o,j))&&void 0},options:{margins:[{weight:150,italic:!0},{weight:150,size:1.15},{italic:!0,size:1.15},{size:1.4}]}},{id:"region",evaluate:function(a,b,c){function d(a){return j&&j===a}function e(a){return a.hasAttribute("role")?k.includes(a.getAttribute("role").toLowerCase()):l.includes(a.nodeName.toUpperCase())}function f(a){var b=a.actualNode;return e(b)||d(b)||!h.isVisible(b,!0)?[]:h.hasContent(b,!0)?[b]:a.children.filter(function(a){return 1===a.actualNode.nodeType}).map(f).reduce(function(a,b){return a.concat(b)},[])}var g=axe.commons,h=g.dom,i=g.aria,j=function(a){var b=axe.utils.querySelectorAll(a,"a[href]")[0];if(b&&axe.commons.dom.getElementByReference(b.actualNode,"href"))return b.actualNode}(c),k=i.getRolesByType("landmark"),l=k.reduce(function(a,b){return a.concat(i.implicitNodes(b))},[]).filter(function(a){return null!==a}).map(function(a){return a.toUpperCase()}),m=f(c);return this.relatedNodes(m),0===m.length},after:function(a,b){return[a[0]]}},{id:"skip-link",evaluate:function(a,b,c){return axe.commons.dom.isFocusable(axe.commons.dom.getElementByReference(a,"href"))},after:function(a,b){return[a[0]]}},{id:"unique-frame-title",evaluate:function(a,b,c){var d=axe.commons.text.sanitize(a.title).trim().toLowerCase();return this.data(d),!0},after:function(a,b){var c={};return a.forEach(function(a){c[a.data]=void 0!==c[a.data]?++c[a.data]:0}),a.forEach(function(a){a.result=!!c[a.data]}),a}},{id:"aria-label",evaluate:function(a,b,c){var d=a.getAttribute("aria-label");return!!(d?axe.commons.text.sanitize(d).trim():"")}},{id:"aria-labelledby",evaluate:function(a,b,c){return(0,axe.commons.dom.idrefs)(a,"aria-labelledby").some(function(a){return a&&axe.commons.text.accessibleText(a,!0)})}},{id:"button-has-visible-text",evaluate:function(a,b,c){var d=a.nodeName.toUpperCase(),e=a.getAttribute("role"),f=void 0;return("BUTTON"===d||"button"===e&&"INPUT"!==d)&&(f=axe.commons.text.accessibleText(a),this.data(f),!!f)}},{id:"doc-has-title",evaluate:function(a,b,c){var d=document.title;return!!(d?axe.commons.text.sanitize(d).trim():"")}},{id:"duplicate-id",evaluate:function(a,b,c){if(!a.getAttribute("id").trim())return!0;for(var d=axe.commons.utils.escapeSelector(a.getAttribute("id")),e=document.querySelectorAll('[id="'+d+'"]'),f=[],g=0;g<e.length;g++)e[g]!==a&&f.push(e[g]);return f.length&&this.relatedNodes(f),this.data(a.getAttribute("id")),e.length<=1},after:function(a,b){var c=[];return a.filter(function(a){return-1===c.indexOf(a.data)&&(c.push(a.data),!0)})}},{
-id:"exists",evaluate:function(a,b,c){return!0}},{id:"has-alt",evaluate:function(a,b,c){var d=a.nodeName.toLowerCase();return a.hasAttribute("alt")&&("img"===d||"input"===d||"area"===d)}},{id:"has-visible-text",evaluate:function(a,b,c){return axe.commons.text.accessibleText(a).length>0}},{id:"is-on-screen",evaluate:function(a,b,c){return axe.commons.dom.isVisible(a,!1)&&!axe.commons.dom.isOffscreen(a)}},{id:"non-empty-alt",evaluate:function(a,b,c){var d=a.getAttribute("alt");return!!(d?axe.commons.text.sanitize(d).trim():"")}},{id:"non-empty-if-present",evaluate:function(a,b,c){var d=a.nodeName.toUpperCase(),e=(a.getAttribute("type")||"").toLowerCase(),f=a.getAttribute("value");return this.data(f),"INPUT"===d&&-1!==["submit","reset"].indexOf(e)&&null===f}},{id:"non-empty-title",evaluate:function(a,b,c){var d=a.getAttribute("title");return!!(d?axe.commons.text.sanitize(d).trim():"")}},{id:"non-empty-value",evaluate:function(a,b,c){var d=a.getAttribute("value");return!!(d?axe.commons.text.sanitize(d).trim():"")}},{id:"role-none",evaluate:function(a,b,c){return"none"===a.getAttribute("role")}},{id:"role-presentation",evaluate:function(a,b,c){return"presentation"===a.getAttribute("role")}},{id:"caption-faked",evaluate:function(a,b,c){var d=axe.commons.table.toGrid(a),e=d[0];return d.length<=1||e.length<=1||a.rows.length<=1||e.reduce(function(a,b,c){return a||b!==e[c+1]&&void 0!==e[c+1]},!1)}},{id:"has-caption",evaluate:function(a,b,c){return!!a.caption}},{id:"has-summary",evaluate:function(a,b,c){return!!a.summary}},{id:"has-th",evaluate:function(a,b,c){for(var d,e,f=[],g=0,h=a.rows.length;g<h;g++){d=a.rows[g];for(var i=0,j=d.cells.length;i<j;i++)e=d.cells[i],"TH"!==e.nodeName.toUpperCase()&&-1===["rowheader","columnheader"].indexOf(e.getAttribute("role"))||f.push(e)}return!!f.length&&(this.relatedNodes(f),!0)}},{id:"html5-scope",evaluate:function(a,b,c){return!axe.commons.dom.isHTML5(document)||"TH"===a.nodeName.toUpperCase()}},{id:"same-caption-summary",evaluate:function(a,b,c){return!(!a.summary||!a.caption)&&a.summary===axe.commons.text.accessibleText(a.caption)}},{id:"scope-value",evaluate:function(a,b,c){b=b||{};var d=a.getAttribute("scope").toLowerCase();return-1!==(["row","col","rowgroup","colgroup"]||b.values).indexOf(d)}},{id:"td-has-header",evaluate:function(a,b,c){var d=axe.commons.table,e=[];return d.getAllCells(a).forEach(function(a){if(axe.commons.dom.hasContent(a)&&d.isDataCell(a)&&!axe.commons.aria.label(a)){var b=d.getHeaders(a);(b=b.reduce(function(a,b){return a||null!==b&&!!axe.commons.dom.hasContent(b)},!1))||e.push(a)}}),!e.length||(this.relatedNodes(e),!1)}},{id:"td-headers-attr",evaluate:function(a,b,c){for(var d=[],e=0,f=a.rows.length;e<f;e++)for(var g=a.rows[e],h=0,i=g.cells.length;h<i;h++)d.push(g.cells[h]);var j=d.reduce(function(a,b){return b.getAttribute("id")&&a.push(b.getAttribute("id")),a},[]),k=d.reduce(function(a,b){var c,d,e=(b.getAttribute("headers")||"").split(/\s/).reduce(function(a,b){return b=b.trim(),b&&a.push(b),a},[]);return 0!==e.length&&(b.getAttribute("id")&&(c=-1!==e.indexOf(b.getAttribute("id").trim())),d=e.reduce(function(a,b){return a||-1===j.indexOf(b)},!1),(c||d)&&a.push(b)),a},[]);return!(k.length>0)||(this.relatedNodes(k),!1)}},{id:"th-has-data-cells",evaluate:function(a,b,c){var d=axe.commons.table,e=d.getAllCells(a),f=this,g=[];e.forEach(function(a){var b=a.getAttribute("headers");b&&(g=g.concat(b.split(/\s+/)));var c=a.getAttribute("aria-labelledby");c&&(g=g.concat(c.split(/\s+/)))});var h=e.filter(function(a){return""!==axe.commons.text.sanitize(a.textContent)&&("TH"===a.nodeName.toUpperCase()||-1!==["rowheader","columnheader"].indexOf(a.getAttribute("role")))}),i=d.toGrid(a);return!!h.reduce(function(a,b){if(b.getAttribute("id")&&g.includes(b.getAttribute("id")))return!!a||a;var c=!1,e=d.getCellPosition(b,i);return d.isColumnHeader(b)&&(c=d.traverse("down",e,i).reduce(function(a,b){return a||axe.commons.dom.hasContent(b)&&!d.isColumnHeader(b)},!1)),!c&&d.isRowHeader(b)&&(c=d.traverse("right",e,i).reduce(function(a,b){return a||axe.commons.dom.hasContent(b)&&!d.isRowHeader(b)},!1)),c||f.relatedNodes(b),a&&c},!0)||void 0}},{id:"hidden-content",evaluate:function(a,b,c){if(!["SCRIPT","HEAD","TITLE","NOSCRIPT","STYLE","TEMPLATE"].includes(a.tagName.toUpperCase())&&axe.commons.dom.hasContent(c)){var d=window.getComputedStyle(a);if("none"===d.getPropertyValue("display"))return;if("hidden"===d.getPropertyValue("visibility")){var e=axe.commons.dom.getComposedParent(a),f=e&&window.getComputedStyle(e);if(!f||"hidden"!==f.getPropertyValue("visibility"))return}}return!0}}],commons:function(){function a(a){return a.getPropertyValue("font-family").split(/[,;]/g).map(function(a){return a.trim().toLowerCase()})}function b(b,c){var d=window.getComputedStyle(b);if("none"!==d.getPropertyValue("background-image"))return!0;if(["border-bottom","border-top","outline"].reduce(function(a,b){var c=new A.Color;return c.parseRgbString(d.getPropertyValue(b+"-color")),a||"none"!==d.getPropertyValue(b+"-style")&&parseFloat(d.getPropertyValue(b+"-width"))>0&&0!==c.alpha},!1))return!0;var e=window.getComputedStyle(c);if(a(d)[0]!==a(e)[0])return!0;var f=["text-decoration-line","text-decoration-style","font-weight","font-style","font-size"].reduce(function(a,b){return a||d.getPropertyValue(b)!==e.getPropertyValue(b)},!1),g=d.getPropertyValue("text-decoration");return g.split(" ").length<3&&(f=f||g!==e.getPropertyValue("text-decoration")),f}function c(a,b){var c=a.nodeName.toUpperCase();if(E.includes(c))return axe.commons.color.incompleteData.set("bgColor","imgNode"),!0;b=b||window.getComputedStyle(a);var d=b.getPropertyValue("background-image"),e="none"!==d;if(e){var f=/gradient/.test(d);axe.commons.color.incompleteData.set("bgColor",f?"bgGradient":"bgImage")}return e}function d(a,b){b=b||window.getComputedStyle(a);var c=new A.Color;if(c.parseRgbString(b.getPropertyValue("background-color")),0!==c.alpha){var d=b.getPropertyValue("opacity");c.alpha=c.alpha*d}return c}function e(a,b){var c=a.getClientRects()[0],d=document.elementsFromPoint(c.left,c.top);if(d)for(var e=0;e<d.length;e++)if(d[e]!==a&&d[e]===b)return!0;return!1}function f(a,b,c){var f=0;if(a>0)for(var g=a-1;g>=0;g--){var h=b[g],i=window.getComputedStyle(h),j=d(h,i);j.alpha&&e(c,h)?f+=j.alpha:b.splice(g,1)}return f}function g(a,b,c){var d=a!==b&&!B.visuallyContains(a,b)&&0!==c.alpha;return d&&axe.commons.color.incompleteData.set("bgColor","elmPartiallyObscured"),d}function h(a,b){var c={TD:"TR",INPUT:"LABEL"},d=a.map(function(a){return a.tagName}),e=a;for(var f in c)if(c.hasOwnProperty(f)){if(b.tagName===f){var g=axe.commons.dom.findUp(b,c[f]);if(g&&-1===a.indexOf(g)){var h=axe.commons.dom.visuallyOverlaps(b.getBoundingClientRect(),g);h&&e.splice(a.indexOf(b)+1,0,g)}}b.tagName===c[f]&&-1===d.indexOf(b.tagName)&&e.splice(d.indexOf(f)+1,0,b)}return e}function i(a){var b=a.indexOf(document.body),e=a;return b>1&&!c(document.documentElement)&&0===d(document.documentElement).alpha&&(e.splice(b,1),e.splice(a.indexOf(document.documentElement),1),e.push(document.body)),e}function j(a){if(!F.includes(a.actualNode.nodeName.toUpperCase()))return a.children.some(function(a){var b=a.actualNode;return 3===b.nodeType&&b.nodeValue.trim()})}function k(a,b){!1!==b(a.actualNode)&&a.children.forEach(function(a){return k(a,b)})}function l(a){var b=window.getComputedStyle(a).getPropertyValue("display");return G.includes(b)||"table-"===b.substr(0,6)}function m(a){for(var b=B.getComposedParent(a);b&&!l(b);)b=B.getComposedParent(b);return axe.utils.getNodeFromTree(axe._tree[0],b)}function n(a){"use strict";var b=a.match(/rect\s*\(([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px\s*\)/);return!(!b||5!==b.length)&&(b[3]-b[1]<=0&&b[2]-b[4]<=0)}function o(a){var b=a.actualNode,c=void 0;return c=b.id?B.findElmsInContext({elm:"label",attr:"for",value:b.id,context:b})[0]:B.findUp(b,"label"),axe.utils.getNodeFromTree(axe._tree[0],c)}function p(a){return["button","reset","submit"].includes(a.actualNode.type.toLowerCase())}function q(a){var b=a.actualNode,c=b.nodeName.toUpperCase();return"TEXTAREA"===c||"SELECT"===c||"INPUT"===c&&"hidden"!==b.type.toLowerCase()}function r(a){return["BUTTON","SUMMARY","A"].includes(a.actualNode.nodeName.toUpperCase())}function s(a){return["TABLE","FIGURE"].includes(a.actualNode.nodeName.toUpperCase())}function t(a){var b=a.actualNode,c=b.nodeName.toUpperCase();if("INPUT"===c)return!b.hasAttribute("type")||J.includes(b.type.toLowerCase())?b.value:"";if("SELECT"===c){var d=b.options;if(d&&d.length){for(var e="",f=0;f<d.length;f++)d[f].selected&&(e+=" "+d[f].text);return D.sanitize(e)}return""}return"TEXTAREA"===c&&b.value?b.value:""}function u(a,b){var c=a.actualNode,d=c.querySelector(b.toLowerCase());return d?D.accessibleText(d):""}function v(a){if(!a)return!1;var b=a.actualNode;switch(b.nodeName.toUpperCase()){case"SELECT":case"TEXTAREA":return!0;case"INPUT":return!b.hasAttribute("type")||J.includes(b.getAttribute("type").toLowerCase());default:return!1}}function w(a){var b=a.actualNode,c=b.nodeName.toUpperCase();return["IMG","APPLET","AREA"].includes(c)||"INPUT"===c&&"image"===b.type.toLowerCase()}function x(a){return!!D.sanitize(a)}var commons={},y=commons.aria={},z=y._lut={};z.attributes={"aria-activedescendant":{type:"idref"},"aria-atomic":{type:"boolean",values:["true","false"]},"aria-autocomplete":{type:"nmtoken",values:["inline","list","both","none"]},"aria-busy":{type:"boolean",values:["true","false"]},"aria-checked":{type:"nmtoken",values:["true","false","mixed","undefined"]},"aria-colcount":{type:"int"},"aria-colindex":{type:"int"},"aria-colspan":{type:"int"},"aria-controls":{type:"idrefs"},"aria-current":{type:"nmtoken",values:["page","step","location","date","time","true","false"]},"aria-describedby":{type:"idrefs"},"aria-disabled":{type:"boolean",values:["true","false"]},"aria-dropeffect":{type:"nmtokens",values:["copy","move","reference","execute","popup","none"]},"aria-expanded":{type:"nmtoken",values:["true","false","undefined"]},"aria-flowto":{type:"idrefs"},"aria-grabbed":{type:"nmtoken",values:["true","false","undefined"]},"aria-haspopup":{type:"boolean",values:["true","false"]},"aria-hidden":{type:"boolean",values:["true","false"]},"aria-invalid":{type:"nmtoken",values:["true","false","spelling","grammar"]},"aria-label":{type:"string"},"aria-labelledby":{type:"idrefs"},"aria-level":{type:"int"},"aria-live":{type:"nmtoken",values:["off","polite","assertive"]},"aria-multiline":{type:"boolean",values:["true","false"]},"aria-multiselectable":{type:"boolean",values:["true","false"]},"aria-orientation":{type:"nmtoken",values:["horizontal","vertical"]},"aria-owns":{type:"idrefs"},"aria-posinset":{type:"int"},"aria-pressed":{type:"nmtoken",values:["true","false","mixed","undefined"]},"aria-readonly":{type:"boolean",values:["true","false"]},"aria-relevant":{type:"nmtokens",values:["additions","removals","text","all"]},"aria-required":{type:"boolean",values:["true","false"]},"aria-rowcount":{type:"int"},"aria-rowindex":{type:"int"},"aria-rowspan":{type:"int"},"aria-selected":{type:"nmtoken",values:["true","false","undefined"]},"aria-setsize":{type:"int"},"aria-sort":{type:"nmtoken",values:["ascending","descending","other","none"]},"aria-valuemax":{type:"decimal"},"aria-valuemin":{type:"decimal"},"aria-valuenow":{type:"decimal"},"aria-valuetext":{type:"string"}},z.globalAttributes=["aria-atomic","aria-busy","aria-controls","aria-current","aria-describedby","aria-disabled","aria-dropeffect","aria-flowto","aria-grabbed","aria-haspopup","aria-hidden","aria-invalid","aria-label","aria-labelledby","aria-live","aria-owns","aria-relevant"],z.role={alert:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},alertdialog:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},application:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},article:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["article"]},banner:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["header"]},button:{type:"widget",attributes:{allowed:["aria-expanded","aria-pressed"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["button",'input[type="button"]','input[type="image"]','input[type="reset"]','input[type="submit"]',"summary"]},cell:{type:"structure",attributes:{allowed:["aria-colindex","aria-colspan","aria-rowindex","aria-rowspan"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["td","th"]},checkbox:{type:"widget",attributes:{required:["aria-checked"]},owned:null,nameFrom:["author","contents"],context:null,implicit:['input[type="checkbox"]']},columnheader:{type:"structure",attributes:{allowed:["aria-expanded","aria-sort","aria-readonly","aria-selected","aria-required"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["th"]},combobox:{type:"composite",attributes:{required:["aria-expanded"],allowed:["aria-autocomplete","aria-required","aria-activedescendant"]},owned:{all:["listbox","textbox"]},nameFrom:["author"],context:null},command:{nameFrom:["author"],type:"abstract"},complementary:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["aside"]},composite:{nameFrom:["author"],type:"abstract"},contentinfo:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["footer"]},definition:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["dd"]},dialog:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["dialog"]},directory:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author","contents"],context:null},document:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["body"]},form:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["form"]},grid:{type:"composite",attributes:{allowed:["aria-level","aria-multiselectable","aria-readonly","aria-activedescendant","aria-expanded"]},owned:{one:["rowgroup","row"]},nameFrom:["author"],context:null,implicit:["table"]},gridcell:{type:"widget",attributes:{allowed:["aria-selected","aria-readonly","aria-expanded","aria-required"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["td","th"]},group:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["details","optgroup"]},heading:{type:"structure",attributes:{allowed:["aria-level","aria-expanded"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["h1","h2","h3","h4","h5","h6"]},img:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["img"]},input:{nameFrom:["author"],type:"abstract"},landmark:{nameFrom:["author"],type:"abstract"},link:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["a[href]"]},list:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:{all:["listitem"]},nameFrom:["author"],context:null,implicit:["ol","ul","dl"]},listbox:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-multiselectable","aria-required","aria-expanded"]},owned:{all:["option"]},nameFrom:["author"],context:null,implicit:["select"]},listitem:{type:"structure",attributes:{allowed:["aria-level","aria-posinset","aria-setsize","aria-expanded"]},owned:null,nameFrom:["author","contents"],context:["list"],implicit:["li","dt"]},log:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},main:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["main"]},marquee:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},math:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["math"]},menu:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded"]},owned:{one:["menuitem","menuitemradio","menuitemcheckbox"]},nameFrom:["author"],context:null,implicit:['menu[type="context"]']},menubar:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded"]},owned:null,nameFrom:["author"],context:null},menuitem:{type:"widget",attributes:null,owned:null,nameFrom:["author","contents"],context:["menu","menubar"],implicit:['menuitem[type="command"]']},menuitemcheckbox:{type:"widget",attributes:{required:["aria-checked"]},owned:null,nameFrom:["author","contents"],context:["menu","menubar"],implicit:['menuitem[type="checkbox"]']},menuitemradio:{type:"widget",attributes:{allowed:["aria-selected","aria-posinset","aria-setsize"],required:["aria-checked"]},owned:null,nameFrom:["author","contents"],context:["menu","menubar"],implicit:['menuitem[type="radio"]']},navigation:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["nav"]},none:{type:"structure",attributes:null,owned:null,nameFrom:["author"],context:null},note:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},option:{type:"widget",attributes:{allowed:["aria-selected","aria-posinset","aria-setsize","aria-checked"]},owned:null,nameFrom:["author","contents"],context:["listbox"],implicit:["option"]},presentation:{type:"structure",attributes:null,owned:null,nameFrom:["author"],context:null},progressbar:{type:"widget",attributes:{allowed:["aria-valuetext","aria-valuenow","aria-valuemax","aria-valuemin"]},owned:null,nameFrom:["author"],context:null,implicit:["progress"]},radio:{type:"widget",attributes:{allowed:["aria-selected","aria-posinset","aria-setsize"],required:["aria-checked"]},owned:null,nameFrom:["author","contents"],context:null,implicit:['input[type="radio"]']},radiogroup:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-required","aria-expanded"]},owned:{all:["radio"]},nameFrom:["author"],context:null},range:{nameFrom:["author"],type:"abstract"},region:{type:"structure",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["section"]},roletype:{type:"abstract"},row:{type:"structure",attributes:{allowed:["aria-level","aria-selected","aria-activedescendant","aria-expanded"]},owned:{one:["cell","columnheader","rowheader","gridcell"]},nameFrom:["author","contents"],context:["rowgroup","grid","treegrid","table"],implicit:["tr"]},rowgroup:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-expanded"]},owned:{all:["row"]},nameFrom:["author","contents"],context:["grid","table"],implicit:["tbody","thead","tfoot"]},rowheader:{type:"structure",attributes:{allowed:["aria-sort","aria-required","aria-readonly","aria-expanded","aria-selected"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["th"]},scrollbar:{type:"widget",attributes:{required:["aria-controls","aria-orientation","aria-valuenow","aria-valuemax","aria-valuemin"],allowed:["aria-valuetext"]},owned:null,nameFrom:["author"],context:null},search:{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},searchbox:{type:"widget",attributes:{allowed:["aria-activedescendant","aria-autocomplete","aria-multiline","aria-readonly","aria-required"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="search"]']},section:{nameFrom:["author","contents"],type:"abstract"},sectionhead:{nameFrom:["author","contents"],type:"abstract"},select:{nameFrom:["author"],type:"abstract"},separator:{type:"structure",attributes:{allowed:["aria-expanded","aria-orientation"]},owned:null,nameFrom:["author"],context:null,implicit:["hr"]},slider:{type:"widget",attributes:{allowed:["aria-valuetext","aria-orientation"],required:["aria-valuenow","aria-valuemax","aria-valuemin"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="range"]']},spinbutton:{type:"widget",attributes:{allowed:["aria-valuetext","aria-required"],required:["aria-valuenow","aria-valuemax","aria-valuemin"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="number"]']},status:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:["output"]},structure:{type:"abstract"},switch:{type:"widget",attributes:{required:["aria-checked"]},owned:null,nameFrom:["author","contents"],context:null},tab:{type:"widget",attributes:{allowed:["aria-selected","aria-expanded"]},owned:null,nameFrom:["author","contents"],context:["tablist"]},table:{type:"structure",attributes:{allowed:["aria-colcount","aria-rowcount"]},owned:{one:["rowgroup","row"]},nameFrom:["author"],context:null,implicit:["table"]},tablist:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-level","aria-multiselectable"]},owned:{all:["tab"]},nameFrom:["author"],context:null},tabpanel:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},text:{type:"structure",owned:null,nameFrom:["author","contents"],context:null},textbox:{type:"widget",attributes:{allowed:["aria-activedescendant","aria-autocomplete","aria-multiline","aria-readonly","aria-required"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="text"]','input[type="email"]','input[type="password"]','input[type="tel"]','input[type="url"]',"input:not([type])","textarea"]},timer:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author"],context:null},toolbar:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-expanded"]},owned:null,nameFrom:["author"],context:null,implicit:['menu[type="toolbar"]']},tooltip:{type:"widget",attributes:{allowed:["aria-expanded"]},owned:null,nameFrom:["author","contents"],context:null},tree:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-multiselectable","aria-required","aria-expanded"]},owned:{all:["treeitem"]},nameFrom:["author"],context:null},treegrid:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-level","aria-multiselectable","aria-readonly","aria-required"]},owned:{all:["treeitem"]},nameFrom:["author"],context:null},treeitem:{type:"widget",attributes:{allowed:["aria-checked","aria-selected","aria-expanded","aria-level","aria-posinset","aria-setsize"]},owned:null,nameFrom:["author","contents"],context:["treegrid","tree"]},widget:{type:"abstract"},window:{nameFrom:["author"],type:"abstract"}};var A={};commons.color=A;var B=commons.dom={},C=commons.table={},D=commons.text={};commons.utils=axe.utils;y.requiredAttr=function(a){"use strict";var b=z.role[a];return b&&b.attributes&&b.attributes.required||[]},y.allowedAttr=function(a){"use strict";var b=z.role[a],c=b&&b.attributes&&b.attributes.allowed||[],d=b&&b.attributes&&b.attributes.required||[];return c.concat(z.globalAttributes).concat(d)},y.validateAttr=function(a){"use strict";return!!z.attributes[a]},y.validateAttrValue=function(a,b){"use strict";var c,d,e=a.getAttribute(b),f=z.attributes[b],g=B.getRootNode(a);if(!f)return!0;switch(f.type){case"boolean":case"nmtoken":return"string"==typeof e&&-1!==f.values.indexOf(e.toLowerCase());case"nmtokens":return d=axe.utils.tokenList(e),d.reduce(function(a,b){return a&&-1!==f.values.indexOf(b)},0!==d.length);case"idref":return!(!e||!g.getElementById(e));case"idrefs":return d=axe.utils.tokenList(e),d.reduce(function(a,b){return!(!a||!g.getElementById(b))},0!==d.length);case"string":return!0;case"decimal":return!(!(c=e.match(/^[-+]?([0-9]*)\.?([0-9]*)$/))||!c[1]&&!c[2]);case"int":return/^[-+]?[0-9]+$/.test(e)}},y.label=function(a){var b,c;return a.actualNode instanceof Node==!1&&(a=axe.utils.getNodeFromTree(axe._tree[0],a)),a.actualNode.getAttribute("aria-labelledby")&&(b=B.idrefs(a.actualNode,"aria-labelledby"),c=b.map(function(a){var b=axe.utils.getNodeFromTree(axe._tree[0],a);return b?D.visible(b,!0):""}).join(" ").trim())?c:(c=a.actualNode.getAttribute("aria-label"),c&&(c=D.sanitize(c).trim())?c:null)},y.isValidRole=function(a){"use strict";return!!z.role[a]},y.getRolesWithNameFromContents=function(){return Object.keys(z.role).filter(function(a){return z.role[a].nameFrom&&-1!==z.role[a].nameFrom.indexOf("contents")})},y.getRolesByType=function(a){return Object.keys(z.role).filter(function(b){return z.role[b].type===a})},y.getRoleType=function(a){var b=z.role[a];return b&&b.type||null},y.requiredOwned=function(a){"use strict";var b=null,c=z.role[a];return c&&(b=axe.utils.clone(c.owned)),b},y.requiredContext=function(a){"use strict";var b=null,c=z.role[a];return c&&(b=axe.utils.clone(c.context)),b},y.implicitNodes=function(a){"use strict";var b=null,c=z.role[a];return c&&c.implicit&&(b=axe.utils.clone(c.implicit)),b},y.implicitRole=function(a){"use strict";var b=function(b,c){var d=function(b){return axe.utils.matchesSelector(a,b)};return c.implicit&&c.implicit.some(d)&&b.push(c.name),b},c=Object.keys(z.role).map(function(a){var b=z.role[a];return{name:a,implicit:b&&b.implicit}}),d=c.reduce(b,[]);if(!d.length)return null;for(var e=a.attributes,f=[],g=0,h=e.length;g<h;g++){var i=e[g];i.name.match(/^aria-/)&&f.push(i.name)}return function(a,b){var c=function(a){return y.allowedAttr(a).reduce(function(a,c){return a+(b.indexOf(c)>-1?1:0)},0)};return a.map(function(a){return{score:c(a),name:a}}).sort(function(a,b){return b.score-a.score}).map(function(a){return a.name})}(d,f).shift()},A.Color=function(a,b,c,d){this.red=a,this.green=b,this.blue=c,this.alpha=d,this.toHexString=function(){var a=Math.round(this.red).toString(16),b=Math.round(this.green).toString(16),c=Math.round(this.blue).toString(16);return"#"+(this.red>15.5?a:"0"+a)+(this.green>15.5?b:"0"+b)+(this.blue>15.5?c:"0"+c)};var e=/^rgb\((\d+), (\d+), (\d+)\)$/,f=/^rgba\((\d+), (\d+), (\d+), (\d*(\.\d+)?)\)/;this.parseRgbString=function(a){if("transparent"===a)return this.red=0,this.green=0,this.blue=0,void(this.alpha=0);var b=a.match(e);return b?(this.red=parseInt(b[1],10),this.green=parseInt(b[2],10),this.blue=parseInt(b[3],10),void(this.alpha=1)):(b=a.match(f),b?(this.red=parseInt(b[1],10),this.green=parseInt(b[2],10),this.blue=parseInt(b[3],10),void(this.alpha=parseFloat(b[4]))):void 0)},this.getRelativeLuminance=function(){var a=this.red/255,b=this.green/255,c=this.blue/255;return.2126*(a<=.03928?a/12.92:Math.pow((a+.055)/1.055,2.4))+.7152*(b<=.03928?b/12.92:Math.pow((b+.055)/1.055,2.4))+.0722*(c<=.03928?c/12.92:Math.pow((c+.055)/1.055,2.4))}},A.flattenColors=function(a,b){var c=a.alpha,d=(1-c)*b.red+c*a.red,e=(1-c)*b.green+c*a.green,f=(1-c)*b.blue+c*a.blue,g=a.alpha+b.alpha*(1-a.alpha);return new A.Color(d,e,f,g)},A.getContrast=function(a,b){if(!b||!a)return null;b.alpha<1&&(b=A.flattenColors(b,a));var c=a.getRelativeLuminance(),d=b.getRelativeLuminance();return(Math.max(d,c)+.05)/(Math.min(d,c)+.05)},A.hasValidContrastRatio=function(a,b,c,d){var e=A.getContrast(a,b),f=d&&Math.ceil(72*c)/96<14||!d&&Math.ceil(72*c)/96<18;return{isValid:f&&e>=4.5||!f&&e>=3,contrastRatio:e}},A.elementIsDistinct=b;var E=["IMG","CANVAS","OBJECT","IFRAME","VIDEO","SVG"];A.getBackgroundStack=function(a){var b=a.getBoundingClientRect(),c=void 0,d=void 0;if(!(b.left>window.innerWidth||b.top>window.innerHeight)){c=Math.min(Math.ceil(b.left+b.width/2),window.innerWidth-1),d=Math.min(Math.ceil(b.top+b.height/2),window.innerHeight-1);var e=document.elementsFromPoint(c,d);e=h(e,a),e=B.reduceToElementsBelowFloating(e,a),e=i(e);var g=e.indexOf(a);return f(g,e,a)>=.99?(axe.commons.color.incompleteData.set("bgColor","bgOverlap"),null):-1!==g?e:null}},A.getBackgroundColor=function(a){var b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[];if(!0!==(arguments.length>2&&void 0!==arguments[2]&&arguments[2])){var e=a.clientHeight-2>=2*window.innerHeight;a.scrollIntoView(e)}var f=[],h=A.getBackgroundStack(a);if((h||[]).some(function(e){var h=window.getComputedStyle(e),i=d(e,h);return g(a,e,i)||c(e,h)?(f=null,b.push(e),!0):0!==i.alpha&&(b.push(e),f.push(i),1===i.alpha)}),null!==f&&null!==h){f.push(new A.Color(255,255,255,1));return f.reduce(A.flattenColors)}return null},B.isOpaque=function(a){var b=window.getComputedStyle(a);return c(a,b)||1===d(a,b).alpha},A.getForegroundColor=function(a,b){var c=window.getComputedStyle(a),d=new A.Color;d.parseRgbString(c.getPropertyValue("color"));var e=c.getPropertyValue("opacity");if(d.alpha=d.alpha*e,1===d.alpha)return d;var f=A.getBackgroundColor(a,[],b);if(null===f){var g=axe.commons.color.incompleteData.get("bgColor");return axe.commons.color.incompleteData.set("fgColor",g),null}return A.flattenColors(d,f)},A.incompleteData=function(){var a={};return{set:function(b,c){if("string"!=typeof b)throw new Error("Incomplete data: key must be a string");return c&&(a[b]=c),a[b]},get:function(b){return a[b]},clear:function(){a={}}}}(),B.reduceToElementsBelowFloating=function(a,b){var c,d,e,f=["fixed","sticky"],g=[],h=!1;for(c=0;c<a.length;++c)d=a[c],d===b&&(h=!0),e=window.getComputedStyle(d),h||-1===f.indexOf(e.position)?g.push(d):g=[];return g},B.findElmsInContext=function(a){var b=a.context,c=a.value,d=a.attr,e=a.elm,f=void 0===e?"":e,g=void 0;b=b.actualNode||b;var h=axe.utils.escapeSelector(c);return g=9===b.nodeType||11===b.nodeType?b:B.getRootNode(b),Array.from(g.querySelectorAll(f+"["+d+"="+h+"]"))},B.findUp=function(a,b){var c=void 0,d=void 0,e=a;do{if(e=e.assignedSlot?e.assignedSlot:e.parentNode,e&&11===e.nodeType&&(d=null,e=e.host),!d&&(c=axe.commons.dom.getRootNode(e),d=c.querySelectorAll(b),d=axe.utils.toArray(d),c===document&&!d.length))return null}while(e&&!d.includes(e));return e},B.getComposedParent=function a(b){if(b.assignedSlot)return a(b.assignedSlot);if(b.parentNode){var c=b.parentNode;if(1===c.nodeType)return c;if(c.host)return c.host}return null},B.getElementByReference=function(a,b){var c=a.getAttribute(b);if(c&&"#"===c.charAt(0)){c=c.substring(1);var d=document.getElementById(c);if(d)return d;if(d=document.getElementsByName(c),d.length)return d[0]}return null},B.getElementCoordinates=function(a){"use strict";var b=B.getScrollOffset(document),c=b.left,d=b.top,e=a.getBoundingClientRect();return{top:e.top+d,right:e.right+c,bottom:e.bottom+d,left:e.left+c,width:e.right-e.left,height:e.bottom-e.top}},B.getRootNode=function(a){var b=a.getRootNode&&a.getRootNode()||document;return b===a&&(b=document),b},B.getScrollOffset=function(a){"use strict";if(!a.nodeType&&a.document&&(a=a.document),9===a.nodeType){var b=a.documentElement,c=a.body;return{left:b&&b.scrollLeft||c&&c.scrollLeft||0,top:b&&b.scrollTop||c&&c.scrollTop||0}}return{left:a.scrollLeft,top:a.scrollTop}},B.getViewportSize=function(a){"use strict";var b,c=a.document,d=c.documentElement;return a.innerWidth?{width:a.innerWidth,height:a.innerHeight}:d?{width:d.clientWidth,height:d.clientHeight}:(b=c.body,{width:b.clientWidth,height:b.clientHeight})};var F=["HEAD","TITLE","TEMPLATE","SCRIPT","STYLE","IFRAME","OBJECT","VIDEO","AUDIO","NOSCRIPT"];B.hasContent=function(a,b){return a.actualNode||(a=axe.utils.getNodeFromTree(axe._tree[0],a)),j(a)||B.isVisualContent(a.actualNode)||!!y.label(a)||!b&&a.children.some(function(a){return 1===a.actualNode.nodeType&&B.hasContent(a)})},B.idrefs=function(a,b){"use strict";var c,d,e=B.getRootNode(a),f=[],g=a.getAttribute(b);if(g)for(g=axe.utils.tokenList(g),c=0,d=g.length;c<d;c++)f.push(e.getElementById(g[c]));return f},B.isFocusable=function(a){"use strict";if(!a||a.disabled||!B.isVisible(a)&&"AREA"!==a.nodeName.toUpperCase())return!1;switch(a.nodeName.toUpperCase()){case"A":case"AREA":if(a.href)return!0;break;case"INPUT":return"hidden"!==a.type
-;case"TEXTAREA":case"SELECT":case"DETAILS":case"BUTTON":return!0}var b=a.getAttribute("tabindex");return!(!b||isNaN(parseInt(b,10)))},B.isHTML5=function(a){var b=a.doctype;return null!==b&&("html"===b.name&&!b.publicId&&!b.systemId)};var G=["block","list-item","table","flex","grid","inline-block"];B.isInTextBlock=function(a){if(l(a))return!1;var b=m(a),c="",d="",e=0;return k(b,function(b){if(2===e)return!1;if(3===b.nodeType&&(c+=b.nodeValue),1===b.nodeType){var f=(b.nodeName||"").toUpperCase();if(["BR","HR"].includes(f))0===e?(c="",d=""):e=2;else{if("none"===b.style.display||"hidden"===b.style.overflow||!["",null,"none"].includes(b.style.float)||!["",null,"relative"].includes(b.style.position))return!1;if("A"===f&&b.href||"link"===(b.getAttribute("role")||"").toLowerCase())return b===a&&(e=1),d+=b.textContent,!1}}}),c=axe.commons.text.sanitize(c),d=axe.commons.text.sanitize(d),c.length>d.length},B.isNode=function(a){"use strict";return a instanceof Node},B.isOffscreen=function(a){"use strict";var b,c=document.documentElement,d=window.getComputedStyle(a),e=window.getComputedStyle(document.body||c).getPropertyValue("direction"),f=B.getElementCoordinates(a);if(f.bottom<0&&(function(a,b){for(a=a.parentNode;"html"!==a.nodeName.toLowerCase();){if(a.scrollTop&&(b+=a.scrollTop)>=0)return!1;a=a.parentNode}return!0}(a,f.bottom)||"absolute"===d.position))return!0;if(0===f.left&&0===f.right)return!1;if("ltr"===e){if(f.right<=0)return!0}else if(b=Math.max(c.scrollWidth,B.getViewportSize(window).width),f.left>=b)return!0;return!1},B.isVisible=function(a,b,c){"use strict";var d,e,f;return 9===a.nodeType||(11===a.nodeType&&(a=a.host),null!==(d=window.getComputedStyle(a,null))&&(e=a.nodeName.toUpperCase(),!("none"===d.getPropertyValue("display")||"STYLE"===e.toUpperCase()||"SCRIPT"===e.toUpperCase()||!b&&n(d.getPropertyValue("clip"))||!c&&("hidden"===d.getPropertyValue("visibility")||!b&&B.isOffscreen(a))||b&&"true"===a.getAttribute("aria-hidden"))&&(!!(f=a.assignedSlot?a.assignedSlot:a.parentNode)&&B.isVisible(f,b,!0))))};var H=["checkbox","img","radio","range","slider","spinbutton","textbox"];B.isVisualContent=function(a){var b=a.getAttribute("role");if(b)return-1!==H.indexOf(b);switch(a.tagName.toUpperCase()){case"IMG":case"IFRAME":case"OBJECT":case"VIDEO":case"AUDIO":case"CANVAS":case"SVG":case"MATH":case"BUTTON":case"SELECT":case"TEXTAREA":case"KEYGEN":case"PROGRESS":case"METER":return!0;case"INPUT":return"hidden"!==a.type;default:return!1}},B.visuallyContains=function(a,b){var c=a.getBoundingClientRect(),d={top:c.top+.01,bottom:c.bottom-.01,left:c.left+.01,right:c.right-.01},e=b.getBoundingClientRect(),f=e.top,g=e.left,h={top:f-b.scrollTop,bottom:f-b.scrollTop+b.scrollHeight,left:g-b.scrollLeft,right:g-b.scrollLeft+b.scrollWidth},i=window.getComputedStyle(b);return"inline"===i.getPropertyValue("display")||!(d.left<h.left&&d.left<e.left||d.top<h.top&&d.top<e.top||d.right>h.right&&d.right>e.right||d.bottom>h.bottom&&d.bottom>e.bottom)&&(!(d.right>e.right||d.bottom>e.bottom)||("scroll"===i.overflow||"auto"===i.overflow||"hidden"===i.overflow||b instanceof HTMLBodyElement||b instanceof HTMLHtmlElement))},B.visuallyOverlaps=function(a,b){var c=b.getBoundingClientRect(),d=c.top,e=c.left,f={top:d-b.scrollTop,bottom:d-b.scrollTop+b.scrollHeight,left:e-b.scrollLeft,right:e-b.scrollLeft+b.scrollWidth};if(a.left>f.right&&a.left>c.right||a.top>f.bottom&&a.top>c.bottom||a.right<f.left&&a.right<c.left||a.bottom<f.top&&a.bottom<c.top)return!1;var g=window.getComputedStyle(b);return!(a.left>c.right||a.top>c.bottom)||("scroll"===g.overflow||"auto"===g.overflow||b instanceof HTMLBodyElement||b instanceof HTMLHtmlElement)},C.getAllCells=function(a){var b,c,d,e,f=[];for(b=0,d=a.rows.length;b<d;b++)for(c=0,e=a.rows[b].cells.length;c<e;c++)f.push(a.rows[b].cells[c]);return f},C.getCellPosition=function(a,b){var c,d;for(b||(b=C.toGrid(B.findUp(a,"table"))),c=0;c<b.length;c++)if(b[c]&&-1!==(d=b[c].indexOf(a)))return{x:d,y:c}},C.getHeaders=function(a){if(a.hasAttribute("headers"))return commons.dom.idrefs(a,"headers");var b=commons.table.toGrid(commons.dom.findUp(a,"table")),c=commons.table.getCellPosition(a,b);return[].concat(C.traverse("left",c,b).filter(function(a){return C.isRowHeader(a)}),C.traverse("up",c,b).filter(function(a){return C.isColumnHeader(a)})).reverse()},C.getScope=function(a){var b=a.getAttribute("scope"),c=a.getAttribute("role");if(a instanceof Element==!1||-1===["TD","TH"].indexOf(a.nodeName.toUpperCase()))throw new TypeError("Expected TD or TH element");if("columnheader"===c)return"col";if("rowheader"===c)return"row";if("col"===b||"row"===b)return b;if("TH"!==a.nodeName.toUpperCase())return!1;var d=C.toGrid(B.findUp(a,"table")),e=C.getCellPosition(a);return d[e.y].reduce(function(a,b){return a&&"TH"===b.nodeName.toUpperCase()},!0)?"col":d.map(function(a){return a[e.x]}).reduce(function(a,b){return a&&"TH"===b.nodeName.toUpperCase()},!0)?"row":"auto"},C.isColumnHeader=function(a){return-1!==["col","auto"].indexOf(C.getScope(a))},C.isDataCell=function(a){return!(!a.children.length&&!a.textContent.trim())&&"TD"===a.nodeName.toUpperCase()},C.isDataTable=function(a){var b=a.getAttribute("role");if(("presentation"===b||"none"===b)&&!B.isFocusable(a))return!1;if("true"===a.getAttribute("contenteditable")||B.findUp(a,'[contenteditable="true"]'))return!0;if("grid"===b||"treegrid"===b||"table"===b)return!0;if("landmark"===commons.aria.getRoleType(b))return!0;if("0"===a.getAttribute("datatable"))return!1;if(a.getAttribute("summary"))return!0;if(a.tHead||a.tFoot||a.caption)return!0;for(var c=0,d=a.children.length;c<d;c++)if("COLGROUP"===a.children[c].nodeName.toUpperCase())return!0;for(var e,f,g=0,h=a.rows.length,i=!1,j=0;j<h;j++){e=a.rows[j];for(var k=0,l=e.cells.length;k<l;k++){if(f=e.cells[k],"TH"===f.nodeName.toUpperCase())return!0;if(i||f.offsetWidth===f.clientWidth&&f.offsetHeight===f.clientHeight||(i=!0),f.getAttribute("scope")||f.getAttribute("headers")||f.getAttribute("abbr"))return!0;if(-1!==["columnheader","rowheader"].indexOf(f.getAttribute("role")))return!0;if(1===f.children.length&&"ABBR"===f.children[0].nodeName.toUpperCase())return!0;g++}}if(a.getElementsByTagName("table").length)return!1;if(h<2)return!1;var m=a.rows[Math.ceil(h/2)];if(1===m.cells.length&&1===m.cells[0].colSpan)return!1;if(m.cells.length>=5)return!0;if(i)return!0;var n,o;for(j=0;j<h;j++){if(e=a.rows[j],n&&n!==window.getComputedStyle(e).getPropertyValue("background-color"))return!0;if(n=window.getComputedStyle(e).getPropertyValue("background-color"),o&&o!==window.getComputedStyle(e).getPropertyValue("background-image"))return!0;o=window.getComputedStyle(e).getPropertyValue("background-image")}return h>=20||!(B.getElementCoordinates(a).width>.95*B.getViewportSize(window).width)&&(!(g<10)&&!a.querySelector("object, embed, iframe, applet"))},C.isHeader=function(a){if(C.isColumnHeader(a)||C.isRowHeader(a))return!0;if(a.getAttribute("id")){var b=axe.utils.escapeSelector(a.getAttribute("id"));return!!document.querySelector('[headers~="'+b+'"]')}return!1},C.isRowHeader=function(a){return-1!==["row","auto"].indexOf(C.getScope(a))},C.toGrid=function(a){for(var b=[],c=a.rows,d=0,e=c.length;d<e;d++){var f=c[d].cells;b[d]=b[d]||[];for(var g=0,h=0,i=f.length;h<i;h++)for(var j=0;j<f[h].colSpan;j++){for(var k=0;k<f[h].rowSpan;k++){for(b[d+k]=b[d+k]||[];b[d+k][g];)g++;b[d+k][g]=f[h]}g++}}return b},C.toArray=C.toGrid,function(a){var b=function a(b,c,d,e){var f,g=d[c.y]?d[c.y][c.x]:void 0;return g?"function"==typeof e&&!0===(f=e(g,c,d))?[g]:(f=a(b,{x:c.x+b.x,y:c.y+b.y},d,e),f.unshift(g),f):[]};a.traverse=function(a,c,d,e){if(Array.isArray(c)&&(e=d,d=c,c={x:0,y:0}),"string"==typeof a)switch(a){case"left":a={x:-1,y:0};break;case"up":a={x:0,y:-1};break;case"right":a={x:1,y:0};break;case"down":a={x:0,y:1}}return b(a,{x:c.x+a.x,y:c.y+a.y},d,e)}}(C);var I={submit:"Submit",reset:"Reset"},J=["text","search","tel","url","email","date","time","number","range","color"],K=["A","EM","STRONG","SMALL","MARK","ABBR","DFN","I","B","S","U","CODE","VAR","SAMP","KBD","SUP","SUB","Q","CITE","SPAN","BDO","BDI","BR","WBR","INS","DEL","IMG","EMBED","OBJECT","IFRAME","MAP","AREA","SCRIPT","NOSCRIPT","RUBY","VIDEO","AUDIO","INPUT","TEXTAREA","SELECT","BUTTON","LABEL","OUTPUT","DATALIST","KEYGEN","PROGRESS","COMMAND","CANVAS","TIME","METER"];D.accessibleText=function(a,b){function c(a,b,c){return a.children.reduce(function(a,d){var e=d.actualNode;return 3===e.nodeType?a+=e.nodeValue:1===e.nodeType&&(K.includes(e.nodeName.toUpperCase())||(a+=" "),a+=f(d,b,c)),a},"")}function d(a,b,d){var e="",g=a.actualNode,h=g.nodeName.toUpperCase();if(r(a)&&(e=c(a,!1,!1)||"",x(e)))return e;if("FIGURE"===h&&(e=u(a,"figcaption"),x(e)))return e;if("TABLE"===h){if(e=u(a,"caption"),x(e))return e;if(e=g.getAttribute("title")||g.getAttribute("summary")||"",x(e))return e}if(w(a))return g.getAttribute("alt")||"";if(q(a)&&!d){if(p(a))return g.value||g.title||I[g.type]||"";var i=o(a);if(i)return f(i,b,!0)}return""}function e(a,b,c){var d="",e=a.actualNode;return!b&&e.hasAttribute("aria-labelledby")&&(d=D.sanitize(B.idrefs(e,"aria-labelledby").map(function(a){if(null!==a){e===a&&g.pop();var b=axe.utils.getNodeFromTree(axe._tree[0],a);return f(b,!0,e!==a)}return""}).join(" "))),d||c&&v(a)||!e.hasAttribute("aria-label")?d:D.sanitize(e.getAttribute("aria-label"))}var f=void 0,g=[];return a instanceof Node&&(a=axe.utils.getNodeFromTree(axe._tree[0],a)),f=function(a,b,f){var h=void 0;if(!a||g.includes(a))return"";if(null!==a&&a.actualNode instanceof Node!=!0)throw new Error("Invalid argument. Virtual Node must be provided");if(!b&&!B.isVisible(a.actualNode,!0))return"";g.push(a);var i=a.actualNode.getAttribute("role");return h=e(a,b,f),x(h)?h:(h=d(a,b,f),x(h)?h:f&&(h=t(a),x(h))?h:s(a)||i&&-1===y.getRolesWithNameFromContents().indexOf(i)||(h=c(a,b,f),!x(h))?a.actualNode.hasAttribute("title")?a.actualNode.getAttribute("title"):"":h)},D.sanitize(f(a,b))},D.label=function(a){var b,c,d;if(c=y.label(a))return c;if(a.actualNode.id){var e=axe.commons.utils.escapeSelector(a.actualNode.getAttribute("id"));if(d=axe.commons.dom.getRootNode(a.actualNode),b=d.querySelector('label[for="'+e+'"]'),b=axe.utils.getNodeFromTree(axe._tree[0],b),c=b&&D.visible(b,!0))return c}return b=B.findUp(a.actualNode,"label"),b=axe.utils.getNodeFromTree(axe._tree[0],b),(c=b&&D.visible(b,!0))||null},D.sanitize=function(a){"use strict";return a.replace(/\r\n/g,"\n").replace(/\u00A0/g," ").replace(/[\s]{2,}/g," ").trim()},D.visible=function(a,b,c){"use strict";var d,e,f,g=a.children,h=g.length,i="";for(d=0;d<h;d++)e=g[d],3===e.actualNode.nodeType?(f=e.actualNode.nodeValue)&&B.isVisible(a.actualNode,b)&&(i+=f):c||(i+=D.visible(e,b));return D.sanitize(i)},axe.utils.toArray=function(a){"use strict";return Array.prototype.slice.call(a)},axe.utils.tokenList=function(a){"use strict";return a.trim().replace(/\s{2,}/g," ").split(" ")}
-;var L=["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","in","io","is","it","iu","iw","ja","ji","jv","jw","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mo","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","sh","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu","aaa","aab","aac","aad","aae","aaf","aag","aah","aai","aak","aal","aam","aan","aao","aap","aaq","aas","aat","aau","aav","aaw","aax","aaz","aba","abb","abc","abd","abe","abf","abg","abh","abi","abj","abl","abm","abn","abo","abp","abq","abr","abs","abt","abu","abv","abw","abx","aby","abz","aca","acb","acd","ace","acf","ach","aci","ack","acl","acm","acn","acp","acq","acr","acs","act","acu","acv","acw","acx","acy","acz","ada","adb","add","ade","adf","adg","adh","adi","adj","adl","adn","ado","adp","adq","adr","ads","adt","adu","adw","adx","ady","adz","aea","aeb","aec","aed","aee","aek","ael","aem","aen","aeq","aer","aes","aeu","aew","aey","aez","afa","afb","afd","afe","afg","afh","afi","afk","afn","afo","afp","afs","aft","afu","afz","aga","agb","agc","agd","age","agf","agg","agh","agi","agj","agk","agl","agm","agn","ago","agp","agq","agr","ags","agt","agu","agv","agw","agx","agy","agz","aha","ahb","ahg","ahh","ahi","ahk","ahl","ahm","ahn","aho","ahp","ahr","ahs","aht","aia","aib","aic","aid","aie","aif","aig","aih","aii","aij","aik","ail","aim","ain","aio","aip","aiq","air","ais","ait","aiw","aix","aiy","aja","ajg","aji","ajn","ajp","ajt","aju","ajw","ajz","akb","akc","akd","ake","akf","akg","akh","aki","akj","akk","akl","akm","ako","akp","akq","akr","aks","akt","aku","akv","akw","akx","aky","akz","ala","alc","ald","ale","alf","alg","alh","ali","alj","alk","all","alm","aln","alo","alp","alq","alr","als","alt","alu","alv","alw","alx","aly","alz","ama","amb","amc","ame","amf","amg","ami","amj","amk","aml","amm","amn","amo","amp","amq","amr","ams","amt","amu","amv","amw","amx","amy","amz","ana","anb","anc","and","ane","anf","ang","anh","ani","anj","ank","anl","anm","ann","ano","anp","anq","anr","ans","ant","anu","anv","anw","anx","any","anz","aoa","aob","aoc","aod","aoe","aof","aog","aoh","aoi","aoj","aok","aol","aom","aon","aor","aos","aot","aou","aox","aoz","apa","apb","apc","apd","ape","apf","apg","aph","api","apj","apk","apl","apm","apn","apo","app","apq","apr","aps","apt","apu","apv","apw","apx","apy","apz","aqa","aqc","aqd","aqg","aql","aqm","aqn","aqp","aqr","aqt","aqz","arb","arc","ard","are","arh","ari","arj","ark","arl","arn","aro","arp","arq","arr","ars","art","aru","arv","arw","arx","ary","arz","asa","asb","asc","asd","ase","asf","asg","ash","asi","asj","ask","asl","asn","aso","asp","asq","asr","ass","ast","asu","asv","asw","asx","asy","asz","ata","atb","atc","atd","ate","atg","ath","ati","atj","atk","atl","atm","atn","ato","atp","atq","atr","ats","att","atu","atv","atw","atx","aty","atz","aua","aub","auc","aud","aue","auf","aug","auh","aui","auj","auk","aul","aum","aun","auo","aup","auq","aur","aus","aut","auu","auw","aux","auy","auz","avb","avd","avi","avk","avl","avm","avn","avo","avs","avt","avu","avv","awa","awb","awc","awd","awe","awg","awh","awi","awk","awm","awn","awo","awr","aws","awt","awu","awv","aww","awx","awy","axb","axe","axg","axk","axl","axm","axx","aya","ayb","ayc","ayd","aye","ayg","ayh","ayi","ayk","ayl","ayn","ayo","ayp","ayq","ayr","ays","ayt","ayu","ayx","ayy","ayz","aza","azb","azc","azd","azg","azj","azm","azn","azo","azt","azz","baa","bab","bac","bad","bae","baf","bag","bah","bai","baj","bal","ban","bao","bap","bar","bas","bat","bau","bav","baw","bax","bay","baz","bba","bbb","bbc","bbd","bbe","bbf","bbg","bbh","bbi","bbj","bbk","bbl","bbm","bbn","bbo","bbp","bbq","bbr","bbs","bbt","bbu","bbv","bbw","bbx","bby","bbz","bca","bcb","bcc","bcd","bce","bcf","bcg","bch","bci","bcj","bck","bcl","bcm","bcn","bco","bcp","bcq","bcr","bcs","bct","bcu","bcv","bcw","bcy","bcz","bda","bdb","bdc","bdd","bde","bdf","bdg","bdh","bdi","bdj","bdk","bdl","bdm","bdn","bdo","bdp","bdq","bdr","bds","bdt","bdu","bdv","bdw","bdx","bdy","bdz","bea","beb","bec","bed","bee","bef","beg","beh","bei","bej","bek","bem","beo","bep","beq","ber","bes","bet","beu","bev","bew","bex","bey","bez","bfa","bfb","bfc","bfd","bfe","bff","bfg","bfh","bfi","bfj","bfk","bfl","bfm","bfn","bfo","bfp","bfq","bfr","bfs","bft","bfu","bfw","bfx","bfy","bfz","bga","bgb","bgc","bgd","bge","bgf","bgg","bgi","bgj","bgk","bgl","bgm","bgn","bgo","bgp","bgq","bgr","bgs","bgt","bgu","bgv","bgw","bgx","bgy","bgz","bha","bhb","bhc","bhd","bhe","bhf","bhg","bhh","bhi","bhj","bhk","bhl","bhm","bhn","bho","bhp","bhq","bhr","bhs","bht","bhu","bhv","bhw","bhx","bhy","bhz","bia","bib","bic","bid","bie","bif","big","bij","bik","bil","bim","bin","bio","bip","biq","bir","bit","biu","biv","biw","bix","biy","biz","bja","bjb","bjc","bjd","bje","bjf","bjg","bjh","bji","bjj","bjk","bjl","bjm","bjn","bjo","bjp","bjq","bjr","bjs","bjt","bju","bjv","bjw","bjx","bjy","bjz","bka","bkb","bkc","bkd","bkf","bkg","bkh","bki","bkj","bkk","bkl","bkm","bkn","bko","bkp","bkq","bkr","bks","bkt","bku","bkv","bkw","bkx","bky","bkz","bla","blb","blc","bld","ble","blf","blg","blh","bli","blj","blk","bll","blm","bln","blo","blp","blq","blr","bls","blt","blv","blw","blx","bly","blz","bma","bmb","bmc","bmd","bme","bmf","bmg","bmh","bmi","bmj","bmk","bml","bmm","bmn","bmo","bmp","bmq","bmr","bms","bmt","bmu","bmv","bmw","bmx","bmy","bmz","bna","bnb","bnc","bnd","bne","bnf","bng","bni","bnj","bnk","bnl","bnm","bnn","bno","bnp","bnq","bnr","bns","bnt","bnu","bnv","bnw","bnx","bny","bnz","boa","bob","boe","bof","bog","boh","boi","boj","bok","bol","bom","bon","boo","bop","boq","bor","bot","bou","bov","bow","box","boy","boz","bpa","bpb","bpd","bpg","bph","bpi","bpj","bpk","bpl","bpm","bpn","bpo","bpp","bpq","bpr","bps","bpt","bpu","bpv","bpw","bpx","bpy","bpz","bqa","bqb","bqc","bqd","bqf","bqg","bqh","bqi","bqj","bqk","bql","bqm","bqn","bqo","bqp","bqq","bqr","bqs","bqt","bqu","bqv","bqw","bqx","bqy","bqz","bra","brb","brc","brd","brf","brg","brh","bri","brj","brk","brl","brm","brn","bro","brp","brq","brr","brs","brt","bru","brv","brw","brx","bry","brz","bsa","bsb","bsc","bse","bsf","bsg","bsh","bsi","bsj","bsk","bsl","bsm","bsn","bso","bsp","bsq","bsr","bss","bst","bsu","bsv","bsw","bsx","bsy","bta","btb","btc","btd","bte","btf","btg","bth","bti","btj","btk","btl","btm","btn","bto","btp","btq","btr","bts","btt","btu","btv","btw","btx","bty","btz","bua","bub","buc","bud","bue","buf","bug","buh","bui","buj","buk","bum","bun","buo","bup","buq","bus","but","buu","buv","buw","bux","buy","buz","bva","bvb","bvc","bvd","bve","bvf","bvg","bvh","bvi","bvj","bvk","bvl","bvm","bvn","bvo","bvp","bvq","bvr","bvt","bvu","bvv","bvw","bvx","bvy","bvz","bwa","bwb","bwc","bwd","bwe","bwf","bwg","bwh","bwi","bwj","bwk","bwl","bwm","bwn","bwo","bwp","bwq","bwr","bws","bwt","bwu","bww","bwx","bwy","bwz","bxa","bxb","bxc","bxd","bxe","bxf","bxg","bxh","bxi","bxj","bxk","bxl","bxm","bxn","bxo","bxp","bxq","bxr","bxs","bxu","bxv","bxw","bxx","bxz","bya","byb","byc","byd","bye","byf","byg","byh","byi","byj","byk","byl","bym","byn","byo","byp","byq","byr","bys","byt","byv","byw","byx","byy","byz","bza","bzb","bzc","bzd","bze","bzf","bzg","bzh","bzi","bzj","bzk","bzl","bzm","bzn","bzo","bzp","bzq","bzr","bzs","bzt","bzu","bzv","bzw","bzx","bzy","bzz","caa","cab","cac","cad","cae","caf","cag","cah","cai","caj","cak","cal","cam","can","cao","cap","caq","car","cas","cau","cav","caw","cax","cay","caz","cba","cbb","cbc","cbd","cbe","cbg","cbh","cbi","cbj","cbk","cbl","cbn","cbo","cbq","cbr","cbs","cbt","cbu","cbv","cbw","cby","cca","ccc","ccd","cce","ccg","cch","ccj","ccl","ccm","ccn","cco","ccp","ccq","ccr","ccs","cda","cdc","cdd","cde","cdf","cdg","cdh","cdi","cdj","cdm","cdn","cdo","cdr","cds","cdy","cdz","cea","ceb","ceg","cek","cel","cen","cet","cfa","cfd","cfg","cfm","cga","cgc","cgg","cgk","chb","chc","chd","chf","chg","chh","chj","chk","chl","chm","chn","cho","chp","chq","chr","cht","chw","chx","chy","chz","cia","cib","cic","cid","cie","cih","cik","cim","cin","cip","cir","ciw","ciy","cja","cje","cjh","cji","cjk","cjm","cjn","cjo","cjp","cjr","cjs","cjv","cjy","cka","ckb","ckh","ckl","ckn","cko","ckq","ckr","cks","ckt","cku","ckv","ckx","cky","ckz","cla","clc","cld","cle","clh","cli","clj","clk","cll","clm","clo","clt","clu","clw","cly","cma","cmc","cme","cmg","cmi","cmk","cml","cmm","cmn","cmo","cmr","cms","cmt","cna","cnb","cnc","cng","cnh","cni","cnk","cnl","cno","cns","cnt","cnu","cnw","cnx","coa","cob","coc","cod","coe","cof","cog","coh","coj","cok","col","com","con","coo","cop","coq","cot","cou","cov","cow","cox","coy","coz","cpa","cpb","cpc","cpe","cpf","cpg","cpi","cpn","cpo","cpp","cps","cpu","cpx","cpy","cqd","cqu","cra","crb","crc","crd","crf","crg","crh","cri","crj","crk","crl","crm","crn","cro","crp","crq","crr","crs","crt","crv","crw","crx","cry","crz","csa","csb","csc","csd","cse","csf","csg","csh","csi","csj","csk","csl","csm","csn","cso","csq","csr","css","cst","csu","csv","csw","csy","csz","cta","ctc","ctd","cte","ctg","cth","ctl","ctm","ctn","cto","ctp","cts","ctt","ctu","ctz","cua","cub","cuc","cug","cuh","cui","cuj","cuk","cul","cum","cuo","cup","cuq","cur","cus","cut","cuu","cuv","cuw","cux","cvg","cvn","cwa","cwb","cwd","cwe","cwg","cwt","cya","cyb","cyo","czh","czk","czn","czo","czt","daa","dac","dad","dae","daf","dag","dah","dai","daj","dak","dal","dam","dao","dap","daq","dar","das","dau","dav","daw","dax","day","daz","dba","dbb","dbd","dbe","dbf","dbg","dbi","dbj","dbl","dbm","dbn","dbo","dbp","dbq","dbr","dbt","dbu","dbv","dbw","dby","dcc","dcr","dda","ddd","dde","ddg","ddi","ddj","ddn","ddo","ddr","dds","ddw","dec","ded","dee","def","deg","deh","dei","dek","del","dem","den","dep","deq","der","des","dev","dez","dga","dgb","dgc","dgd","dge","dgg","dgh","dgi","dgk","dgl","dgn","dgo","dgr","dgs","dgt","dgu","dgw","dgx","dgz","dha","dhd","dhg","dhi","dhl","dhm","dhn","dho","dhr","dhs","dhu","dhv","dhw","dhx","dia","dib","dic","did","dif","dig","dih","dii","dij","dik","dil","dim","din","dio","dip","diq","dir","dis","dit","diu","diw","dix","diy","diz","dja","djb","djc","djd","dje","djf","dji","djj","djk","djl","djm","djn","djo","djr","dju","djw","dka","dkk","dkl","dkr","dks","dkx","dlg","dlk","dlm","dln","dma","dmb","dmc","dmd","dme","dmg","dmk","dml","dmm","dmn","dmo","dmr","dms","dmu","dmv","dmw","dmx","dmy","dna","dnd","dne","dng","dni","dnj","dnk","dnn","dnr","dnt","dnu","dnv","dnw","dny","doa","dob","doc","doe","dof","doh","doi","dok","dol","don","doo","dop","doq","dor","dos","dot","dov","dow","dox","doy","doz","dpp","dra","drb","drc","drd","dre","drg","drh","dri","drl","drn","dro","drq","drr","drs","drt","dru","drw","dry","dsb","dse","dsh","dsi","dsl","dsn","dso","dsq","dta","dtb","dtd","dth","dti","dtk","dtm","dtn","dto","dtp","dtr","dts","dtt","dtu","dty","dua","dub","duc","dud","due","duf","dug","duh","dui","duj","duk","dul","dum","dun","duo","dup","duq","dur","dus","duu","duv","duw","dux","duy","duz","dva","dwa","dwl","dwr","dws","dwu","dww","dwy","dya","dyb","dyd","dyg","dyi","dym","dyn","dyo","dyu","dyy","dza","dzd","dze","dzg","dzl","dzn","eaa","ebg","ebk","ebo","ebr","ebu","ecr","ecs","ecy","eee","efa","efe","efi","ega","egl","ego","egx","egy","ehu","eip","eit","eiv","eja","eka","ekc","eke","ekg","eki","ekk","ekl","ekm","eko","ekp","ekr","eky","ele","elh","eli","elk","elm","elo","elp","elu","elx","ema","emb","eme","emg","emi","emk","emm","emn","emo","emp","ems","emu","emw","emx","emy","ena","enb","enc","end","enf","enh","enl","enm","enn","eno","enq","enr","enu","env","enw","enx","eot","epi","era","erg","erh","eri","erk","ero","err","ers","ert","erw","ese","esg","esh","esi","esk","esl","esm","esn","eso","esq","ess","esu","esx","esy","etb","etc","eth","etn","eto","etr","ets","ett","etu","etx","etz","euq","eve","evh","evn","ewo","ext","eya","eyo","eza","eze","faa","fab","fad","faf","fag","fah","fai","faj","fak","fal","fam","fan","fap","far","fat","fau","fax","fay","faz","fbl","fcs","fer","ffi","ffm","fgr","fia","fie","fil","fip","fir","fit","fiu","fiw","fkk","fkv","fla","flh","fli","fll","fln","flr","fly","fmp","fmu","fnb","fng","fni","fod","foi","fom","fon","for","fos","fox","fpe","fqs","frc","frd","frk","frm","fro","frp","frq","frr","frs","frt","fse","fsl","fss","fub","fuc","fud","fue","fuf","fuh","fui","fuj","fum","fun","fuq","fur","fut","fuu","fuv","fuy","fvr","fwa","fwe","gaa","gab","gac","gad","gae","gaf","gag","gah","gai","gaj","gak","gal","gam","gan","gao","gap","gaq","gar","gas","gat","gau","gav","gaw","gax","gay","gaz","gba","gbb","gbc","gbd","gbe","gbf","gbg","gbh","gbi","gbj","gbk","gbl","gbm","gbn","gbo","gbp","gbq","gbr","gbs","gbu","gbv","gbw","gbx","gby","gbz","gcc","gcd","gce","gcf","gcl","gcn","gcr","gct","gda","gdb","gdc","gdd","gde","gdf","gdg","gdh","gdi","gdj","gdk","gdl","gdm","gdn","gdo","gdq","gdr","gds","gdt","gdu","gdx","gea","geb","gec","ged","geg","geh","gei","gej","gek","gel","gem","geq","ges","gev","gew","gex","gey","gez","gfk","gft","gfx","gga","ggb","ggd","gge","ggg","ggk","ggl","ggn","ggo","ggr","ggt","ggu","ggw","gha","ghc","ghe","ghh","ghk","ghl","ghn","gho","ghr","ghs","ght","gia","gib","gic","gid","gie","gig","gih","gil","gim","gin","gio","gip","giq","gir","gis","git","giu","giw","gix","giy","giz","gji","gjk","gjm","gjn","gjr","gju","gka","gke","gkn","gko","gkp","gku","glc","gld","glh","gli","glj","glk","gll","glo","glr","glu","glw","gly","gma","gmb","gmd","gme","gmg","gmh","gml","gmm","gmn","gmq","gmu","gmv","gmw","gmx","gmy","gmz","gna","gnb","gnc","gnd","gne","gng","gnh","gni","gnk","gnl","gnm","gnn","gno","gnq","gnr","gnt","gnu","gnw","gnz","goa","gob","goc","god","goe","gof","gog","goh","goi","goj","gok","gol","gom","gon","goo","gop","goq","gor","gos","got","gou","gow","gox","goy","goz","gpa","gpe","gpn","gqa","gqi","gqn","gqr","gqu","gra","grb","grc","grd","grg","grh","gri","grj","grk","grm","gro","grq","grr","grs","grt","gru","grv","grw","grx","gry","grz","gse","gsg","gsl","gsm","gsn","gso","gsp","gss","gsw","gta","gti","gtu","gua","gub","guc","gud","gue","guf","gug","guh","gui","guk","gul","gum","gun","guo","gup","guq","gur","gus","gut","guu","guv","guw","gux","guz","gva","gvc","gve","gvf","gvj","gvl","gvm","gvn","gvo","gvp","gvr","gvs","gvy","gwa","gwb","gwc","gwd","gwe","gwf","gwg","gwi","gwj","gwm","gwn","gwr","gwt","gwu","gww","gwx","gxx","gya","gyb","gyd","gye","gyf","gyg","gyi","gyl","gym","gyn","gyr","gyy","gza","gzi","gzn","haa","hab","hac","had","hae","haf","hag","hah","hai","haj","hak","hal","ham","han","hao","hap","haq","har","has","hav","haw","hax","hay","haz","hba","hbb","hbn","hbo","hbu","hca","hch","hdn","hds","hdy","hea","hed","heg","heh","hei","hem","hgm","hgw","hhi","hhr","hhy","hia","hib","hid","hif","hig","hih","hii","hij","hik","hil","him","hio","hir","hit","hiw","hix","hji","hka","hke","hkk","hks","hla","hlb","hld","hle","hlt","hlu","hma","hmb","hmc","hmd","hme","hmf","hmg","hmh","hmi","hmj","hmk","hml","hmm","hmn","hmp","hmq","hmr","hms","hmt","hmu","hmv","hmw","hmx","hmy","hmz","hna","hnd","hne","hnh","hni","hnj","hnn","hno","hns","hnu","hoa","hob","hoc","hod","hoe","hoh","hoi","hoj","hok","hol","hom","hoo","hop","hor","hos","hot","hov","how","hoy","hoz","hpo","hps","hra","hrc","hre","hrk","hrm","hro","hrp","hrr","hrt","hru","hrw","hrx","hrz","hsb","hsh","hsl","hsn","hss","hti","hto","hts","htu","htx","hub","huc","hud","hue","huf","hug","huh","hui","huj","huk","hul","hum","huo","hup","huq","hur","hus","hut","huu","huv","huw","hux","huy","huz","hvc","hve","hvk","hvn","hvv","hwa","hwc","hwo","hya","hyx","iai","ian","iap","iar","iba","ibb","ibd","ibe","ibg","ibh","ibi","ibl","ibm","ibn","ibr","ibu","iby","ica","ich","icl","icr","ida","idb","idc","idd","ide","idi","idr","ids","idt","idu","ifa","ifb","ife","iff","ifk","ifm","ifu","ify","igb","ige","igg","igl","igm","ign","igo","igs","igw","ihb","ihi","ihp","ihw","iin","iir","ijc","ije","ijj","ijn","ijo","ijs","ike","iki","ikk","ikl","iko","ikp","ikr","iks","ikt","ikv","ikw","ikx","ikz","ila","ilb","ilg","ili","ilk","ill","ilm","ilo","ilp","ils","ilu","ilv","ilw","ima","ime","imi","iml","imn","imo","imr","ims","imy","inb","inc","ine","ing","inh","inj","inl","inm","inn","ino","inp","ins","int","inz","ior","iou","iow","ipi","ipo","iqu","iqw","ira","ire","irh","iri","irk","irn","iro","irr","iru","irx","iry","isa","isc","isd","ise","isg","ish","isi","isk","ism","isn","iso","isr","ist","isu","itb","itc","itd","ite","iti","itk","itl","itm","ito","itr","its","itt","itv","itw","itx","ity","itz","ium","ivb","ivv","iwk","iwm","iwo","iws","ixc","ixl","iya","iyo","iyx","izh","izi","izr","izz","jaa","jab","jac","jad","jae","jaf","jah","jaj","jak","jal","jam","jan","jao","jaq","jar","jas","jat","jau","jax","jay","jaz","jbe","jbi","jbj","jbk","jbn","jbo","jbr","jbt","jbu","jbw","jcs","jct","jda","jdg","jdt","jeb","jee","jeg","jeh","jei","jek","jel","jen","jer","jet","jeu","jgb","jge","jgk","jgo","jhi","jhs","jia","jib","jic","jid","jie","jig","jih","jii","jil","jim","jio","jiq","jit","jiu","jiv","jiy","jje","jjr","jka","jkm","jko","jkp","jkr","jku","jle","jls","jma","jmb","jmc","jmd","jmi","jml","jmn","jmr","jms","jmw","jmx","jna","jnd","jng","jni","jnj","jnl","jns","job","jod","jog","jor","jos","jow","jpa","jpr","jpx","jqr","jra","jrb","jrr","jrt","jru","jsl","jua","jub","juc","jud","juh","jui","juk","jul","jum","jun","juo","jup","jur","jus","jut","juu","juw","juy","jvd","jvn","jwi","jya","jye","jyy","kaa","kab","kac","kad","kae","kaf","kag","kah","kai","kaj","kak","kam","kao","kap","kaq","kar","kav","kaw","kax","kay","kba","kbb","kbc","kbd","kbe","kbf","kbg","kbh","kbi","kbj","kbk","kbl","kbm","kbn","kbo","kbp","kbq","kbr","kbs","kbt","kbu","kbv","kbw","kbx","kby","kbz","kca","kcb","kcc","kcd","kce","kcf","kcg","kch","kci","kcj","kck","kcl","kcm","kcn","kco","kcp","kcq","kcr","kcs","kct","kcu","kcv","kcw","kcx","kcy","kcz","kda","kdc","kdd","kde","kdf","kdg","kdh","kdi","kdj","kdk","kdl","kdm","kdn","kdo","kdp","kdq","kdr","kdt","kdu","kdv","kdw","kdx","kdy","kdz","kea","keb","kec","ked","kee","kef","keg","keh","kei","kej","kek","kel","kem","ken","keo","kep","keq","ker","kes","ket","keu","kev","kew","kex","key","kez","kfa","kfb","kfc","kfd","kfe","kff","kfg","kfh","kfi","kfj","kfk","kfl","kfm","kfn","kfo","kfp","kfq","kfr","kfs","kft","kfu","kfv","kfw","kfx","kfy","kfz","kga","kgb","kgc","kgd","kge","kgf","kgg","kgh","kgi","kgj","kgk","kgl","kgm","kgn","kgo","kgp","kgq","kgr","kgs","kgt","kgu","kgv","kgw","kgx","kgy","kha","khb","khc","khd","khe","khf","khg","khh","khi","khj","khk","khl","khn","kho","khp","khq","khr","khs","kht","khu","khv","khw","khx","khy","khz","kia","kib","kic","kid","kie","kif","kig","kih","kii","kij","kil","kim","kio","kip","kiq","kis","kit","kiu","kiv","kiw","kix","kiy","kiz","kja","kjb","kjc","kjd","kje","kjf","kjg","kjh","kji","kjj","kjk","kjl","kjm","kjn","kjo","kjp","kjq","kjr","kjs","kjt","kju","kjv","kjx","kjy","kjz","kka","kkb","kkc","kkd","kke","kkf","kkg","kkh","kki","kkj","kkk","kkl","kkm","kkn","kko","kkp","kkq","kkr","kks","kkt","kku","kkv","kkw","kkx","kky","kkz","kla","klb","klc","kld","kle","klf","klg","klh","kli","klj","klk","kll","klm","kln","klo","klp","klq","klr","kls","klt","klu","klv","klw","klx","kly","klz","kma","kmb","kmc","kmd","kme","kmf","kmg","kmh","kmi","kmj","kmk","kml","kmm","kmn","kmo","kmp","kmq","kmr","kms","kmt","kmu","kmv","kmw","kmx","kmy","kmz","kna","knb","knc","knd","kne","knf","kng","kni","knj","knk","knl","knm","knn","kno","knp","knq","knr","kns","knt","knu","knv","knw","knx","kny","knz","koa","koc","kod","koe","kof","kog","koh","koi","koj","kok","kol","koo","kop","koq","kos","kot","kou","kov","kow","kox","koy","koz","kpa","kpb","kpc","kpd","kpe","kpf","kpg","kph","kpi","kpj","kpk","kpl","kpm","kpn","kpo","kpp","kpq","kpr","kps","kpt","kpu","kpv","kpw","kpx","kpy","kpz","kqa","kqb","kqc","kqd","kqe","kqf","kqg","kqh","kqi","kqj","kqk","kql","kqm","kqn","kqo","kqp","kqq","kqr","kqs","kqt","kqu","kqv","kqw","kqx","kqy","kqz","kra","krb","krc","krd","kre","krf","krh","kri","krj","krk","krl","krm","krn","kro","krp","krr","krs","krt","kru","krv","krw","krx","kry","krz","ksa","ksb","ksc","ksd","kse","ksf","ksg","ksh","ksi","ksj","ksk","ksl","ksm","ksn","kso","ksp","ksq","ksr","kss","kst","ksu","ksv","ksw","ksx","ksy","ksz","kta","ktb","ktc","ktd","kte","ktf","ktg","kth","kti","ktj","ktk","ktl","ktm","ktn","kto","ktp","ktq","ktr","kts","ktt","ktu","ktv","ktw","ktx","kty","ktz","kub","kuc","kud","kue","kuf","kug","kuh","kui","kuj","kuk","kul","kum","kun","kuo","kup","kuq","kus","kut","kuu","kuv","kuw","kux","kuy","kuz","kva","kvb","kvc","kvd","kve","kvf","kvg","kvh","kvi","kvj","kvk","kvl","kvm","kvn","kvo","kvp","kvq","kvr","kvs","kvt","kvu","kvv","kvw","kvx","kvy","kvz","kwa","kwb","kwc","kwd","kwe","kwf","kwg","kwh","kwi","kwj","kwk","kwl","kwm","kwn","kwo","kwp","kwq","kwr","kws","kwt","kwu","kwv","kww","kwx","kwy","kwz","kxa","kxb","kxc","kxd","kxe","kxf","kxh","kxi","kxj","kxk","kxl","kxm","kxn","kxo","kxp","kxq","kxr","kxs","kxt","kxu","kxv","kxw","kxx","kxy","kxz","kya","kyb","kyc","kyd","kye","kyf","kyg","kyh","kyi","kyj","kyk","kyl","kym","kyn","kyo","kyp","kyq","kyr","kys","kyt","kyu","kyv","kyw","kyx","kyy","kyz","kza","kzb","kzc","kzd","kze","kzf","kzg","kzh","kzi","kzj","kzk","kzl","kzm","kzn","kzo","kzp","kzq","kzr","kzs","kzt","kzu","kzv","kzw","kzx","kzy","kzz","laa","lab","lac","lad","lae","laf","lag","lah","lai","laj","lak","lal","lam","lan","lap","laq","lar","las","lau","law","lax","lay","laz","lba","lbb","lbc","lbe","lbf","lbg","lbi","lbj","lbk","lbl","lbm","lbn","lbo","lbq","lbr","lbs","lbt","lbu","lbv","lbw","lbx","lby","lbz","lcc","lcd","lce","lcf","lch","lcl","lcm","lcp","lcq","lcs","lda","ldb","ldd","ldg","ldh","ldi","ldj","ldk","ldl","ldm","ldn","ldo","ldp","ldq","lea","leb","lec","led","lee","lef","leg","leh","lei","lej","lek","lel","lem","len","leo","lep","leq","ler","les","let","leu","lev","lew","lex","ley","lez","lfa","lfn","lga","lgb","lgg","lgh","lgi","lgk","lgl","lgm","lgn","lgq","lgr","lgt","lgu","lgz","lha","lhh","lhi","lhl","lhm","lhn","lhp","lhs","lht","lhu","lia","lib","lic","lid","lie","lif","lig","lih","lii","lij","lik","lil","lio","lip","liq","lir","lis","liu","liv","liw","lix","liy","liz","lja","lje","lji","ljl","ljp","ljw","ljx","lka","lkb","lkc","lkd","lke","lkh","lki","lkj","lkl","lkm","lkn","lko","lkr","lks","lkt","lku","lky","lla","llb","llc","lld","lle","llf","llg","llh","lli","llj","llk","lll","llm","lln","llo","llp","llq","lls","llu","llx","lma","lmb","lmc","lmd","lme","lmf","lmg","lmh","lmi","lmj","lmk","lml","lmm","lmn","lmo","lmp","lmq","lmr","lmu","lmv","lmw","lmx","lmy","lmz","lna","lnb","lnd","lng","lnh","lni","lnj","lnl","lnm","lnn","lno","lns","lnu","lnw","lnz","loa","lob","loc","loe","lof","log","loh","loi","loj","lok","lol","lom","lon","loo","lop","loq","lor","los","lot","lou","lov","low","lox","loy","loz","lpa","lpe","lpn","lpo","lpx","lra","lrc","lre","lrg","lri","lrk","lrl","lrm","lrn","lro","lrr","lrt","lrv","lrz","lsa","lsd","lse","lsg","lsh","lsi","lsl","lsm","lso","lsp","lsr","lss","lst","lsy","ltc","ltg","lth","lti","ltn","lto","lts","ltu","lua","luc","lud","lue","luf","lui","luj","luk","lul","lum","lun","luo","lup","luq","lur","lus","lut","luu","luv","luw","luy","luz","lva","lvk","lvs","lvu","lwa","lwe","lwg","lwh","lwl","lwm","lwo","lwt","lwu","lww","lya","lyg","lyn","lzh","lzl","lzn","lzz","maa","mab","mad","mae","maf","mag","mai","maj","mak","mam","man","map","maq","mas","mat","mau","mav","maw","max","maz","mba","mbb","mbc","mbd","mbe","mbf","mbh","mbi","mbj","mbk","mbl","mbm","mbn","mbo","mbp","mbq","mbr","mbs","mbt","mbu","mbv","mbw","mbx","mby","mbz","mca","mcb","mcc","mcd","mce","mcf","mcg","mch","mci","mcj","mck","mcl","mcm","mcn","mco","mcp","mcq","mcr","mcs","mct","mcu","mcv","mcw","mcx","mcy","mcz","mda","mdb","mdc","mdd","mde","mdf","mdg","mdh","mdi","mdj","mdk","mdl","mdm","mdn","mdp","mdq","mdr","mds","mdt","mdu","mdv","mdw","mdx","mdy","mdz","mea","meb","mec","med","mee","mef","meg","meh","mei","mej","mek","mel","mem","men","meo","mep","meq","mer","mes","met","meu","mev","mew","mey","mez","mfa","mfb","mfc","mfd","mfe","mff","mfg","mfh","mfi","mfj","mfk","mfl","mfm","mfn","mfo","mfp","mfq","mfr","mfs","mft","mfu","mfv","mfw","mfx","mfy","mfz","mga","mgb","mgc","mgd","mge","mgf","mgg","mgh","mgi","mgj","mgk","mgl","mgm","mgn","mgo","mgp","mgq","mgr","mgs","mgt","mgu","mgv","mgw","mgx","mgy","mgz","mha","mhb","mhc","mhd","mhe","mhf","mhg","mhh","mhi","mhj","mhk","mhl","mhm","mhn","mho","mhp","mhq","mhr","mhs","mht","mhu","mhw","mhx","mhy","mhz","mia","mib","mic","mid","mie","mif","mig","mih","mii","mij","mik","mil","mim","min","mio","mip","miq","mir","mis","mit","miu","miw","mix","miy","miz","mja","mjb","mjc","mjd","mje","mjg","mjh","mji","mjj","mjk","mjl","mjm","mjn","mjo","mjp","mjq","mjr","mjs","mjt","mju","mjv","mjw","mjx","mjy","mjz","mka","mkb","mkc","mke","mkf","mkg","mkh","mki","mkj","mkk","mkl","mkm","mkn","mko","mkp","mkq","mkr","mks","mkt","mku","mkv","mkw","mkx","mky","mkz","mla","mlb","mlc","mld","mle","mlf","mlh","mli","mlj","mlk","mll","mlm","mln","mlo","mlp","mlq","mlr","mls","mlu","mlv","mlw","mlx","mlz","mma","mmb","mmc","mmd","mme","mmf","mmg","mmh","mmi","mmj","mmk","mml","mmm","mmn","mmo","mmp","mmq","mmr","mmt","mmu","mmv","mmw","mmx","mmy","mmz","mna","mnb","mnc","mnd","mne","mnf","mng","mnh","mni","mnj","mnk","mnl","mnm","mnn","mno","mnp","mnq","mnr","mns","mnt","mnu","mnv","mnw","mnx","mny","mnz","moa","moc","mod","moe","mof","mog","moh","moi","moj","mok","mom","moo","mop","moq","mor","mos","mot","mou","mov","mow","mox","moy","moz","mpa","mpb","mpc","mpd","mpe","mpg","mph","mpi","mpj","mpk","mpl","mpm","mpn","mpo","mpp","mpq","mpr","mps","mpt","mpu","mpv","mpw","mpx","mpy","mpz","mqa","mqb","mqc","mqe","mqf","mqg","mqh","mqi","mqj","mqk","mql","mqm","mqn","mqo","mqp","mqq","mqr","mqs","mqt","mqu","mqv","mqw","mqx","mqy","mqz","mra","mrb","mrc","mrd","mre","mrf","mrg","mrh","mrj","mrk","mrl","mrm","mrn","mro","mrp","mrq","mrr","mrs","mrt","mru","mrv","mrw","mrx","mry","mrz","msb","msc","msd","mse","msf","msg","msh","msi","msj","msk","msl","msm","msn","mso","msp","msq","msr","mss","mst","msu","msv","msw","msx","msy","msz","mta","mtb","mtc","mtd","mte","mtf","mtg","mth","mti","mtj","mtk","mtl","mtm","mtn","mto","mtp","mtq","mtr","mts","mtt","mtu","mtv","mtw","mtx","mty","mua","mub","muc","mud","mue","mug","muh","mui","muj","muk","mul","mum","mun","muo","mup","muq","mur","mus","mut","muu","muv","mux","muy","muz","mva","mvb","mvd","mve","mvf","mvg","mvh","mvi","mvk","mvl","mvm","mvn","mvo","mvp","mvq","mvr","mvs","mvt","mvu","mvv","mvw","mvx","mvy","mvz","mwa","mwb","mwc","mwd","mwe","mwf","mwg","mwh","mwi","mwj","mwk","mwl","mwm","mwn","mwo","mwp","mwq","mwr","mws","mwt","mwu","mwv","mww","mwx","mwy","mwz","mxa","mxb","mxc","mxd","mxe","mxf","mxg","mxh","mxi","mxj","mxk","mxl","mxm","mxn","mxo","mxp","mxq","mxr","mxs","mxt","mxu","mxv","mxw","mxx","mxy","mxz","myb","myc","myd","mye","myf","myg","myh","myi","myj","myk","myl","mym","myn","myo","myp","myq","myr","mys","myt","myu","myv","myw","myx","myy","myz","mza","mzb","mzc","mzd","mze","mzg","mzh","mzi","mzj","mzk","mzl","mzm","mzn","mzo","mzp","mzq","mzr","mzs","mzt","mzu","mzv","mzw","mzx","mzy","mzz","naa","nab","nac","nad","nae","naf","nag","nah","nai","naj","nak","nal","nam","nan","nao","nap","naq","nar","nas","nat","naw","nax","nay","naz","nba","nbb","nbc","nbd","nbe","nbf","nbg","nbh","nbi","nbj","nbk","nbm","nbn","nbo","nbp","nbq","nbr","nbs","nbt","nbu","nbv","nbw","nbx","nby","nca","ncb","ncc","ncd","nce","ncf","ncg","nch","nci","ncj","nck","ncl","ncm","ncn","nco","ncp","ncq","ncr","ncs","nct","ncu","ncx","ncz","nda","ndb","ndc","ndd","ndf","ndg","ndh","ndi","ndj","ndk","ndl","ndm","ndn","ndp","ndq","ndr","nds","ndt","ndu","ndv","ndw","ndx","ndy","ndz","nea","neb","nec","ned","nee","nef","neg","neh","nei","nej","nek","nem","nen","neo","neq","ner","nes","net","neu","nev","new","nex","ney","nez","nfa","nfd","nfl","nfr","nfu","nga","ngb","ngc","ngd","nge","ngf","ngg","ngh","ngi","ngj","ngk","ngl","ngm","ngn","ngo","ngp","ngq","ngr","ngs","ngt","ngu","ngv","ngw","ngx","ngy","ngz","nha","nhb","nhc","nhd","nhe","nhf","nhg","nhh","nhi","nhk","nhm","nhn","nho","nhp","nhq","nhr","nht","nhu","nhv","nhw","nhx","nhy","nhz","nia","nib","nic","nid","nie","nif","nig","nih","nii","nij","nik","nil","nim","nin","nio","niq","nir","nis","nit","niu","niv","niw","nix","niy","niz","nja","njb","njd","njh","nji","njj","njl","njm","njn","njo","njr","njs","njt","nju","njx","njy","njz","nka","nkb","nkc","nkd","nke","nkf","nkg","nkh","nki","nkj","nkk","nkm","nkn","nko","nkp","nkq","nkr","nks","nkt","nku","nkv","nkw","nkx","nkz","nla","nlc","nle","nlg","nli","nlj","nlk","nll","nln","nlo","nlq","nlr","nlu","nlv","nlw","nlx","nly","nlz","nma","nmb","nmc","nmd","nme","nmf","nmg","nmh","nmi","nmj","nmk","nml","nmm","nmn","nmo","nmp","nmq","nmr","nms","nmt","nmu","nmv","nmw","nmx","nmy","nmz","nna","nnb","nnc","nnd","nne","nnf","nng","nnh","nni","nnj","nnk","nnl","nnm","nnn","nnp","nnq","nnr","nns","nnt","nnu","nnv","nnw","nnx","nny","nnz","noa","noc","nod","noe","nof","nog","noh","noi","noj","nok","nol","nom","non","noo","nop","noq","nos","not","nou","nov","now","noy","noz","npa","npb","npg","nph","npi","npl","npn","npo","nps","npu","npx","npy","nqg","nqk","nql","nqm","nqn","nqo","nqq","nqy","nra","nrb","nrc","nre","nrf","nrg","nri","nrk","nrl","nrm","nrn","nrp","nrr","nrt","nru","nrx","nrz","nsa","nsc","nsd","nse","nsf","nsg","nsh","nsi","nsk","nsl","nsm","nsn","nso","nsp","nsq","nsr","nss","nst","nsu","nsv","nsw","nsx","nsy","nsz","ntd","nte","ntg","nti","ntj","ntk","ntm","nto","ntp","ntr","nts","ntu","ntw","ntx","nty","ntz","nua","nub","nuc","nud","nue","nuf","nug","nuh","nui","nuj","nuk","nul","num","nun","nuo","nup","nuq","nur","nus","nut","nuu","nuv","nuw","nux","nuy","nuz","nvh","nvm","nvo","nwa","nwb","nwc","nwe","nwg","nwi","nwm","nwo","nwr","nwx","nwy","nxa","nxd","nxe","nxg","nxi","nxk","nxl","nxm","nxn","nxo","nxq","nxr","nxu","nxx","nyb","nyc","nyd","nye","nyf","nyg","nyh","nyi","nyj","nyk","nyl","nym","nyn","nyo","nyp","nyq","nyr","nys","nyt","nyu","nyv","nyw","nyx","nyy","nza","nzb","nzi","nzk","nzm","nzs","nzu","nzy","nzz","oaa","oac","oar","oav","obi","obk","obl","obm","obo","obr","obt","obu","oca","och","oco","ocu","oda","odk","odt","odu","ofo","ofs","ofu","ogb","ogc","oge","ogg","ogo","ogu","oht","ohu","oia","oin","ojb","ojc","ojg","ojp","ojs","ojv","ojw","oka","okb","okd","oke","okg","okh","oki","okj","okk","okl","okm","okn","oko","okr","oks","oku","okv","okx","ola","old","ole","olk","olm","olo","olr","olt","olu","oma","omb","omc","ome","omg","omi","omk","oml","omn","omo","omp","omq","omr","omt","omu","omv","omw","omx","ona","onb","one","ong","oni","onj","onk","onn","ono","onp","onr","ons","ont","onu","onw","onx","ood","oog","oon","oor","oos","opa","opk","opm","opo","opt","opy","ora","orc","ore","org","orh","orn","oro","orr","ors","ort","oru","orv","orw","orx","ory","orz","osa","osc","osi","oso","osp","ost","osu","osx","ota","otb","otd","ote","oti","otk","otl","otm","otn","oto","otq","otr","ots","ott","otu","otw","otx","oty","otz","oua","oub","oue","oui","oum","oun","ovd","owi","owl","oyb","oyd","oym","oyy","ozm","paa","pab","pac","pad","pae","paf","pag","pah","pai","pak","pal","pam","pao","pap","paq","par","pas","pat","pau","pav","paw","pax","pay","paz","pbb","pbc","pbe","pbf","pbg","pbh","pbi","pbl","pbn","pbo","pbp","pbr","pbs","pbt","pbu","pbv","pby","pbz","pca","pcb","pcc","pcd","pce","pcf","pcg","pch","pci","pcj","pck","pcl","pcm","pcn","pcp","pcr","pcw","pda","pdc","pdi","pdn","pdo","pdt","pdu","pea","peb","ped","pee","pef","peg","peh","pei","pej","pek","pel","pem","peo","pep","peq","pes","pev","pex","pey","pez","pfa","pfe","pfl","pga","pgd","pgg","pgi","pgk","pgl","pgn","pgs","pgu","pgy","pgz","pha","phd","phg","phh","phi","phk","phl","phm","phn","pho","phq","phr","pht","phu","phv","phw","pia","pib","pic","pid","pie","pif","pig","pih","pii","pij","pil","pim","pin","pio","pip","pir","pis","pit","piu","piv","piw","pix","piy","piz","pjt","pka","pkb","pkc","pkg","pkh","pkn","pko","pkp","pkr","pks","pkt","pku","pla","plb","plc","pld","ple","plf","plg","plh","plj","plk","pll","pln","plo","plp","plq","plr","pls","plt","plu","plv","plw","ply","plz","pma","pmb","pmc","pmd","pme","pmf","pmh","pmi","pmj","pmk","pml","pmm","pmn","pmo","pmq","pmr","pms","pmt","pmu","pmw","pmx","pmy","pmz","pna","pnb","pnc","pne","png","pnh","pni","pnj","pnk","pnl","pnm","pnn","pno","pnp","pnq","pnr","pns","pnt","pnu","pnv","pnw","pnx","pny","pnz","poc","pod","poe","pof","pog","poh","poi","pok","pom","pon","poo","pop","poq","pos","pot","pov","pow","pox","poy","poz","ppa","ppe","ppi","ppk","ppl","ppm","ppn","ppo","ppp","ppq","ppr","pps","ppt","ppu","pqa","pqe","pqm","pqw","pra","prb","prc","prd","pre","prf","prg","prh","pri","prk","prl","prm","prn","pro","prp","prq","prr","prs","prt","pru","prw","prx","pry","prz","psa","psc","psd","pse","psg","psh","psi","psl","psm","psn","pso","psp","psq","psr","pss","pst","psu","psw","psy","pta","pth","pti","ptn","pto","ptp","ptq","ptr","ptt","ptu","ptv","ptw","pty","pua","pub","puc","pud","pue","puf","pug","pui","puj","puk","pum","puo","pup","puq","pur","put","puu","puw","pux","puy","puz","pwa","pwb","pwg","pwi","pwm","pwn","pwo","pwr","pww","pxm","pye","pym","pyn","pys","pyu","pyx","pyy","pzn","qaa..qtz","qua","qub","quc","qud","quf","qug","quh","qui","quk","qul","qum","qun","qup","quq","qur","qus","quv","quw","qux","quy","quz","qva","qvc","qve","qvh","qvi","qvj","qvl","qvm","qvn","qvo","qvp","qvs","qvw","qvy","qvz","qwa","qwc","qwe","qwh","qwm","qws","qwt","qxa","qxc","qxh","qxl","qxn","qxo","qxp","qxq","qxr","qxs","qxt","qxu","qxw","qya","qyp","raa","rab","rac","rad","raf","rag","rah","rai","raj","rak","ral","ram","ran","rao","rap","raq","rar","ras","rat","rau","rav","raw","rax","ray","raz","rbb","rbk","rbl","rbp","rcf","rdb","rea","reb","ree","reg","rei","rej","rel","rem","ren","rer","res","ret","rey","rga","rge","rgk","rgn","rgr","rgs","rgu","rhg","rhp","ria","rie","rif","ril","rim","rin","rir","rit","riu","rjg","rji","rjs","rka","rkb","rkh","rki","rkm","rkt","rkw","rma","rmb","rmc","rmd","rme","rmf","rmg","rmh","rmi","rmk","rml","rmm","rmn","rmo","rmp","rmq","rmr","rms","rmt","rmu","rmv","rmw","rmx","rmy","rmz","rna","rnd","rng","rnl","rnn","rnp","rnr","rnw","roa","rob","roc","rod","roe","rof","rog","rol","rom","roo","rop","ror","rou","row","rpn","rpt","rri","rro","rrt","rsb","rsi","rsl","rsm","rtc","rth","rtm","rts","rtw","rub","ruc","rue","ruf","rug","ruh","rui","ruk","ruo","rup","ruq","rut","ruu","ruy","ruz","rwa","rwk","rwm","rwo","rwr","rxd","rxw","ryn","rys","ryu","rzh","saa","sab","sac","sad","sae","saf","sah","sai","saj","sak","sal","sam","sao","sap","saq","sar","sas","sat","sau","sav","saw","sax","say","saz","sba","sbb","sbc","sbd","sbe","sbf","sbg","sbh","sbi","sbj","sbk","sbl","sbm","sbn","sbo","sbp","sbq","sbr","sbs","sbt","sbu","sbv","sbw","sbx","sby","sbz","sca","scb","sce","scf","scg","sch","sci","sck","scl","scn","sco","scp","scq","scs","sct","scu","scv","scw","scx","sda","sdb","sdc","sde","sdf","sdg","sdh","sdj","sdk","sdl","sdm","sdn","sdo","sdp","sdr","sds","sdt","sdu","sdv","sdx","sdz","sea","seb","sec","sed","see","sef","seg","seh","sei","sej","sek","sel","sem","sen","seo","sep","seq","ser","ses","set","seu","sev","sew","sey","sez","sfb","sfe","sfm","sfs","sfw","sga","sgb","sgc","sgd","sge","sgg","sgh","sgi","sgj","sgk","sgl","sgm","sgn","sgo","sgp","sgr","sgs","sgt","sgu","sgw","sgx","sgy","sgz","sha","shb","shc","shd","she","shg","shh","shi","shj","shk","shl","shm","shn","sho","shp","shq","shr","shs","sht","shu","shv","shw","shx","shy","shz","sia","sib","sid","sie","sif","sig","sih","sii","sij","sik","sil","sim","sio","sip","siq","sir","sis","sit","siu","siv","siw","six","siy","siz","sja","sjb","sjd","sje","sjg","sjk","sjl","sjm","sjn","sjo","sjp","sjr","sjs","sjt","sju","sjw","ska","skb","skc","skd","ske","skf","skg","skh","ski","skj","skk","skm","skn","sko","skp","skq","skr","sks","skt","sku","skv","skw","skx","sky","skz","sla","slc","sld","sle","slf","slg","slh","sli","slj","sll","slm","sln","slp","slq","slr","sls","slt","slu","slw","slx","sly","slz","sma","smb","smc","smd","smf","smg","smh","smi","smj","smk","sml","smm","smn","smp","smq","smr","sms","smt","smu","smv","smw","smx","smy","smz","snb","snc","sne","snf","sng","snh","sni","snj","snk","snl","snm","snn","sno","snp","snq","snr","sns","snu","snv","snw","snx","sny","snz","soa","sob","soc","sod","soe","sog","soh","soi","soj","sok","sol","son","soo","sop","soq","sor","sos","sou","sov","sow","sox","soy","soz","spb","spc","spd","spe","spg","spi","spk","spl","spm","spn","spo","spp","spq","spr","sps","spt","spu","spv","spx","spy","sqa","sqh","sqj","sqk","sqm","sqn","sqo","sqq","sqr","sqs","sqt","squ","sra","srb","src","sre","srf","srg","srh","sri","srk","srl","srm","srn","sro","srq","srr","srs","srt","sru","srv","srw","srx","sry","srz","ssa","ssb","ssc","ssd","sse","ssf","ssg","ssh","ssi","ssj","ssk","ssl","ssm","ssn","sso","ssp","ssq","ssr","sss","sst","ssu","ssv","ssx","ssy","ssz","sta","stb","std","ste","stf","stg","sth","sti","stj","stk","stl","stm","stn","sto","stp","stq","str","sts","stt","stu","stv","stw","sty","sua","sub","suc","sue","sug","sui","suj","suk","sul","sum","suq","sur","sus","sut","suv","suw","sux","suy","suz","sva","svb","svc","sve","svk","svm","svr","svs","svx","swb","swc","swf","swg","swh","swi","swj","swk","swl","swm","swn","swo","swp","swq","swr","sws","swt","swu","swv","sww","swx","swy","sxb","sxc","sxe","sxg","sxk","sxl","sxm","sxn","sxo","sxr","sxs","sxu","sxw","sya","syb","syc","syd","syi","syk","syl","sym","syn","syo","syr","sys","syw","syx","syy","sza","szb","szc","szd","sze","szg","szl","szn","szp","szs","szv","szw","taa","tab","tac","tad","tae","taf","tag","tai","taj","tak","tal","tan","tao","tap","taq","tar","tas","tau","tav","taw","tax","tay","taz","tba","tbb","tbc","tbd","tbe","tbf","tbg","tbh","tbi","tbj","tbk","tbl","tbm","tbn","tbo","tbp","tbq","tbr","tbs","tbt","tbu","tbv","tbw","tbx","tby","tbz","tca","tcb","tcc","tcd","tce","tcf","tcg","tch","tci","tck","tcl","tcm","tcn","tco","tcp","tcq","tcs","tct","tcu","tcw","tcx","tcy","tcz","tda","tdb","tdc","tdd","tde","tdf","tdg","tdh","tdi","tdj","tdk","tdl","tdm","tdn","tdo","tdq","tdr","tds","tdt","tdu","tdv","tdx","tdy","tea","teb","tec","ted","tee","tef","teg","teh","tei","tek","tem","ten","teo","tep","teq","ter","tes","tet","teu","tev","tew","tex","tey","tfi","tfn","tfo","tfr","tft","tga","tgb","tgc","tgd","tge","tgf","tgg","tgh","tgi","tgj","tgn","tgo","tgp","tgq","tgr","tgs","tgt","tgu","tgv","tgw","tgx","tgy","tgz","thc","thd","the","thf","thh","thi","thk","thl","thm","thn","thp","thq","thr","ths","tht","thu","thv","thw","thx","thy","thz","tia","tic","tid","tie","tif","tig","tih","tii","tij","tik","til","tim","tin","tio","tip","tiq","tis","tit","tiu","tiv","tiw","tix","tiy","tiz","tja","tjg","tji","tjl","tjm","tjn","tjo","tjs","tju","tjw","tka","tkb","tkd","tke","tkf","tkg","tkk","tkl","tkm","tkn","tkp","tkq","tkr","tks","tkt","tku","tkv","tkw","tkx","tkz","tla","tlb","tlc","tld","tlf","tlg","tlh","tli","tlj","tlk","tll","tlm","tln","tlo","tlp","tlq","tlr","tls","tlt","tlu","tlv","tlw","tlx","tly","tma","tmb","tmc","tmd","tme","tmf","tmg","tmh","tmi","tmj","tmk","tml","tmm","tmn","tmo","tmp","tmq","tmr","tms","tmt","tmu","tmv","tmw","tmy","tmz","tna","tnb","tnc","tnd","tne","tnf","tng","tnh","tni","tnk","tnl","tnm","tnn","tno","tnp","tnq","tnr","tns","tnt","tnu","tnv","tnw","tnx","tny","tnz","tob","toc","tod","toe","tof","tog","toh","toi","toj","tol","tom","too","top","toq","tor","tos","tou","tov","tow","tox","toy","toz","tpa","tpc","tpe","tpf","tpg","tpi","tpj","tpk","tpl","tpm","tpn","tpo","tpp","tpq","tpr","tpt","tpu","tpv","tpw","tpx","tpy","tpz","tqb","tql","tqm","tqn","tqo","tqp","tqq","tqr","tqt","tqu","tqw","tra","trb","trc","trd","tre","trf","trg","trh","tri","trj","trk","trl","trm","trn","tro","trp","trq","trr","trs","trt","tru","trv","trw","trx","try","trz","tsa","tsb","tsc","tsd","tse","tsf","tsg","tsh","tsi","tsj","tsk","tsl","tsm","tsp","tsq","tsr","tss","tst","tsu","tsv","tsw","tsx","tsy","tsz","tta","ttb","ttc","ttd","tte","ttf","ttg","tth","tti","ttj","ttk","ttl","ttm","ttn","tto","ttp","ttq","ttr","tts","ttt","ttu","ttv","ttw","tty","ttz","tua","tub","tuc","tud","tue","tuf","tug","tuh","tui","tuj","tul","tum","tun","tuo","tup","tuq","tus","tut","tuu","tuv","tuw","tux","tuy","tuz","tva","tvd","tve","tvk","tvl","tvm","tvn","tvo","tvs","tvt","tvu","tvw","tvy","twa","twb","twc","twd","twe","twf","twg","twh","twl","twm","twn","two","twp","twq","twr","twt","twu","tww","twx","twy","txa","txb","txc","txe","txg","txh","txi","txj","txm","txn","txo","txq","txr","txs","txt","txu","txx","txy","tya","tye","tyh","tyi","tyj","tyl","tyn","typ","tyr","tys","tyt","tyu","tyv","tyx","tyz","tza","tzh","tzj","tzl","tzm","tzn","tzo","tzx","uam","uan","uar","uba","ubi","ubl","ubr","ubu","uby","uda","ude","udg","udi","udj","udl","udm","udu","ues","ufi","uga","ugb","uge","ugn","ugo","ugy","uha","uhn","uis","uiv","uji","uka","ukg","ukh","ukk","ukl","ukp","ukq","uks","uku","ukw","uky","ula","ulb","ulc","ule","ulf","uli","ulk","ull","ulm","uln","ulu","ulw","uma","umb","umc","umd","umg","umi","umm","umn","umo","ump","umr","ums","umu","una","und","une","ung","unk","unm","unn","unp","unr","unu","unx","unz","uok","upi","upv","ura","urb","urc","ure","urf","urg","urh","uri","urj","urk","url","urm","urn","uro","urp","urr","urt","uru","urv","urw","urx","ury","urz","usa","ush","usi","usk","usp","usu","uta","ute","utp","utr","utu","uum","uun","uur","uuu","uve","uvh","uvl","uwa","uya","uzn","uzs","vaa","vae","vaf","vag","vah","vai","vaj","val","vam","van","vao","vap","var","vas","vau","vav","vay","vbb","vbk","vec","ved","vel","vem","veo","vep","ver","vgr","vgt","vic","vid","vif","vig","vil","vin","vis","vit","viv","vka","vki","vkj","vkk","vkl","vkm","vko","vkp","vkt","vku","vlp","vls","vma","vmb","vmc","vmd","vme","vmf","vmg","vmh","vmi","vmj","vmk","vml","vmm","vmp","vmq","vmr","vms","vmu","vmv","vmw","vmx","vmy","vmz","vnk","vnm","vnp","vor","vot","vra","vro","vrs","vrt","vsi","vsl","vsv","vto","vum","vun","vut","vwa","waa","wab","wac","wad","wae","waf","wag","wah","wai","waj","wak","wal","wam","wan","wao","wap","waq","war","was","wat","wau","wav","waw","wax","way","waz","wba","wbb","wbe","wbf","wbh","wbi","wbj","wbk","wbl","wbm","wbp","wbq","wbr","wbs","wbt","wbv","wbw","wca","wci","wdd","wdg","wdj","wdk","wdu","wdy","wea","wec","wed","weg","weh","wei","wem","wen","weo","wep","wer","wes","wet","weu","wew","wfg","wga","wgb","wgg","wgi","wgo","wgu","wgw","wgy","wha","whg","whk","whu","wib","wic","wie","wif","wig","wih","wii","wij","wik","wil","wim","win","wir","wit","wiu","wiv","wiw","wiy","wja","wji","wka","wkb","wkd","wkl","wku","wkw","wky","wla","wlc","wle","wlg","wli","wlk","wll","wlm","wlo","wlr","wls","wlu","wlv","wlw","wlx","wly","wma","wmb","wmc","wmd","wme","wmh","wmi","wmm","wmn","wmo","wms","wmt","wmw","wmx","wnb","wnc","wnd","wne","wng","wni","wnk","wnm","wnn","wno","wnp","wnu","wnw","wny","woa","wob","woc","wod","woe","wof","wog","woi","wok","wom","won","woo","wor","wos","wow","woy","wpc","wra","wrb","wrd","wrg","wrh","wri","wrk","wrl","wrm","wrn","wro","wrp","wrr","wrs","wru","wrv","wrw","wrx","wry","wrz","wsa","wsg","wsi","wsk","wsr","wss","wsu","wsv","wtf","wth","wti","wtk","wtm","wtw","wua","wub","wud","wuh","wul","wum","wun","wur","wut","wuu","wuv","wux","wuy","wwa","wwb","wwo","wwr","www","wxa","wxw","wya","wyb","wyi","wym","wyr","wyy","xaa","xab","xac","xad","xae","xag","xai","xaj","xak","xal","xam","xan","xao","xap","xaq","xar","xas","xat","xau","xav","xaw","xay","xba","xbb","xbc","xbd","xbe","xbg","xbi","xbj","xbm","xbn","xbo","xbp","xbr","xbw","xbx","xby","xcb","xcc","xce","xcg","xch","xcl","xcm","xcn","xco","xcr","xct","xcu","xcv","xcw","xcy","xda","xdc","xdk","xdm","xdo","xdy","xeb","xed","xeg","xel","xem","xep","xer","xes","xet","xeu","xfa","xga","xgb","xgd","xgf","xgg","xgi","xgl","xgm","xgn","xgr","xgu","xgw","xha","xhc","xhd","xhe","xhr","xht","xhu","xhv","xia","xib","xii","xil","xin","xip","xir","xis","xiv","xiy","xjb","xjt","xka","xkb","xkc","xkd","xke","xkf","xkg","xkh","xki","xkj","xkk","xkl","xkn","xko","xkp","xkq","xkr","xks","xkt","xku","xkv","xkw","xkx","xky","xkz","xla","xlb","xlc","xld","xle","xlg","xli","xln","xlo","xlp","xls","xlu","xly","xma","xmb","xmc","xmd","xme","xmf","xmg","xmh","xmj","xmk","xml","xmm","xmn","xmo","xmp","xmq","xmr","xms","xmt","xmu","xmv","xmw","xmx","xmy","xmz","xna","xnb","xnd","xng","xnh","xni","xnk","xnn","xno","xnr","xns","xnt","xnu","xny","xnz","xoc","xod","xog","xoi","xok","xom","xon","xoo","xop","xor","xow","xpa","xpc","xpe","xpg","xpi","xpj","xpk","xpm","xpn","xpo","xpp","xpq","xpr","xps","xpt","xpu","xpy","xqa","xqt","xra","xrb","xrd","xre","xrg","xri","xrm","xrn","xrq","xrr","xrt","xru","xrw","xsa","xsb","xsc","xsd","xse","xsh","xsi","xsj","xsl","xsm","xsn","xso","xsp","xsq","xsr","xss","xsu","xsv","xsy","xta","xtb","xtc","xtd","xte","xtg","xth","xti","xtj","xtl","xtm","xtn","xto","xtp","xtq","xtr","xts","xtt","xtu","xtv","xtw","xty","xtz","xua","xub","xud","xug","xuj","xul","xum","xun","xuo","xup","xur","xut","xuu","xve","xvi","xvn","xvo","xvs","xwa","xwc","xwd","xwe","xwg","xwj","xwk","xwl","xwo","xwr","xwt","xww","xxb","xxk","xxm","xxr","xxt","xya","xyb","xyj","xyk","xyl","xyt","xyy","xzh","xzm","xzp","yaa","yab","yac","yad","yae","yaf","yag","yah","yai","yaj","yak","yal","yam","yan","yao","yap","yaq","yar","yas","yat","yau","yav","yaw","yax","yay","yaz","yba","ybb","ybd","ybe","ybh","ybi","ybj","ybk","ybl","ybm","ybn","ybo","ybx","yby","ych","ycl","ycn","ycp","yda","ydd","yde","ydg","ydk","yds","yea","yec","yee","yei","yej","yel","yen","yer","yes","yet","yeu","yev","yey","yga","ygi","ygl","ygm","ygp","ygr","ygs","ygu","ygw","yha","yhd","yhl","yhs","yia","yif","yig","yih","yii","yij","yik","yil","yim","yin","yip","yiq","yir","yis","yit","yiu","yiv","yix","yiy","yiz","yka","ykg","yki","ykk","ykl","ykm","ykn","yko","ykr","ykt","yku","yky","yla","ylb","yle","ylg","yli","yll","ylm","yln","ylo","ylr","ylu","yly","yma","ymb","ymc","ymd","yme","ymg","ymh","ymi","ymk","yml","ymm","ymn","ymo","ymp","ymq","ymr","yms","ymt","ymx","ymz","yna","ynd","yne","yng","ynh","ynk","ynl","ynn","yno","ynq","yns","ynu","yob","yog","yoi","yok","yol","yom","yon","yos","yot","yox","yoy","ypa","ypb","ypg","yph","ypk","ypm","ypn","ypo","ypp","ypz","yra","yrb","yre","yri","yrk","yrl","yrm","yrn","yro","yrs","yrw","yry","ysc","ysd","ysg","ysl","ysn","yso","ysp","ysr","yss","ysy","yta","ytl","ytp","ytw","yty","yua","yub","yuc","yud","yue","yuf","yug","yui","yuj","yuk","yul","yum","yun","yup","yuq","yur","yut","yuu","yuw","yux","yuy","yuz","yva","yvt","ywa","ywg","ywl","ywn","ywq","ywr","ywt","ywu","yww","yxa","yxg","yxl","yxm","yxu","yxy","yyr","yyu","yyz","yzg","yzk","zaa","zab","zac","zad","zae","zaf","zag","zah","zai","zaj","zak","zal","zam","zao","zap","zaq","zar","zas","zat","zau","zav","zaw","zax","zay","zaz","zbc","zbe","zbl","zbt","zbw","zca","zch","zdj","zea","zeg","zeh","zen","zga","zgb","zgh","zgm","zgn","zgr","zhb","zhd","zhi","zhn","zhw","zhx","zia","zib","zik","zil","zim","zin","zir","ziw","ziz","zka","zkb","zkd","zkg","zkh","zkk","zkn","zko","zkp","zkr","zkt","zku","zkv","zkz","zle","zlj","zlm","zln","zlq","zls","zlw","zma","zmb","zmc","zmd","zme","zmf","zmg","zmh","zmi","zmj","zmk","zml","zmm","zmn","zmo","zmp","zmq","zmr","zms","zmt","zmu","zmv","zmw","zmx","zmy","zmz","zna","znd","zne","zng","znk","zns","zoc","zoh","zom","zoo","zoq","zor","zos","zpa","zpb","zpc","zpd","zpe","zpf","zpg","zph","zpi","zpj","zpk","zpl","zpm","zpn","zpo","zpp","zpq","zpr","zps","zpt","zpu","zpv","zpw","zpx","zpy","zpz","zqe","zra","zrg","zrn","zro","zrp","zrs","zsa","zsk","zsl","zsm","zsr","zsu","zte","ztg","ztl","ztm","ztn","ztp","ztq","zts","ztt","ztu","ztx","zty","zua","zuh","zum","zun","zuy","zwa","zxx","zyb","zyg","zyj","zyn","zyp","zza","zzj"]
-;return axe.utils.validLangs=function(){"use strict";return L},commons}()})}("object"==typeof window?window:this);
\ No newline at end of file
+!function e(window){var a=window,document=window.document;function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function l(e){this.name="SupportError",this.cause=e.cause,this.message="`".concat(e.cause,"` - feature unsupported in your environment."),e.ruleId&&(this.ruleId=e.ruleId,this.message+=" Skipping ".concat(this.ruleId," rule.")),this.stack=(new Error).stack}(axe=axe||{}).version="3.3.2","function"==typeof define&&define.amd&&define("axe-core",[],function(){"use strict";return axe}),"object"===("undefined"==typeof module?"undefined":S(module))&&module.exports&&"function"==typeof e.toString&&(axe.source="("+e.toString()+')(typeof window === "object" ? window : this);',module.exports=axe),"function"==typeof window.getComputedStyle&&(window.axe=axe),(l.prototype=Object.create(Error.prototype)).constructor=l,function o(i,u,s){function l(t,e){if(!u[t]){if(!i[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(c)return c(t,!0);var r=new Error("Cannot find module '"+t+"'");throw r.code="MODULE_NOT_FOUND",r}var a=u[t]={exports:{}};i[t][0].call(a.exports,function(e){return l(i[t][1][e]||e)},a,a.exports,o,i,u,s)}return u[t].exports}for(var c="function"==typeof require&&require,e=0;e<s.length;e++)l(s[e]);return l}({1:[function(e,t,n){"Promise"in window||e("es6-promise").polyfill(),e("weakmap-polyfill"),axe.imports={axios:e("axios"),CssSelectorParser:e("css-selector-parser").CssSelectorParser,doT:e("@deque/dot"),emojiRegexText:e("emoji-regex")}},{"@deque/dot":2,axios:3,"css-selector-parser":29,"emoji-regex":31,"es6-promise":32,"weakmap-polyfill":34}],2:[function(e,t,n){!function(){"use strict";var s={name:"doT",version:"1.1.1",templateSettings:{evaluate:/\{\{([\s\S]+?(\}?)+)\}\}/g,interpolate:/\{\{=([\s\S]+?)\}\}/g,encode:/\{\{!([\s\S]+?)\}\}/g,use:/\{\{#([\s\S]+?)\}\}/g,useParams:/(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,define:/\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,defineParams:/^\s*([\w$]+):([\s\S]+)/,conditional:/\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,iterate:/\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,varname:"it",strip:!0,append:!0,selfcontained:!1,doNotSkipEncoded:!1},template:void 0,compile:void 0,log:!0};"object"!=typeof globalThis&&(Object.defineProperty(Object.prototype,"__magic__",{get:function(){return this},configurable:!0}),__magic__.globalThis=__magic__,delete Object.prototype.__magic__),s.encodeHTMLSource=function(e){var t={"&":"&#38;","<":"&#60;",">":"&#62;",'"':"&#34;","'":"&#39;","/":"&#47;"},n=e?/[&<>"'\/]/g:/&(?!#?\w+;)|<|>|"|'|\//g;return function(e){return e?e.toString().replace(n,function(e){return t[e]||e}):""}},void 0!==t&&t.exports?t.exports=s:"function"==typeof define&&define.amd?define(function(){return s}):globalThis.doT=s;var l={append:{start:"'+(",end:")+'",startencode:"'+encodeHTML("},split:{start:"';out+=(",end:");out+='",startencode:"';out+=encodeHTML("}},c=/$^/;function d(e){return e.replace(/\\('|\\)/g,"$1").replace(/[\r\t\n]/g," ")}s.template=function(e,t,n){var r,a,o=(t=t||s.templateSettings).append?l.append:l.split,i=0,u=t.use||t.define?function r(a,e,o){return("string"==typeof e?e:e.toString()).replace(a.define||c,function(e,r,t,n){return 0===r.indexOf("def.")&&(r=r.substring(4)),r in o||(":"===t?(a.defineParams&&n.replace(a.defineParams,function(e,t,n){o[r]={arg:t,text:n}}),r in o||(o[r]=n)):new Function("def","def['"+r+"']="+n)(o)),""}).replace(a.use||c,function(e,t){a.useParams&&(t=t.replace(a.useParams,function(e,t,n,r){if(o[n]&&o[n].arg&&r){var a=(n+":"+r).replace(/'|\\/g,"_");return o.__exp=o.__exp||{},o.__exp[a]=o[n].text.replace(new RegExp("(^|[^\\w$])"+o[n].arg+"([^\\w$])","g"),"$1"+r+"$2"),t+"def.__exp['"+a+"']"}}));var n=new Function("def","return "+t)(o);return n?r(a,n,o):n})}(t,e,n||{}):e;u=("var out='"+(t.strip?u.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g," ").replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,""):u).replace(/'|\\/g,"\\$&").replace(t.interpolate||c,function(e,t){return o.start+d(t)+o.end}).replace(t.encode||c,function(e,t){return r=!0,o.startencode+d(t)+o.end}).replace(t.conditional||c,function(e,t,n){return t?n?"';}else if("+d(n)+"){out+='":"';}else{out+='":n?"';if("+d(n)+"){out+='":"';}out+='"}).replace(t.iterate||c,function(e,t,n,r){return t?(i+=1,a=r||"i"+i,t=d(t),"';var arr"+i+"="+t+";if(arr"+i+"){var "+n+","+a+"=-1,l"+i+"=arr"+i+".length-1;while("+a+"<l"+i+"){"+n+"=arr"+i+"["+a+"+=1];out+='"):"';} } out+='"}).replace(t.evaluate||c,function(e,t){return"';"+d(t)+"out+='"})+"';return out;").replace(/\n/g,"\\n").replace(/\t/g,"\\t").replace(/\r/g,"\\r").replace(/(\s|;|\}|^|\{)out\+='';/g,"$1").replace(/\+''/g,""),r&&(t.selfcontained||!globalThis||globalThis._encodeHTML||(globalThis._encodeHTML=s.encodeHTMLSource(t.doNotSkipEncoded)),u="var encodeHTML = typeof _encodeHTML !== 'undefined' ? _encodeHTML : ("+s.encodeHTMLSource.toString()+"("+(t.doNotSkipEncoded||"")+"));"+u);try{return new Function(t.varname,u)}catch(e){throw"undefined"!=typeof console&&console.log("Could not create a template function: "+u),e}},s.compile=function(e,t){return s.template(e,null,t)}}()},{}],3:[function(e,t,n){t.exports=e("./lib/axios")},{"./lib/axios":5}],4:[function(c,e,t){"use strict";var utils=c("./../utils"),d=c("./../core/settle"),m=c("./../helpers/buildURL"),p=c("./../helpers/parseHeaders"),f=c("./../helpers/isURLSameOrigin"),h=c("../core/createError");e.exports=function(l){return new Promise(function(n,r){var a=l.data,o=l.headers;utils.isFormData(a)&&delete o["Content-Type"];var i=new XMLHttpRequest;if(l.auth){var e=l.auth.username||"",t=l.auth.password||"";o.Authorization="Basic "+btoa(e+":"+t)}if(i.open(l.method.toUpperCase(),m(l.url,l.params,l.paramsSerializer),!0),i.timeout=l.timeout,i.onreadystatechange=function(){if(i&&4===i.readyState&&(0!==i.status||i.responseURL&&0===i.responseURL.indexOf("file:"))){var e="getAllResponseHeaders"in i?p(i.getAllResponseHeaders()):null,t={data:l.responseType&&"text"!==l.responseType?i.response:i.responseText,status:i.status,statusText:i.statusText,headers:e,config:l,request:i};d(n,r,t),i=null}},i.onabort=function(){i&&(r(h("Request aborted",l,"ECONNABORTED",i)),i=null)},i.onerror=function(){r(h("Network Error",l,null,i)),i=null},i.ontimeout=function(){r(h("timeout of "+l.timeout+"ms exceeded",l,"ECONNABORTED",i)),i=null},utils.isStandardBrowserEnv()){var u=c("./../helpers/cookies"),s=(l.withCredentials||f(l.url))&&l.xsrfCookieName?u.read(l.xsrfCookieName):void 0;s&&(o[l.xsrfHeaderName]=s)}if("setRequestHeader"in i&&utils.forEach(o,function(e,t){void 0===a&&"content-type"===t.toLowerCase()?delete o[t]:i.setRequestHeader(t,e)}),l.withCredentials&&(i.withCredentials=!0),l.responseType)try{i.responseType=l.responseType}catch(e){if("json"!==l.responseType)throw e}"function"==typeof l.onDownloadProgress&&i.addEventListener("progress",l.onDownloadProgress),"function"==typeof l.onUploadProgress&&i.upload&&i.upload.addEventListener("progress",l.onUploadProgress),l.cancelToken&&l.cancelToken.promise.then(function(e){i&&(i.abort(),r(e),i=null)}),void 0===a&&(a=null),i.send(a)})}},{"../core/createError":11,"./../core/settle":15,"./../helpers/buildURL":19,"./../helpers/cookies":21,"./../helpers/isURLSameOrigin":23,"./../helpers/parseHeaders":25,"./../utils":27}],5:[function(e,t,n){"use strict";var utils=e("./utils"),r=e("./helpers/bind"),a=e("./core/Axios"),o=e("./core/mergeConfig");function i(e){var t=new a(e),n=r(a.prototype.request,t);return utils.extend(n,a.prototype,t),utils.extend(n,t),n}var u=i(e("./defaults"));u.Axios=a,u.create=function(e){return i(o(u.defaults,e))},u.Cancel=e("./cancel/Cancel"),u.CancelToken=e("./cancel/CancelToken"),u.isCancel=e("./cancel/isCancel"),u.all=function(e){return Promise.all(e)},u.spread=e("./helpers/spread"),t.exports=u,t.exports.default=u},{"./cancel/Cancel":6,"./cancel/CancelToken":7,"./cancel/isCancel":8,"./core/Axios":9,"./core/mergeConfig":14,"./defaults":17,"./helpers/bind":18,"./helpers/spread":26,"./utils":27}],6:[function(e,t,n){"use strict";function r(e){this.message=e}r.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},r.prototype.__CANCEL__=!0,t.exports=r},{}],7:[function(e,t,n){"use strict";var r=e("./Cancel");function a(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise(function(e){t=e});var n=this;e(function(e){n.reason||(n.reason=new r(e),t(n.reason))})}a.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},a.source=function(){var t;return{token:new a(function(e){t=e}),cancel:t}},t.exports=a},{"./Cancel":6}],8:[function(e,t,n){"use strict";t.exports=function(e){return!(!e||!e.__CANCEL__)}},{}],9:[function(e,t,n){"use strict";var utils=e("./../utils"),r=e("../helpers/buildURL"),a=e("./InterceptorManager"),o=e("./dispatchRequest"),i=e("./mergeConfig");function u(e){this.defaults=e,this.interceptors={request:new a,response:new a}}u.prototype.request=function(e,t){"string"==typeof e?(e=t||{}).url=arguments[0]:e=e||{},(e=i(this.defaults,e)).method=e.method?e.method.toLowerCase():"get";var n=[o,void 0],r=Promise.resolve(e);for(this.interceptors.request.forEach(function(e){n.unshift(e.fulfilled,e.rejected)}),this.interceptors.response.forEach(function(e){n.push(e.fulfilled,e.rejected)});n.length;)r=r.then(n.shift(),n.shift());return r},u.prototype.getUri=function(e){return e=i(this.defaults,e),r(e.url,e.params,e.paramsSerializer).replace(/^\?/,"")},utils.forEach(["delete","get","head","options"],function(n){u.prototype[n]=function(e,t){return this.request(utils.merge(t||{},{method:n,url:e}))}}),utils.forEach(["post","put","patch"],function(r){u.prototype[r]=function(e,t,n){return this.request(utils.merge(n||{},{method:r,url:e,data:t}))}}),t.exports=u},{"../helpers/buildURL":19,"./../utils":27,"./InterceptorManager":10,"./dispatchRequest":12,"./mergeConfig":14}],10:[function(e,t,n){"use strict";var utils=e("./../utils");function r(){this.handlers=[]}r.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},r.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},r.prototype.forEach=function(t){utils.forEach(this.handlers,function(e){null!==e&&t(e)})},t.exports=r},{"./../utils":27}],11:[function(e,t,n){"use strict";var i=e("./enhanceError");t.exports=function(e,t,n,r,a){var o=new Error(e);return i(o,t,n,r,a)}},{"./enhanceError":13}],12:[function(e,t,n){"use strict";var utils=e("./../utils"),r=e("./transformData"),a=e("../cancel/isCancel"),o=e("../defaults"),i=e("./../helpers/isAbsoluteURL"),u=e("./../helpers/combineURLs");function s(e){e.cancelToken&&e.cancelToken.throwIfRequested()}t.exports=function(t){return s(t),t.baseURL&&!i(t.url)&&(t.url=u(t.baseURL,t.url)),t.headers=t.headers||{},t.data=r(t.data,t.headers,t.transformRequest),t.headers=utils.merge(t.headers.common||{},t.headers[t.method]||{},t.headers||{}),utils.forEach(["delete","get","head","post","put","patch","common"],function(e){delete t.headers[e]}),(t.adapter||o.adapter)(t).then(function(e){return s(t),e.data=r(e.data,e.headers,t.transformResponse),e},function(e){return a(e)||(s(t),e&&e.response&&(e.response.data=r(e.response.data,e.response.headers,t.transformResponse))),Promise.reject(e)})}},{"../cancel/isCancel":8,"../defaults":17,"./../helpers/combineURLs":20,"./../helpers/isAbsoluteURL":22,"./../utils":27,"./transformData":16}],13:[function(e,t,n){"use strict";t.exports=function(e,t,n,r,a){return e.config=t,n&&(e.code=n),e.request=r,e.response=a,e.isAxiosError=!0,e.toJSON=function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:this.config,code:this.code}},e}},{}],14:[function(e,t,n){"use strict";var utils=e("../utils");t.exports=function(t,n){n=n||{};var r={};return utils.forEach(["url","method","params","data"],function(e){void 0!==n[e]&&(r[e]=n[e])}),utils.forEach(["headers","auth","proxy"],function(e){utils.isObject(n[e])?r[e]=utils.deepMerge(t[e],n[e]):void 0!==n[e]?r[e]=n[e]:utils.isObject(t[e])?r[e]=utils.deepMerge(t[e]):void 0!==t[e]&&(r[e]=t[e])}),utils.forEach(["baseURL","transformRequest","transformResponse","paramsSerializer","timeout","withCredentials","adapter","responseType","xsrfCookieName","xsrfHeaderName","onUploadProgress","onDownloadProgress","maxContentLength","validateStatus","maxRedirects","httpAgent","httpsAgent","cancelToken","socketPath"],function(e){void 0!==n[e]?r[e]=n[e]:void 0!==t[e]&&(r[e]=t[e])}),r}},{"../utils":27}],15:[function(e,t,n){"use strict";var a=e("./createError");t.exports=function(e,t,n){var r=n.config.validateStatus;!r||r(n.status)?e(n):t(a("Request failed with status code "+n.status,n.config,null,n.request,n))}},{"./createError":11}],16:[function(e,t,n){"use strict";var utils=e("./../utils");t.exports=function(t,n,e){return utils.forEach(e,function(e){t=e(t,n)}),t}},{"./../utils":27}],17:[function(i,u,e){(function(e){"use strict";var utils=i("./utils"),n=i("./helpers/normalizeHeaderName"),t={"Content-Type":"application/x-www-form-urlencoded"};function r(e,t){!utils.isUndefined(e)&&utils.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}var a,o={adapter:(void 0!==e&&"[object process]"===Object.prototype.toString.call(e)?a=i("./adapters/http"):"undefined"!=typeof XMLHttpRequest&&(a=i("./adapters/xhr")),a),transformRequest:[function(e,t){return n(t,"Accept"),n(t,"Content-Type"),utils.isFormData(e)||utils.isArrayBuffer(e)||utils.isBuffer(e)||utils.isStream(e)||utils.isFile(e)||utils.isBlob(e)?e:utils.isArrayBufferView(e)?e.buffer:utils.isURLSearchParams(e)?(r(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):utils.isObject(e)?(r(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(e){}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return 200<=e&&e<300}};o.headers={common:{Accept:"application/json, text/plain, */*"}},utils.forEach(["delete","get","head"],function(e){o.headers[e]={}}),utils.forEach(["post","put","patch"],function(e){o.headers[e]=utils.merge(t)}),u.exports=o}).call(this,i("_process"))},{"./adapters/http":4,"./adapters/xhr":4,"./helpers/normalizeHeaderName":24,"./utils":27,_process:33}],18:[function(e,t,n){"use strict";t.exports=function(n,r){return function(){for(var e=new Array(arguments.length),t=0;t<e.length;t++)e[t]=arguments[t];return n.apply(r,e)}}},{}],19:[function(e,t,n){"use strict";var utils=e("./../utils");function i(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}t.exports=function(e,t,n){if(!t)return e;var r;if(n)r=n(t);else if(utils.isURLSearchParams(t))r=t.toString();else{var a=[];utils.forEach(t,function(e,t){null!=e&&(utils.isArray(e)?t+="[]":e=[e],utils.forEach(e,function(e){utils.isDate(e)?e=e.toISOString():utils.isObject(e)&&(e=JSON.stringify(e)),a.push(i(t)+"="+i(e))}))}),r=a.join("&")}if(r){var o=e.indexOf("#");-1!==o&&(e=e.slice(0,o)),e+=(-1===e.indexOf("?")?"?":"&")+r}return e}},{"./../utils":27}],20:[function(e,t,n){"use strict";t.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},{}],21:[function(e,t,n){"use strict";var utils=e("./../utils");t.exports=utils.isStandardBrowserEnv()?{write:function(e,t,n,r,a,o){var i=[];i.push(e+"="+encodeURIComponent(t)),utils.isNumber(n)&&i.push("expires="+new Date(n).toGMTString()),utils.isString(r)&&i.push("path="+r),utils.isString(a)&&i.push("domain="+a),!0===o&&i.push("secure"),document.cookie=i.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}:{write:function(){},read:function(){return null},remove:function(){}}},{"./../utils":27}],22:[function(e,t,n){"use strict";t.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},{}],23:[function(e,t,n){"use strict";var r,a,o,utils=e("./../utils");function i(e){var t=e;return a&&(o.setAttribute("href",t),t=o.href),o.setAttribute("href",t),{href:o.href,protocol:o.protocol?o.protocol.replace(/:$/,""):"",host:o.host,search:o.search?o.search.replace(/^\?/,""):"",hash:o.hash?o.hash.replace(/^#/,""):"",hostname:o.hostname,port:o.port,pathname:"/"===o.pathname.charAt(0)?o.pathname:"/"+o.pathname}}t.exports=utils.isStandardBrowserEnv()?(a=/(msie|trident)/i.test(navigator.userAgent),o=document.createElement("a"),r=i(window.location.href),function(e){var t=utils.isString(e)?i(e):e;return t.protocol===r.protocol&&t.host===r.host}):function(){return!0}},{"./../utils":27}],24:[function(e,t,n){"use strict";var utils=e("../utils");t.exports=function(n,r){utils.forEach(n,function(e,t){t!==r&&t.toUpperCase()===r.toUpperCase()&&(n[r]=e,delete n[t])})}},{"../utils":27}],25:[function(e,t,n){"use strict";var utils=e("./../utils"),o=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];t.exports=function(e){var t,n,r,a={};return e&&utils.forEach(e.split("\n"),function(e){if(r=e.indexOf(":"),t=utils.trim(e.substr(0,r)).toLowerCase(),n=utils.trim(e.substr(r+1)),t){if(a[t]&&0<=o.indexOf(t))return;a[t]="set-cookie"===t?(a[t]?a[t]:[]).concat([n]):a[t]?a[t]+", "+n:n}}),a}},{"./../utils":27}],26:[function(e,t,n){"use strict";t.exports=function(t){return function(e){return t.apply(null,e)}}},{}],27:[function(e,t,n){"use strict";var a=e("./helpers/bind"),r=e("is-buffer"),o=Object.prototype.toString;function i(e){return"[object Array]"===o.call(e)}function u(e){return null!==e&&"object"==typeof e}function s(e){return"[object Function]"===o.call(e)}function l(e,t){if(null!=e)if("object"!=typeof e&&(e=[e]),i(e))for(var n=0,r=e.length;n<r;n++)t.call(null,e[n],n,e);else for(var a in e)Object.prototype.hasOwnProperty.call(e,a)&&t.call(null,e[a],a,e)}t.exports={isArray:i,isArrayBuffer:function(e){return"[object ArrayBuffer]"===o.call(e)},isBuffer:r,isFormData:function(e){return"undefined"!=typeof FormData&&e instanceof FormData},isArrayBufferView:function(e){return"undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer},isString:function(e){return"string"==typeof e},isNumber:function(e){return"number"==typeof e},isObject:u,isUndefined:function(e){return void 0===e},isDate:function(e){return"[object Date]"===o.call(e)},isFile:function(e){return"[object File]"===o.call(e)},isBlob:function(e){return"[object Blob]"===o.call(e)},isFunction:s,isStream:function(e){return u(e)&&s(e.pipe)},isURLSearchParams:function(e){return"undefined"!=typeof URLSearchParams&&e instanceof URLSearchParams},isStandardBrowserEnv:function(){return("undefined"==typeof navigator||"ReactNative"!==navigator.product&&"NativeScript"!==navigator.product&&"NS"!==navigator.product)&&(void 0!==window&&void 0!==document)},forEach:l,merge:function n(){var r={};function e(e,t){"object"==typeof r[t]&&"object"==typeof e?r[t]=n(r[t],e):r[t]=e}for(var t=0,a=arguments.length;t<a;t++)l(arguments[t],e);return r},deepMerge:function n(){var r={};function e(e,t){"object"==typeof r[t]&&"object"==typeof e?r[t]=n(r[t],e):r[t]="object"==typeof e?n({},e):e}for(var t=0,a=arguments.length;t<a;t++)l(arguments[t],e);return r},extend:function(n,e,r){return l(e,function(e,t){n[t]=r&&"function"==typeof e?a(e,r):e}),n},trim:function(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}}},{"./helpers/bind":18,"is-buffer":28}],28:[function(e,t,n){t.exports=function(e){return null!=e&&null!=e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}},{}],29:[function(e,t,n){t.exports={CssSelectorParser:e("./lib/css-selector-parser.js").CssSelectorParser}},{"./lib/css-selector-parser.js":30}],30:[function(e,t,n){function r(){this.pseudos={},this.attrEqualityMods={},this.ruleNestingOperators={},this.substitutesEnabled=!1}function o(e){return"a"<=e&&e<="f"||"A"<=e&&e<="F"||"0"<=e&&e<="9"}r.prototype.registerSelectorPseudos=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],this.pseudos[e]="selector";return this},r.prototype.unregisterSelectorPseudos=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],delete this.pseudos[e];return this},r.prototype.registerNumericPseudos=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],this.pseudos[e]="numeric";return this},r.prototype.unregisterNumericPseudos=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],delete this.pseudos[e];return this},r.prototype.registerNestingOperators=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],this.ruleNestingOperators[e]=!0;return this},r.prototype.unregisterNestingOperators=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],delete this.ruleNestingOperators[e];return this},r.prototype.registerAttrEqualityMods=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],this.attrEqualityMods[e]=!0;return this},r.prototype.unregisterAttrEqualityMods=function(e){for(var t=0,n=arguments.length;t<n;t++)e=arguments[t],delete this.attrEqualityMods[e];return this},r.prototype.enableSubstitutes=function(){return this.substitutesEnabled=!0,this},r.prototype.disableSubstitutes=function(){return this.substitutesEnabled=!1,this};var u={"!":!0,'"':!0,"#":!0,$:!0,"%":!0,"&":!0,"'":!0,"(":!0,")":!0,"*":!0,"+":!0,",":!0,".":!0,"/":!0,";":!0,"<":!0,"=":!0,">":!0,"?":!0,"@":!0,"[":!0,"\\":!0,"]":!0,"^":!0,"`":!0,"{":!0,"|":!0,"}":!0,"~":!0},i={"\n":"\\n","\r":"\\r","\t":"\\t","\f":"\\f","\v":"\\v"},y={n:"\n",r:"\r",t:"\t",f:"\f","\\":"\\","'":"'"},v={n:"\n",r:"\r",t:"\t",f:"\f","\\":"\\",'"':'"'};function a(s,l,c,d,a,m){var p,f,h,b,g;return b=s.length,p=null,h=function(e,t){var n,r,a;for(a="",l++,p=s.charAt(l);l<b;){if(p===e)return l++,a;if("\\"===p)if(l++,(p=s.charAt(l))===e)a+=e;else if(n=t[p])a+=n;else{if(o(p)){for(r=p,l++,p=s.charAt(l);o(p);)r+=p,l++,p=s.charAt(l);" "===p&&(l++,p=s.charAt(l)),a+=String.fromCharCode(parseInt(r,16));continue}a+=p}else a+=p;l++,p=s.charAt(l)}return a},f=function(){var e,t="";for(p=s.charAt(l);l<b;){if("a"<=(e=p)&&e<="z"||"A"<=e&&e<="Z"||"0"<=e&&e<="9"||"-"===e||"_"===e)t+=p;else{if("\\"!==p)return t;if(b<=++l)throw Error("Expected symbol but end of file reached.");if(p=s.charAt(l),u[p])t+=p;else{if(o(p)){var n=p;for(l++,p=s.charAt(l);o(p);)n+=p,l++,p=s.charAt(l);" "===p&&(l++,p=s.charAt(l)),t+=String.fromCharCode(parseInt(n,16));continue}t+=p}}l++,p=s.charAt(l)}return t},g=function(){p=s.charAt(l);for(var e=!1;" "===p||"\t"===p||"\n"===p||"\r"===p||"\f"===p;)e=!0,l++,p=s.charAt(l);return e},this.parse=function(){var e=this.parseSelector();if(l<b)throw Error('Rule expected but "'+s.charAt(l)+'" found.');return e},this.parseSelector=function(){var e,t=e=this.parseSingleSelector();for(p=s.charAt(l);","===p;){if(l++,g(),"selectors"!==e.type&&(e={type:"selectors",selectors:[t]}),!(t=this.parseSingleSelector()))throw Error('Rule expected after ",".');e.selectors.push(t)}return e},this.parseSingleSelector=function(){g();var e={type:"ruleSet"},t=this.parseRule();if(!t)return null;for(var n=e;t&&(t.type="rule",n.rule=t,n=t,g(),p=s.charAt(l),!(b<=l||","===p||")"===p));)if(a[p]){var r=p;if(l++,g(),!(t=this.parseRule()))throw Error('Rule expected after "'+r+'".');t.nestingOperator=r}else(t=this.parseRule())&&(t.nestingOperator=null);return e},this.parseRule=function(){for(var e,t=null;l<b;)if("*"===(p=s.charAt(l)))l++,(t=t||{}).tagName="*";else if("a"<=(e=p)&&e<="z"||"A"<=e&&e<="Z"||"-"===e||"_"===e||"\\"===p)(t=t||{}).tagName=f();else if("."===p)l++,((t=t||{}).classNames=t.classNames||[]).push(f());else if("#"===p)l++,(t=t||{}).id=f();else if("["===p){l++,g();var n={name:f()};if(g(),"]"===p)l++;else{var r="";if(d[p]&&(r=p,l++,p=s.charAt(l)),b<=l)throw Error('Expected "=" but end of file reached.');if("="!==p)throw Error('Expected "=" but "'+p+'" found.');n.operator=r+"=",l++,g();var a="";if(n.valueType="string",'"'===p)a=h('"',v);else if("'"===p)a=h("'",y);else if(m&&"$"===p)l++,a=f(),n.valueType="substitute";else{for(;l<b&&"]"!==p;)a+=p,l++,p=s.charAt(l);a=a.trim()}if(g(),b<=l)throw Error('Expected "]" but end of file reached.');if("]"!==p)throw Error('Expected "]" but "'+p+'" found.');l++,n.value=a}((t=t||{}).attrs=t.attrs||[]).push(n)}else{if(":"!==p)break;l++;var o=f(),i={name:o};if("("===p){l++;var u="";if(g(),"selector"===c[o])i.valueType="selector",u=this.parseSelector();else{if(i.valueType=c[o]||"string",'"'===p)u=h('"',v);else if("'"===p)u=h("'",y);else if(m&&"$"===p)l++,u=f(),i.valueType="substitute";else{for(;l<b&&")"!==p;)u+=p,l++,p=s.charAt(l);u=u.trim()}g()}if(b<=l)throw Error('Expected ")" but end of file reached.');if(")"!==p)throw Error('Expected ")" but "'+p+'" found.');l++,i.value=u}((t=t||{}).pseudos=t.pseudos||[]).push(i)}return t},this}r.prototype.parse=function(e){return new a(e,0,this.pseudos,this.attrEqualityMods,this.ruleNestingOperators,this.substitutesEnabled).parse()},r.prototype.escapeIdentifier=function(e){for(var t="",n=0,r=e.length;n<r;){var a=e.charAt(n);if(u[a])t+="\\"+a;else if("_"===a||"-"===a||"A"<=a&&a<="Z"||"a"<=a&&a<="z"||0!==n&&"0"<=a&&a<="9")t+=a;else{var o=a.charCodeAt(0);if(55296==(63488&o)){var i=e.charCodeAt(n++);if(55296!=(64512&o)||56320!=(64512&i))throw Error("UCS-2(decode): illegal sequence");o=((1023&o)<<10)+(1023&i)+65536}t+="\\"+o.toString(16)+" "}n++}return t},r.prototype.escapeStr=function(e){for(var t,n,r="",a=0,o=e.length;a<o;)'"'===(t=e.charAt(a))?t='\\"':"\\"===t?t="\\\\":(n=i[t])&&(t=n),r+=t,a++;return'"'+r+'"'},r.prototype.render=function(e){return this._renderEntity(e).trim()},r.prototype._renderEntity=function(e){var t,n,r;switch(r="",e.type){case"ruleSet":for(t=e.rule,n=[];t;)t.nestingOperator&&n.push(t.nestingOperator),n.push(this._renderEntity(t)),t=t.rule;r=n.join(" ");break;case"selectors":r=e.selectors.map(this._renderEntity,this).join(", ");break;case"rule":e.tagName&&(r="*"===e.tagName?"*":this.escapeIdentifier(e.tagName)),e.id&&(r+="#"+this.escapeIdentifier(e.id)),e.classNames&&(r+=e.classNames.map(function(e){return"."+this.escapeIdentifier(e)},this).join("")),e.attrs&&(r+=e.attrs.map(function(e){return e.operator?"substitute"===e.valueType?"["+this.escapeIdentifier(e.name)+e.operator+"$"+e.value+"]":"["+this.escapeIdentifier(e.name)+e.operator+this.escapeStr(e.value)+"]":"["+this.escapeIdentifier(e.name)+"]"},this).join("")),e.pseudos&&(r+=e.pseudos.map(function(e){return e.valueType?"selector"===e.valueType?":"+this.escapeIdentifier(e.name)+"("+this._renderEntity(e.value)+")":"substitute"===e.valueType?":"+this.escapeIdentifier(e.name)+"($"+e.value+")":"numeric"===e.valueType?":"+this.escapeIdentifier(e.name)+"("+e.value+")":":"+this.escapeIdentifier(e.name)+"("+this.escapeIdentifier(e.value)+")":":"+this.escapeIdentifier(e.name)},this).join(""));break;default:throw Error('Unknown entity type: "'+e.type(NaN))}return r},n.CssSelectorParser=r},{}],31:[function(e,t,n){"use strict";t.exports=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g}},{}],32:[function(V,n,r){(function(P,U){var e,t;e=this,t=function(){"use strict";function s(e){return"function"==typeof e}var n=Array.isArray?Array.isArray:function(e){return"[object Array]"===Object.prototype.toString.call(e)},r=0,t=void 0,a=void 0,i=function(e,t){m[r]=e,m[r+1]=t,2===(r+=2)&&(a?a(p):y())};var e=void 0!==window?window:void 0,o=e||{},u=o.MutationObserver||o.WebKitMutationObserver,l="undefined"==typeof self&&void 0!==P&&"[object process]"==={}.toString.call(P),c="undefined"!=typeof Uint8ClampedArray&&"undefined"!=typeof importScripts&&"undefined"!=typeof MessageChannel;function d(){var e=setTimeout;return function(){return e(p,1)}}var m=new Array(1e3);function p(){for(var e=0;e<r;e+=2){(0,m[e])(m[e+1]),m[e]=void 0,m[e+1]=void 0}r=0}var f,h,b,g,y=void 0;function v(e,t){var n=this,r=new this.constructor(k);void 0===r[w]&&O(r);var a=n._state;if(a){var o=arguments[a-1];i(function(){return S(a,r,o,n._result)})}else N(n,r,e,t);return r}function D(e){if(e&&"object"==typeof e&&e.constructor===this)return e;var t=new this(k);return F(t,e),t}y=l?function(){return P.nextTick(p)}:u?(h=0,b=new u(p),g=document.createTextNode(""),b.observe(g,{characterData:!0}),function(){g.data=h=++h%2}):c?((f=new MessageChannel).port1.onmessage=p,function(){return f.port2.postMessage(0)}):void 0===e&&"function"==typeof V?function(){try{var e=Function("return this")().require("vertx");return void 0!==(t=e.runOnLoop||e.runOnContext)?function(){t(p)}:d()}catch(e){return d()}}():d();var w=Math.random().toString(36).substring(2);function k(){}var x=void 0,E=1,C=2;function A(e,t,n){t.constructor===e.constructor&&n===v&&t.constructor.resolve===D?function(t,e){e._state===E?z(t,e._result):e._state===C?q(t,e._result):N(e,void 0,function(e){return F(t,e)},function(e){return q(t,e)})}(e,t):void 0===n?z(e,t):s(n)?function(e,r,a){i(function(t){var n=!1,e=function(e,t,n,r){try{e.call(t,n,r)}catch(e){return e}}(a,r,function(e){n||(n=!0,r!==e?F(t,e):z(t,e))},function(e){n||(n=!0,q(t,e))},t._label);!n&&e&&(n=!0,q(t,e))},e)}(e,t,n):z(e,t)}function F(t,e){if(t===e)q(t,new TypeError("You cannot resolve a promise with itself"));else if(function(e){var t=typeof e;return null!==e&&("object"==t||"function"==t)}(e)){var n=void 0;try{n=e.then}catch(e){return void q(t,e)}A(t,e,n)}else z(t,e)}function j(e){e._onerror&&e._onerror(e._result),T(e)}function z(e,t){e._state===x&&(e._result=t,e._state=E,0!==e._subscribers.length&&i(T,e))}function q(e,t){e._state===x&&(e._state=C,e._result=t,i(j,e))}function N(e,t,n,r){var a=e._subscribers,o=a.length;e._onerror=null,a[o]=t,a[o+E]=n,a[o+C]=r,0===o&&e._state&&i(T,e)}function T(e){var t=e._subscribers,n=e._state;if(0!==t.length){for(var r=void 0,a=void 0,o=e._result,i=0;i<t.length;i+=3)r=t[i],a=t[i+n],r?S(n,r,a,o):a(o);e._subscribers.length=0}}function S(e,t,n,r){var a=s(n),o=void 0,i=void 0,u=!0;if(a){try{o=n(r)}catch(e){u=!1,i=e}if(t===o)return void q(t,new TypeError("A promises callback cannot return that same promise."))}else o=r;t._state!==x||(a&&u?F(t,o):!1===u?q(t,i):e===E?z(t,o):e===C&&q(t,o))}var R=0;function O(e){e[w]=R++,e._state=void 0,e._result=void 0,e._subscribers=[]}var _=(B.prototype._enumerate=function(e){for(var t=0;this._state===x&&t<e.length;t++)this._eachEntry(e[t],t)},B.prototype._eachEntry=function(t,e){var n=this._instanceConstructor,r=n.resolve;if(r===D){var a=void 0,o=void 0,i=!1;try{a=t.then}catch(e){i=!0,o=e}if(a===v&&t._state!==x)this._settledAt(t._state,e,t._result);else if("function"!=typeof a)this._remaining--,this._result[e]=t;else if(n===L){var u=new n(k);i?q(u,o):A(u,t,a),this._willSettleAt(u,e)}else this._willSettleAt(new n(function(e){return e(t)}),e)}else this._willSettleAt(r(t),e)},B.prototype._settledAt=function(e,t,n){var r=this.promise;r._state===x&&(this._remaining--,e===C?q(r,n):this._result[t]=n),0===this._remaining&&z(r,this._result)},B.prototype._willSettleAt=function(e,t){var n=this;N(e,void 0,function(e){return n._settledAt(E,t,e)},function(e){return n._settledAt(C,t,e)})},B);function B(e,t){this._instanceConstructor=e,this.promise=new e(k),this.promise[w]||O(this.promise),n(t)?(this.length=t.length,this._remaining=t.length,this._result=new Array(this.length),0===this.length?z(this.promise,this._result):(this.length=this.length||0,this._enumerate(t),0===this._remaining&&z(this.promise,this._result))):q(this.promise,new Error("Array Methods must be provided an Array"))}var L=(I.prototype.catch=function(e){return this.then(null,e)},I.prototype.finally=function(t){var n=this.constructor;return s(t)?this.then(function(e){return n.resolve(t()).then(function(){return e})},function(e){return n.resolve(t()).then(function(){throw e})}):this.then(t,t)},I);function I(e){this[w]=R++,this._result=this._state=void 0,this._subscribers=[],k!==e&&("function"!=typeof e&&function(){throw new TypeError("You must pass a resolver function as the first argument to the promise constructor")}(),this instanceof I?function(t,e){try{e(function(e){F(t,e)},function(e){q(t,e)})}catch(e){q(t,e)}}(this,e):function(){throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.")}())}return L.prototype.then=v,L.all=function(e){return new _(this,e).promise},L.race=function(a){var o=this;return n(a)?new o(function(e,t){for(var n=a.length,r=0;r<n;r++)o.resolve(a[r]).then(e,t)}):new o(function(e,t){return t(new TypeError("You must pass an array to race."))})},L.resolve=D,L.reject=function(e){var t=new this(k);return q(t,e),t},L._setScheduler=function(e){a=e},L._setAsap=function(e){i=e},L._asap=i,L.polyfill=function(){var e=void 0;if(void 0!==U)e=U;else if("undefined"!=typeof self)e=self;else try{e=Function("return this")()}catch(e){throw new Error("polyfill failed because global object is unavailable in this environment")}var t=e.Promise;if(t){var n=null;try{n=Object.prototype.toString.call(t.resolve())}catch(e){}if("[object Promise]"===n&&!t.cast)return}e.Promise=L},L.Promise=L},"object"==typeof r&&void 0!==n?n.exports=t():"function"==typeof define&&define.amd?define(t):e.ES6Promise=t()}).call(this,V("_process"),void 0!==a?a:"undefined"!=typeof self?self:void 0!==window?window:{})},{_process:33}],33:[function(e,t,n){var r,a,o=t.exports={};function i(){throw new Error("setTimeout has not been defined")}function u(){throw new Error("clearTimeout has not been defined")}function s(t){if(r===setTimeout)return setTimeout(t,0);if((r===i||!r)&&setTimeout)return r=setTimeout,setTimeout(t,0);try{return r(t,0)}catch(e){try{return r.call(null,t,0)}catch(e){return r.call(this,t,0)}}}!function(){try{r="function"==typeof setTimeout?setTimeout:i}catch(e){r=i}try{a="function"==typeof clearTimeout?clearTimeout:u}catch(e){a=u}}();var l,c=[],d=!1,m=-1;function p(){d&&l&&(d=!1,l.length?c=l.concat(c):m=-1,c.length&&f())}function f(){if(!d){var e=s(p);d=!0;for(var t=c.length;t;){for(l=c,c=[];++m<t;)l&&l[m].run();m=-1,t=c.length}l=null,d=!1,function(t){if(a===clearTimeout)return clearTimeout(t);if((a===u||!a)&&clearTimeout)return a=clearTimeout,clearTimeout(t);try{a(t)}catch(e){try{return a.call(null,t)}catch(e){return a.call(this,t)}}}(e)}}function h(e,t){this.fun=e,this.array=t}function b(){}o.nextTick=function(e){var t=new Array(arguments.length-1);if(1<arguments.length)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];c.push(new h(e,t)),1!==c.length||d||s(f)},h.prototype.run=function(){this.fun.apply(null,this.array)},o.title="browser",o.browser=!0,o.env={},o.argv=[],o.version="",o.versions={},o.on=b,o.addListener=b,o.once=b,o.off=b,o.removeListener=b,o.removeAllListeners=b,o.emit=b,o.prependListener=b,o.prependOnceListener=b,o.listeners=function(e){return[]},o.binding=function(e){throw new Error("process.binding is not supported")},o.cwd=function(){return"/"},o.chdir=function(e){throw new Error("process.chdir is not supported")},o.umask=function(){return 0}},{}],34:[function(e,t,n){(function(e){!function(e){"use strict";if(!e.WeakMap){var n=Object.prototype.hasOwnProperty,r=function(e,t,n){Object.defineProperty?Object.defineProperty(e,t,{configurable:!0,writable:!0,value:n}):e[t]=n};e.WeakMap=(r(t.prototype,"delete",function(e){if(a(this,"delete"),!i(e))return!1;var t=e[this._id];return!(!t||t[0]!==e||(delete e[this._id],0))}),r(t.prototype,"get",function(e){if(a(this,"get"),i(e)){var t=e[this._id];return t&&t[0]===e?t[1]:void 0}}),r(t.prototype,"has",function(e){if(a(this,"has"),!i(e))return!1;var t=e[this._id];return!(!t||t[0]!==e)}),r(t.prototype,"set",function(e,t){if(a(this,"set"),!i(e))throw new TypeError("Invalid value used as weak map key");var n=e[this._id];return n&&n[0]===e?n[1]=t:r(e,this._id,[e,t]),this}),r(t,"_polyfill",!0),t)}function t(){if(void 0===this)throw new TypeError("Constructor WeakMap requires 'new'");if(r(this,"_id",function(e){return e+"_"+o()+"."+o()}("_WeakMap")),0<arguments.length)throw new TypeError("WeakMap iterable is not supported")}function a(e,t){if(!i(e)||!n.call(e,"_id"))throw new TypeError(t+" method called on incompatible receiver "+typeof e)}function o(){return Math.random().toString().substring(2)}function i(e){return Object(e)===e}}("undefined"!=typeof self?self:void 0!==window?window:void 0!==e?e:this)}).call(this,void 0!==a?a:"undefined"!=typeof self?self:void 0!==window?window:{})},{}]},{},[1]);var utils=axe.utils={},u={};function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function t(e,t,n){"use strict";var r,a;for(r=0,a=e.length;r<a;r++)t[n](e[r])}function n(e){this.brand="axe",this.application="axeAPI",this.tagExclude=["experimental"],this.defaultConfig=e,this._init(),this._defaultLocale=null}n.prototype._setDefaultLocale=function(){if(!this._defaultLocale){for(var e={checks:{},rules:{}},t=Object.keys(this.data.checks),n=0;n<t.length;n++){var r=t[n],a=this.data.checks[r].messages,o=a.pass,i=a.fail,u=a.incomplete;e.checks[r]={pass:o,fail:i,incomplete:u}}for(var s=Object.keys(this.data.rules),l=0;l<s.length;l++){var c=s[l],d=this.data.rules[c],m=d.description,p=d.help;e.rules[c]={description:m,help:p}}this._defaultLocale=e}},n.prototype._resetLocale=function(){var e=this._defaultLocale;e&&this.applyLocale(e)};function c(a,e,o){return o.performanceTimer&&axe.utils.performanceTimer.mark("mark_rule_start_"+a.id),function(n,r){a.run(e,o,function(e){n(e)},function(e){if(o.debug)r(e);else{var t=Object.assign(new f(a),{result:axe.constants.CANTTELL,description:"An error occured while running this rule",message:e.message,stack:e.stack,error:e,errorNode:e.errorNode});n(t)}})}}function o(e,t,n){var r=e.brand,a=e.application;return axe.constants.helpUrlBase+r+"/"+(n||axe.version.substring(0,axe.version.lastIndexOf(".")))+"/"+t+"?application="+a}function d(e){"use strict";this.id=e.id,this.data=null,this.relatedNodes=[],this.result=null}function r(e){"use strict";return"string"==typeof e?new Function("return "+e+";")():e}function i(e){e&&(this.id=e.id,this.configure(e))}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function s(e,t,n){"use strict";var r,a;e.frames=e.frames||[];var o=document.querySelectorAll(n.shift());e:for(var i=0,u=o.length;i<u;i++){a=o[i];for(var s=0,l=e.frames.length;s<l;s++)if(e.frames[s].node===a){e.frames[s][t].push(n);break e}r={node:a,include:[],exclude:[]},n&&r[t].push(n),e.frames.push(r)}}function m(e,t){"use strict";for(var n,r,a=[],o=0,i=e[t].length;o<i;o++){if("string"==typeof(n=e[t][o])){r=Array.from(document.querySelectorAll(n)),a=a.concat(r.map(function(e){return axe.utils.getNodeFromTree(e)}));break}!n||!n.length||n instanceof Node?n instanceof Node&&(n.documentElement instanceof Node?a.push(e.flatTree[0]):a.push(axe.utils.getNodeFromTree(n))):1<n.length?s(e,t,n):(r=Array.from(document.querySelectorAll(n[0])),a=a.concat(r.map(function(e){return axe.utils.getNodeFromTree(e)})))}return a.filter(function(e){return e})}function p(e){"use strict";var t=this;this.frames=[],this.initiator=!e||"boolean"!=typeof e.initiator||e.initiator,this.page=!1,e=function(e){"use strict";if(e&&"object"===S(e)||e instanceof NodeList){if(e instanceof Node)return{include:[e],exclude:[]};if(e.hasOwnProperty("include")||e.hasOwnProperty("exclude"))return{include:e.include&&+e.include.length?e.include:[document],exclude:e.exclude||[]};if(e.length===+e.length)return{include:e,exclude:[]}}return"string"==typeof e?{include:[e],exclude:[]}:{include:[document],exclude:[]}}(e),this.flatTree=axe.utils.getFlattenedTree(function(e){var t=e.include,n=e.exclude;return(Array.from(t).concat(Array.from(n)).reduce(function(e,t){return e||(t instanceof Element?t.ownerDocument:t instanceof Document?t:void 0)},null)||document).documentElement}(e)),this.exclude=e.exclude,this.include=e.include,this.include=m(this,"include"),this.exclude=m(this,"exclude"),axe.utils.select("frame, iframe",this).forEach(function(e){Be(e,t)&&function(e,t){"use strict";axe.utils.isHidden(t)||axe.utils.findBy(e,"node",t)||e.push({node:t,include:[],exclude:[]})}(t.frames,e.actualNode)}),1===this.include.length&&this.include[0].actualNode===document.documentElement&&(this.page=!0);var n=function(e){"use strict";if(0===e.include.length){if(0===e.frames.length){var t=axe.utils.respondable.isInFrame()?"frame":"page";return new Error("No elements found for include in "+t+" Context")}e.frames.forEach(function(e,t){if(0===e.include.length)return new Error("No elements found for include in Context of frame "+t)})}}(this);if(n instanceof Error)throw n;Array.isArray(this.include)||(this.include=Array.from(this.include)),this.include.sort(axe.utils.nodeSorter)}function f(e){"use strict";this.id=e.id,this.result=axe.constants.NA,this.pageLevel=e.pageLevel,this.impact=null,this.nodes=[]}function h(e,t){"use strict";this._audit=t,this.id=e.id,this.selector=e.selector||"*",this.excludeHidden="boolean"!=typeof e.excludeHidden||e.excludeHidden,this.enabled="boolean"!=typeof e.enabled||e.enabled,this.pageLevel="boolean"==typeof e.pageLevel&&e.pageLevel,this.any=e.any||[],this.all=e.all||[],this.none=e.none||[],this.tags=e.tags||[],this.preload=!!e.preload,e.matches&&(this.matches=r(e.matches))}function b(e){if(e.length){var n=!1,r={};return e.forEach(function(e){var t=e.results.filter(function(e){return e});(r[e.type]=t).length&&(n=!0)}),n?r:null}}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function g(e){return(g=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function y(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function v(e,t){return(v=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function D(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function w(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function k(e,t,n){return t&&w(e.prototype,t),n&&w(e,n),e}n.prototype._applyCheckLocale=function(e){for(var t,n,r,a,o=Object.keys(e),i=0;i<o.length;i++){var u=o[i];if(!this.data.checks[u])throw new Error('Locale provided for unknown check: "'.concat(u,'"'));this.data.checks[u]=(t=this.data.checks[u],n=e[u],a=r=void 0,r=n.pass,a=n.fail,"string"==typeof r&&(r=axe.imports.doT.compile(r)),"string"==typeof a&&(a=axe.imports.doT.compile(a)),R({},t,{messages:{pass:r||t.messages.pass,fail:a||t.messages.fail,incomplete:"object"===S(t.messages.incomplete)?R({},t.messages.incomplete,{},n.incomplete):n.incomplete}}))}},n.prototype._applyRuleLocale=function(e){for(var t,n,r,a,o=Object.keys(e),i=0;i<o.length;i++){var u=o[i];if(!this.data.rules[u])throw new Error('Locale provided for unknown rule: "'.concat(u,'"'));this.data.rules[u]=(t=this.data.rules[u],n=e[u],a=r=void 0,r=n.help,a=n.description,"string"==typeof r&&(r=axe.imports.doT.compile(r)),"string"==typeof a&&(a=axe.imports.doT.compile(a)),R({},t,{help:r||t.help,description:a||t.description}))}},n.prototype.applyLocale=function(e){this._setDefaultLocale(),e.checks&&this._applyCheckLocale(e.checks),e.rules&&this._applyRuleLocale(e.rules)},n.prototype._init=function(){var e=function(e){"use strict";var t;return e?(t=axe.utils.clone(e)).commons=e.commons:t={},t.reporter=t.reporter||null,t.rules=t.rules||[],t.checks=t.checks||[],t.data=R({checks:{},rules:{}},t.data),t}(this.defaultConfig);axe.commons=e.commons,this.reporter=e.reporter,this.commands={},this.rules=[],this.checks={},t(e.rules,this,"addRule"),t(e.checks,this,"addCheck"),this.data={},this.data.checks=e.data&&e.data.checks||{},this.data.rules=e.data&&e.data.rules||{},this.data.failureSummaries=e.data&&e.data.failureSummaries||{},this.data.incompleteFallbackMessage=e.data&&e.data.incompleteFallbackMessage||"",this._constructHelpUrls()},n.prototype.registerCommand=function(e){"use strict";this.commands[e.id]=e.callback},n.prototype.addRule=function(e){"use strict";e.metadata&&(this.data.rules[e.id]=e.metadata);var t=this.getRule(e.id);t?t.configure(e):this.rules.push(new h(e,this))},n.prototype.addCheck=function(e){"use strict";var t=e.metadata;"object"===S(t)&&(this.data.checks[e.id]=t,"object"===S(t.messages)&&Object.keys(t.messages).filter(function(e){return t.messages.hasOwnProperty(e)&&"string"==typeof t.messages[e]}).forEach(function(e){0===t.messages[e].indexOf("function")&&(t.messages[e]=new Function("return "+t.messages[e]+";")())})),this.checks[e.id]?this.checks[e.id].configure(e):this.checks[e.id]=new i(e)},n.prototype.run=function(o,i,u,s){"use strict";this.normalizeOptions(i),axe._selectCache=[];var e=function(e,n,r){return e.reduce(function(e,t){return axe.utils.ruleShouldRun(t,n,r)&&(t.preload?e.later.push(t):e.now.push(t)),e},{now:[],later:[]})}(this.rules,o,i),t=e.now,l=e.later,n=axe.utils.queue();t.forEach(function(e){n.defer(c(e,o,i))});var r=axe.utils.queue();l.length&&r.defer(function(t){axe.utils.preload(i).then(function(e){return t(e)}).catch(function(e){console.warn("Couldn't load preload assets: ",e),t(void 0)})});var a=axe.utils.queue();a.defer(n),a.defer(r),a.then(function(e){var t=e.pop();if(t&&t.length){var n=t[0];n&&(o=R({},o,{},n))}var r=e[0];if(!l.length)return axe._selectCache=void 0,void u(r.filter(function(e){return!!e}));var a=axe.utils.queue();l.forEach(function(e){var t=c(e,o,i);a.defer(t)}),a.then(function(e){axe._selectCache=void 0,u(r.concat(e).filter(function(e){return!!e}))}).catch(s)}).catch(s)},n.prototype.after=function(e,n){"use strict";var r=this.rules;return e.map(function(e){var t=axe.utils.findBy(r,"id",e.id);if(!t)throw new Error("Result for unknown rule. You may be running mismatch axe-core versions");return t.after(e,n)})},n.prototype.getRule=function(t){return this.rules.find(function(e){return e.id===t})},n.prototype.normalizeOptions=function(e){"use strict";var t=this;if("object"===S(e.runOnly)){Array.isArray(e.runOnly)&&(e.runOnly={type:"tag",values:e.runOnly});var n=e.runOnly;if(n.value&&!n.values&&(n.values=n.value,delete n.value),!Array.isArray(n.values)||0===n.values.length)throw new Error("runOnly.values must be a non-empty array");if(["rule","rules"].includes(n.type))n.type="rule",n.values.forEach(function(e){if(!t.getRule(e))throw new Error("unknown rule `"+e+"` in options.runOnly")});else{if(!["tag","tags",void 0].includes(n.type))throw new Error("Unknown runOnly type '".concat(n.type,"'"));n.type="tag";var r=t.rules.reduce(function(e,t){return e.length?e.filter(function(e){return!t.tags.includes(e)}):e},n.values);0!==r.length&&axe.log("Could not find tags `"+r.join("`, `")+"`")}}return"object"===S(e.rules)&&Object.keys(e.rules).forEach(function(e){if(!t.getRule(e))throw new Error("unknown rule `"+e+"` in options.rules")}),e},n.prototype.setBranding=function(e){"use strict";var t={brand:this.brand,application:this.application};e&&e.hasOwnProperty("brand")&&e.brand&&"string"==typeof e.brand&&(this.brand=e.brand),e&&e.hasOwnProperty("application")&&e.application&&"string"==typeof e.application&&(this.application=e.application),this._constructHelpUrls(t)},n.prototype._constructHelpUrls=function(){var n=this,r=0<arguments.length&&void 0!==arguments[0]?arguments[0]:null,a=(axe.version.match(/^[1-9][0-9]*\.[0-9]+/)||["x.y"])[0];this.rules.forEach(function(e){n.data.rules[e.id]||(n.data.rules[e.id]={});var t=n.data.rules[e.id];("string"!=typeof t.helpUrl||r&&t.helpUrl===o(r,e.id,a))&&(t.helpUrl=o(n,e.id,a))})},n.prototype.resetRulesAndChecks=function(){"use strict";this._init(),this._resetLocale()},function(){"use strict";var n={},e={set:function(e,t){n[e]=t},get:function(e){return n[e]},clear:function(){n={}}};axe._cache=e}(),i.prototype.enabled=!0,i.prototype.run=function(t,e,n,r,a){"use strict";var o=(e=e||{}).hasOwnProperty("enabled")?e.enabled:this.enabled,i=e.options||this.options;if(o){var u,s=new d(this),l=axe.utils.checkHelper(s,e,r,a);try{u=this.evaluate.call(l,t.actualNode,i,t,n)}catch(e){return t&&t.actualNode&&(e.errorNode=new X(t.actualNode).toJSON()),void a(e)}l.isAsync||(s.result=u,r(s))}else r(null)},i.prototype.runSync=function(t,e,n){var r=(e=e||{}).enabled;if(!(void 0===r?this.enabled:r))return null;var a,o=e.options||this.options,i=new d(this),u=axe.utils.checkHelper(i,e);u.async=function(){throw new Error("Cannot run async check while in a synchronous run")};try{a=this.evaluate.call(u,t.actualNode,o,t,n)}catch(e){throw t&&t.actualNode&&(e.errorNode=new X(t.actualNode).toJSON()),e}return i.result=a,i},i.prototype.configure=function(t){var n=this;["options","enabled"].filter(function(e){return t.hasOwnProperty(e)}).forEach(function(e){return n[e]=t[e]}),["evaluate","after"].filter(function(e){return t.hasOwnProperty(e)}).forEach(function(e){return n[e]=r(t[e])})},h.prototype.matches=function(){"use strict";return!0},h.prototype.gather=function(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},n="mark_gather_start_"+this.id,r="mark_gather_end_"+this.id,a="mark_isHidden_start_"+this.id,o="mark_isHidden_end_"+this.id;t.performanceTimer&&axe.utils.performanceTimer.mark(n);var i=axe.utils.select(this.selector,e);return this.excludeHidden&&(t.performanceTimer&&axe.utils.performanceTimer.mark(a),i=i.filter(function(e){return!axe.utils.isHidden(e.actualNode)}),t.performanceTimer&&(axe.utils.performanceTimer.mark(o),axe.utils.performanceTimer.measure("rule_"+this.id+"#gather_axe.utils.isHidden",a,o))),t.performanceTimer&&(axe.utils.performanceTimer.mark(r),axe.utils.performanceTimer.measure("rule_"+this.id+"#gather",n,r)),i},h.prototype.runChecks=function(t,a,o,i,n,e){"use strict";var u=this,s=axe.utils.queue();this[t].forEach(function(e){var n=u._audit.checks[e.id||e],r=axe.utils.getCheckOption(n,u.id,o);s.defer(function(e,t){n.run(a,r,i,e,t)})}),s.then(function(e){e=e.filter(function(e){return e}),n({type:t,results:e})}).catch(e)},h.prototype.runChecksSync=function(e,r,a,o){"use strict";var i=this,u=[];return this[e].forEach(function(e){var t=i._audit.checks[e.id||e],n=axe.utils.getCheckOption(t,i.id,a);u.push(t.runSync(r,n,o))}),{type:e,results:u=u.filter(function(e){return e})}},h.prototype.run=function(a){var o=this,i=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},e=2<arguments.length?arguments[2]:void 0,t=3<arguments.length?arguments[3]:void 0;i.performanceTimer&&this._trackPerformance();var n,u=axe.utils.queue(),s=new f(this);try{n=this.gatherAndMatchNodes(a,i)}catch(e){return void t(new l({cause:e,ruleId:this.id}))}i.performanceTimer&&this._logGatherPerformance(n),n.forEach(function(r){u.defer(function(n,t){var e=axe.utils.queue();["any","all","none"].forEach(function(n){e.defer(function(e,t){o.runChecks(n,r,i,a,e,t)})}),e.then(function(e){var t=b(e);t&&(t.node=new axe.utils.DqElement(r.actualNode,i),s.nodes.push(t)),n()}).catch(function(e){return t(e)})})}),u.defer(function(e){return setTimeout(e,0)}),i.performanceTimer&&this._logRulePerformance(),u.then(function(){return e(s)}).catch(function(e){return t(e)})},h.prototype.runSync=function(r){var a=this,o=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{};o.performanceTimer&&this._trackPerformance();var e,i=new f(this);try{e=this.gatherAndMatchNodes(r,o)}catch(e){throw new l({cause:e,ruleId:this.id})}return o.performanceTimer&&this._logGatherPerformance(e),e.forEach(function(t){var n=[];["any","all","none"].forEach(function(e){n.push(a.runChecksSync(e,t,o,r))});var e=b(n);e&&(e.node=t.actualNode?new axe.utils.DqElement(t.actualNode,o):null,i.nodes.push(e))}),o.performanceTimer&&this._logRulePerformance(),i},h.prototype._trackPerformance=function(){this._markStart="mark_rule_start_"+this.id,this._markEnd="mark_rule_end_"+this.id,this._markChecksStart="mark_runchecks_start_"+this.id,this._markChecksEnd="mark_runchecks_end_"+this.id},h.prototype._logGatherPerformance=function(e){axe.log("gather (",e.length,"):",axe.utils.performanceTimer.timeElapsed()+"ms"),axe.utils.performanceTimer.mark(this._markChecksStart)},h.prototype._logRulePerformance=function(){axe.utils.performanceTimer.mark(this._markChecksEnd),axe.utils.performanceTimer.mark(this._markEnd),axe.utils.performanceTimer.measure("runchecks_"+this.id,this._markChecksStart,this._markChecksEnd),axe.utils.performanceTimer.measure("rule_"+this.id,this._markStart,this._markEnd)},h.prototype.gatherAndMatchNodes=function(t,e){var n=this,r="mark_matches_start_"+this.id,a="mark_matches_end_"+this.id,o=this.gather(t,e);return e.performanceTimer&&axe.utils.performanceTimer.mark(r),o=o.filter(function(e){return n.matches(e.actualNode,e,t)}),e.performanceTimer&&(axe.utils.performanceTimer.mark(a),axe.utils.performanceTimer.measure("rule_"+this.id+"#matches",r,a)),o},h.prototype.after=function(a,o){"use strict";var e=function(n){"use strict";return axe.utils.getAllChecks(n).map(function(e){var t=n._audit.checks[e.id||e];return t&&"function"==typeof t.after?t:null}).filter(Boolean)}(this),i=this.id;return e.forEach(function(e){var t=function(e,t){"use strict";var n=[];return e.forEach(function(e){axe.utils.getAllChecks(e).forEach(function(e){e.id===t&&n.push(e)})}),n}(a.nodes,e.id),n=axe.utils.getCheckOption(e,i,o),r=e.after(t,n);t.forEach(function(e){-1===r.indexOf(e)&&(e.filtered=!0)})}),a.nodes=function(e){"use strict";var r=["any","all","none"],t=e.nodes.filter(function(t){var n=0;return r.forEach(function(e){t[e]=function(e){"use strict";return e.filter(function(e){return!0!==e.filtered})}(t[e]),n+=t[e].length}),0<n});return e.pageLevel&&t.length&&(t=[t.reduce(function(t,n){if(t)return r.forEach(function(e){t[e].push.apply(t[e],n[e])}),t})]),t}(a),a},h.prototype.configure=function(e){"use strict";e.hasOwnProperty("selector")&&(this.selector=e.selector),e.hasOwnProperty("excludeHidden")&&(this.excludeHidden="boolean"!=typeof e.excludeHidden||e.excludeHidden),e.hasOwnProperty("enabled")&&(this.enabled="boolean"!=typeof e.enabled||e.enabled),e.hasOwnProperty("pageLevel")&&(this.pageLevel="boolean"==typeof e.pageLevel&&e.pageLevel),e.hasOwnProperty("any")&&(this.any=e.any),e.hasOwnProperty("all")&&(this.all=e.all),e.hasOwnProperty("none")&&(this.none=e.none),e.hasOwnProperty("tags")&&(this.tags=e.tags),e.hasOwnProperty("matches")&&("string"==typeof e.matches?this.matches=new Function("return "+e.matches+";")():this.matches=e.matches)};var x=/[\t\r\n\f]/g,E=(k(C,[{key:"hasClass",value:function(){throw new Error('VirtualNode class must have a "hasClass" function')}},{key:"attr",value:function(){throw new Error('VirtualNode class must have a "attr" function')}},{key:"hasAttr",value:function(){throw new Error('VirtualNode class must have a "hasAttr" function')}},{key:"props",get:function(){throw new Error('VirtualNode class must have a "props" object consisting of "nodeType" and "nodeName" properties')}}]),C);function C(){D(this,C),this.children=[],this.parent=null}var A=(function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&v(e,t)}(F,E),k(F,[{key:"hasClass",value:function(e){var t=this.attr("class");if(!t)return!1;var n=" "+e+" ";return 0<=(" "+t+" ").replace(x," ").indexOf(n)}},{key:"attr",value:function(e){return"function"!=typeof this.actualNode.getAttribute?null:this.actualNode.getAttribute(e)}},{key:"hasAttr",value:function(e){return"function"==typeof this.actualNode.hasAttribute&&this.actualNode.hasAttribute(e)}},{key:"props",get:function(){var e=this.actualNode,t=e.nodeType,n=e.nodeName,r=e.id,a=e.type;return{nodeType:t,nodeName:n.toLowerCase(),id:r,type:a}}},{key:"isFocusable",get:function(){return this._cache.hasOwnProperty("isFocusable")||(this._cache.isFocusable=axe.commons.dom.isFocusable(this.actualNode)),this._cache.isFocusable}},{key:"tabbableElements",get:function(){return this._cache.hasOwnProperty("tabbableElements")||(this._cache.tabbableElements=axe.commons.dom.getTabbableElements(this)),this._cache.tabbableElements}}]),F);function F(e,t,n){var r;return D(this,F),(r=function(e,t){return!t||"object"!==S(t)&&"function"!=typeof t?y(e):t}(this,g(F).call(this))).shadowId=n,r.children=[],r.actualNode=e,r.parent=t,r._isHidden=null,r._cache={},axe._cache.get("nodeMap")&&axe._cache.get("nodeMap").set(e,y(r)),r}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function j(t,n){"use strict";if(t=t||function(){},n=n||axe.log,!axe._audit)throw new Error("No audit configured");var r=axe.utils.queue(),a=[];Object.keys(axe.plugins).forEach(function(e){r.defer(function(t){function n(e){a.push(e),t()}try{axe.plugins[e].cleanup(t,n)}catch(e){n(e)}})});var e=axe.utils.getFlattenedTree(document.body);axe.utils.querySelectorAll(e,"iframe, frame").forEach(function(n){r.defer(function(e,t){return axe.utils.sendCommandToFrame(n.actualNode,{command:"cleanup-plugin"},e,t)})}),r.then(function(e){0===a.length?t(e):n(a)}).catch(n)}function z(e,t,n){"use strict";function r(e){e instanceof Error==!1&&(e=new Error(e)),n(e)}var a=n,o=e&&e.context||{};o.hasOwnProperty("include")&&!o.include.length&&(o.include=[document]);var i=e&&e.options||{};switch(e.command){case"rules":return _(o,i,function(e,t){a(e),t()},r);case"cleanup-plugin":return j(a,r);default:if(axe._audit&&axe._audit.commands&&axe._audit.commands[e.command])return axe._audit.commands[e.command](e,n)}}function q(e){"use strict";this._run=e.run,this._collect=e.collect,this._registry={},e.commands.forEach(function(e){axe._audit.registerCommand(e)})}axe.AbstractVirtualNode=E,function(axe){var o={helpUrlBase:"https://dequeuniversity.com/rules/",results:[],resultGroups:[],resultGroupMap:{},impact:Object.freeze(["minor","moderate","serious","critical"]),preload:Object.freeze({assets:["cssom"],timeout:1e4})};[{name:"NA",value:"inapplicable",priority:0,group:"inapplicable"},{name:"PASS",value:"passed",priority:1,group:"passes"},{name:"CANTTELL",value:"cantTell",priority:2,group:"incomplete"},{name:"FAIL",value:"failed",priority:3,group:"violations"}].forEach(function(e){var t=e.name,n=e.value,r=e.priority,a=e.group;o[t]=n,o[t+"_PRIO"]=r,o[t+"_GROUP"]=a,o.results[r]=n,o.resultGroups[r]=a,o.resultGroupMap[n]=a}),Object.freeze(o.results),Object.freeze(o.resultGroups),Object.freeze(o.resultGroupMap),Object.freeze(o),Object.defineProperty(axe,"constants",{value:o,enumerable:!0,configurable:!1,writable:!1})}(axe),axe.log=function(){"use strict";"object"===("undefined"==typeof console?"undefined":S(console))&&console.log&&Function.prototype.apply.call(console.log,console,arguments)},axe.cleanup=j,axe.configure=function(e){"use strict";var t;if(!(t=axe._audit))throw new Error("No audit configured");e.reporter&&("function"==typeof e.reporter||T[e.reporter])&&(t.reporter=e.reporter),e.checks&&e.checks.forEach(function(e){t.addCheck(e)});var n=[];e.rules&&e.rules.forEach(function(e){n.push(e.id),t.addRule(e)}),e.disableOtherRules&&t.rules.forEach(function(e){!1===n.includes(e.id)&&(e.enabled=!1)}),void 0!==e.branding?t.setBranding(e.branding):t._constructHelpUrls(),e.tagExclude&&(t.tagExclude=e.tagExclude),e.locale&&t.applyLocale(e.locale)},axe.getRules=function(e){"use strict";var t=(e=e||[]).length?axe._audit.rules.filter(function(t){return!!e.filter(function(e){return-1!==t.tags.indexOf(e)}).length}):axe._audit.rules,n=axe._audit.data.rules||{};return t.map(function(e){var t=n[e.id]||{};return{ruleId:e.id,description:t.description,help:t.help,helpUrl:t.helpUrl,tags:e.tags}})},axe._load=function(e){"use strict";axe.utils.respondable.subscribe("axe.ping",function(e,t,n){n({axe:!0})}),axe.utils.respondable.subscribe("axe.start",z),axe._audit=new n(e)},(axe=axe||{}).plugins={},q.prototype.run=function(){"use strict";return this._run.apply(this,arguments)},q.prototype.collect=function(){"use strict";return this._collect.apply(this,arguments)},q.prototype.cleanup=function(e){"use strict";var n=axe.utils.queue(),r=this;Object.keys(this._registry).forEach(function(t){n.defer(function(e){r._registry[t].cleanup(e)})}),n.then(function(){e()})},q.prototype.add=function(e){"use strict";this._registry[e.id]=e},axe.registerPlugin=function(e){"use strict";axe.plugins[e.id]=new q(e)};var N,T={};function O(){axe._cache.clear(),axe._tree=void 0,axe._selectorData=void 0}function _(n,r,a,o){"use strict";try{n=new p(n),axe._tree=n.flatTree,axe._selectorData=axe.utils.getSelectorData(n.flatTree)}catch(e){return O(),o(e)}var i,e=axe.utils.queue(),u=axe._audit;r.performanceTimer&&axe.utils.performanceTimer.auditStart(),n.frames.length&&!1!==r.iframes&&e.defer(function(e,t){axe.utils.collectResultsFromFrames(n,r,"rules",null,e,t)}),e.defer(function(e,t){r.restoreScroll&&(i=axe.utils.getScrollState()),u.run(n,r,e,t)}),e.then(function(e){try{i&&axe.utils.setScrollState(i),r.performanceTimer&&axe.utils.performanceTimer.auditEnd();var t=axe.utils.mergeResults(e.map(function(e){return{results:e}}));n.initiator&&((t=u.after(t,r)).forEach(axe.utils.publishMetaData),t=t.map(axe.utils.finalizeRuleResult));try{a(t,O)}catch(e){O(),axe.log(e)}}catch(e){O(),o(e)}}).catch(function(e){O(),o(e)})}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}axe.getReporter=function(e){"use strict";return"string"==typeof e&&T[e]?T[e]:"function"==typeof e?e:N},axe.addReporter=function(e,t,n){"use strict";T[e]=t,n&&(N=t)},axe.reset=function(){"use strict";var e=axe._audit;if(!e)throw new Error("No audit configured");e.resetRulesAndChecks()},axe._runRules=_,axe.runVirtualRule=function(t,e){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};n.reporter=n.reporter||axe._audit.reporter||"v1",axe._selectorData={};var r=axe._audit.rules.find(function(e){return e.id===t});if(!r)throw new Error("unknown rule `"+t+"`");var a={include:[e]},o=(r=Object.create(r,{excludeHidden:{value:!1}})).runSync(a,n);axe.utils.publishMetaData(o),axe.utils.finalizeRuleResult(o);var i=axe.utils.aggregateResult([o]);return i.violations.forEach(function(e){return e.nodes.forEach(function(e){e.failureSummary=u.failureSummary(e)})}),R({},u.getEnvironmentData(),{},i,{toolOptions:n})};function B(){}function L(e,t,n){"use strict";var r=new TypeError("axe.run arguments are invalid");if(!function(e){"use strict";switch(!0){case"string"==typeof e:case Array.isArray(e):case Node&&e instanceof Node:case NodeList&&e instanceof NodeList:return!0;case"object"!==S(e):return!1;case void 0!==e.include:case void 0!==e.exclude:case"number"==typeof e.length:return!0;default:return!1}}(e)){if(void 0!==n)throw r;n=t,t=e,e=document}if("object"!==S(t)){if(void 0!==n)throw r;n=t,t={}}if("function"!=typeof n&&void 0!==n)throw r;return{context:e,options:t,callback:n||B}}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}axe.run=function(e,a,o){"use strict";if(!axe._audit)throw new Error("No audit configured");var t,n=L(e,a,o);e=n.context,a=n.options,o=n.callback,a.reporter=a.reporter||axe._audit.reporter||"v1",a.performanceTimer&&axe.utils.performanceTimer.start();var i=B,u=B;return"function"==typeof Promise&&o===B&&(t=new Promise(function(e,t){i=t,u=e})),axe._runRules(e,a,function(e,t){function n(e){t();try{o(null,e)}catch(e){axe.log(e)}u(e)}a.performanceTimer&&axe.utils.performanceTimer.end();try{var r=axe.getReporter(a.reporter)(e,a,n);void 0!==r&&n(r)}catch(e){t(),o(e),i(e)}},function(e){o(e),i(e)}),t},u.failureSummary=function(e){"use strict";var n={};return n.none=e.none.concat(e.all),n.any=e.any,Object.keys(n).map(function(e){if(n[e].length){var t=axe._audit.data.failureSummaries[e];return t&&"function"==typeof t.failureMessage?t.failureMessage(n[e].map(function(e){return e.message||""})):void 0}}).filter(function(e){return void 0!==e}).join("\n\n")},u.getEnvironmentData=function(e){var t=0<arguments.length&&void 0!==e?e:window,n=t.screen,r=void 0===n?{}:n,a=t.navigator,o=void 0===a?{}:a,i=t.location,u=void 0===i?{}:i,s=t.innerHeight,l=t.innerWidth,c=r.msOrientation||r.orientation||r.mozOrientation||{};return{testEngine:{name:"axe-core",version:axe.version},testRunner:{name:axe._audit.brand},testEnvironment:{userAgent:o.userAgent,windowWidth:l,windowHeight:s,orientationAngle:c.angle,orientationType:c.type},timestamp:(new Date).toISOString(),url:u.href}},u.incompleteFallbackMessage=function(){"use strict";return axe._audit.data.incompleteFallbackMessage()};var I=axe.constants.resultGroups;function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}u.processAggregate=function(e,n){var t=axe.utils.aggregateResult(e);return I.forEach(function(e){n.resultTypes&&!n.resultTypes.includes(e)&&(t[e]||[]).forEach(function(e){Array.isArray(e.nodes)&&0<e.nodes.length&&(e.nodes=[e.nodes[0]])}),t[e]=(t[e]||[]).map(function(t){return t=Object.assign({},t),Array.isArray(t.nodes)&&0<t.nodes.length&&(t.nodes=t.nodes.map(function(e){return"object"===S(e.node)&&(e.html=e.node.source,n.elementRef&&!e.node.fromFrame&&(e.element=e.node.element),!1===n.selectors&&!e.node.fromFrame||(e.target=e.node.selector),n.xpath&&(e.xpath=e.node.xpath)),delete e.result,delete e.node,function(t,n){"use strict";["any","all","none"].forEach(function(e){Array.isArray(t[e])&&t[e].filter(function(e){return Array.isArray(e.relatedNodes)}).forEach(function(e){e.relatedNodes=e.relatedNodes.map(function(e){var t={html:e.source};return n.elementRef&&!e.fromFrame&&(t.element=e.element),!1===n.selectors&&!e.fromFrame||(t.target=e.selector),n.xpath&&(t.xpath=e.xpath),t})})})}(e,n),e})),I.forEach(function(e){return delete t[e]}),delete t.pageLevel,delete t.result,t})}),t},axe.addReporter("na",function(e,t,n){"use strict";console.warn('"na" reporter will be deprecated in axe v4.0. Use the "v2" reporter instead.'),"function"==typeof t&&(n=t,t={});var r=u.processAggregate(e,t);n(R({},u.getEnvironmentData(),{toolOptions:t,violations:r.violations,passes:r.passes,incomplete:r.incomplete,inapplicable:r.inapplicable}))}),axe.addReporter("no-passes",function(e,t,n){"use strict";"function"==typeof t&&(n=t,t={}),t.resultTypes=["violations"];var r=u.processAggregate(e,t);n(R({},u.getEnvironmentData(),{toolOptions:t,violations:r.violations}))}),axe.addReporter("rawEnv",function(e,t,n){"function"==typeof t&&(n=t,t={}),axe.getReporter("raw")(e,t,function(e){var t=u.getEnvironmentData();n({raw:e,env:t})})}),axe.addReporter("raw",function(e,t,n){"use strict";if("function"==typeof t&&(n=t,t={}),!e||!Array.isArray(e))return n(e);n(e.map(function(e){for(var t=R({},e),n=0,r=["passes","violations","incomplete","inapplicable"];n<r.length;n++){var a=r[n];t[a]&&Array.isArray(t[a])&&(t[a]=t[a].map(function(e){return R({},e,{node:e.node.toJSON()})}))}return t}))}),axe.addReporter("v1",function(e,t,n){"use strict";"function"==typeof t&&(n=t,t={});var r=u.processAggregate(e,t);r.violations.forEach(function(e){return e.nodes.forEach(function(e){e.failureSummary=u.failureSummary(e)})}),n(R({},u.getEnvironmentData(),{toolOptions:t,violations:r.violations,passes:r.passes,incomplete:r.incomplete,inapplicable:r.inapplicable}))}),axe.addReporter("v2",function(e,t,n){"use strict";"function"==typeof t&&(n=t,t={});var r=u.processAggregate(e,t);n(R({},u.getEnvironmentData(),{toolOptions:t,violations:r.violations,passes:r.passes,incomplete:r.incomplete,inapplicable:r.inapplicable}))},!0),axe.utils.aggregate=function(t,e,n){e=e.slice(),n&&e.push(n);var r=e.map(function(e){return t.indexOf(e)}).sort();return t[r.pop()]};var P=axe.constants,U=P.CANTTELL_PRIO,V=P.FAIL_PRIO,M=[];M[axe.constants.PASS_PRIO]=!0,M[axe.constants.CANTTELL_PRIO]=null,M[axe.constants.FAIL_PRIO]=!1;var axe,H=["any","all","none"];function G(n,r){return H.reduce(function(e,t){return e[t]=(n[t]||[]).map(function(e){return r(e,t)}),e},{})}function W(e,t,n){var r=Object.assign({},t);r.nodes=(r[n]||[]).concat(),axe.constants.resultGroups.forEach(function(e){delete r[e]}),e[n].push(r)}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function $(e,t){"use strict";var n;return axe._tree&&(n=axe.utils.getSelector(t)),new Error(e+": "+(n||t))}function X(e,t,n){this._fromFrame=!!n,this.spec=n||{},t&&t.absolutePaths&&(this._options={toRoot:!0}),this.source=void 0!==this.spec.source?this.spec.source:function(e){var t=e.outerHTML;return t||"function"!=typeof XMLSerializer||(t=(new XMLSerializer).serializeToString(e)),function(e,t){if(t=t||300,e.length>t){var n=e.indexOf(">");e=e.substring(0,n+1)}return e}(t||"")}(e),this._element=e}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Y(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,a=!1,o=void 0;try{for(var i,u=e[Symbol.iterator]();!(r=(i=u.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){a=!0,o=e}finally{try{r||null==u.return||u.return()}finally{if(a)throw o}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function J(e,t){return[e.substring(0,t),e.substring(t)]}function K(e){return e.replace(/\s+$/,"")}axe.utils.aggregateChecks=function(e){var n=Object.assign({},e);G(n,function(e,t){var n=void 0===e.result?-1:M.indexOf(e.result);e.priority=-1!==n?n:axe.constants.CANTTELL_PRIO,"none"===t&&(e.priority===axe.constants.PASS_PRIO?e.priority=axe.constants.FAIL_PRIO:e.priority===axe.constants.FAIL_PRIO&&(e.priority=axe.constants.PASS_PRIO))});var r={all:n.all.reduce(function(e,t){return Math.max(e,t.priority)},0),none:n.none.reduce(function(e,t){return Math.max(e,t.priority)},0),any:n.any.reduce(function(e,t){return Math.min(e,t.priority)},4)%4};n.priority=Math.max(r.all,r.none,r.any);var a=[];return H.forEach(function(t){n[t]=n[t].filter(function(e){return e.priority===n.priority&&e.priority===r[t]}),n[t].forEach(function(e){return a.push(e.impact)})}),[U,V].includes(n.priority)?n.impact=axe.utils.aggregate(axe.constants.impact,a):n.impact=null,G(n,function(e){delete e.result,delete e.priority}),n.result=axe.constants.results[n.priority],delete n.priority,n},axe.utils.aggregateNodeResults=function(e){var n={};if((e=e.map(function(e){if(e.any&&e.all&&e.none)return axe.utils.aggregateChecks(e);if(Array.isArray(e.node))return axe.utils.finalizeRuleResult(e);throw new TypeError("Invalid Result type")}))&&e.length){var t=e.map(function(e){return e.result});n.result=axe.utils.aggregate(axe.constants.results,t,n.result)}else n.result="inapplicable";axe.constants.resultGroups.forEach(function(e){return n[e]=[]}),e.forEach(function(e){var t=axe.constants.resultGroupMap[e.result];n[t].push(e)});var r=axe.constants.FAIL_GROUP;if(0===n[r].length&&(r=axe.constants.CANTTELL_GROUP),0<n[r].length){var a=n[r].map(function(e){return e.impact});n.impact=axe.utils.aggregate(axe.constants.impact,a)||null}else n.impact=null;return n},axe.utils.aggregateResult=function(e){var n={};return axe.constants.resultGroups.forEach(function(e){return n[e]=[]}),e.forEach(function(t){t.error?W(n,t,axe.constants.CANTTELL_GROUP):t.result===axe.constants.NA?W(n,t,axe.constants.NA_GROUP):axe.constants.resultGroups.forEach(function(e){Array.isArray(t[e])&&0<t[e].length&&W(n,t,e)})}),n},axe.utils.areStylesSet=function e(t,n,r){"use strict";var a=window.getComputedStyle(t,null),o=!1;return!!a&&(n.forEach(function(e){a.getPropertyValue(e.property)===e.value&&(o=!0)}),!!o||!(t.nodeName.toUpperCase()===r.toUpperCase()||!t.parentNode)&&e(t.parentNode,n,r))},axe.utils.checkHelper=function(t,n,r,a){"use strict";return{isAsync:!1,async:function(){return this.isAsync=!0,function(e){e instanceof Error==!1?(t.result=e,r(t)):a(e)}},data:function(e){t.data=e},relatedNodes:function(e){e=e instanceof Node?[e]:axe.utils.toArray(e),t.relatedNodes=e.map(function(e){return new axe.utils.DqElement(e,n)})}}},axe.utils.clone=function(e){"use strict";var t,n,r=e;if(null!==e&&"object"===S(e))if(Array.isArray(e))for(r=[],t=0,n=e.length;t<n;t++)r[t]=axe.utils.clone(e[t]);else for(t in r={},e)r[t]=axe.utils.clone(e[t]);return r},axe.utils.sendCommandToFrame=function(t,n,r,a){"use strict";var o=t.contentWindow;if(!o)return axe.log("Frame does not have a content window",t),void r(null);var i=setTimeout(function(){i=setTimeout(function(){n.debug?a($("No response from frame",t)):r(null)},0)},500);axe.utils.respondable(o,"axe.ping",null,void 0,function(){clearTimeout(i);var e=n.options&&n.options.frameWaitTime||6e4;i=setTimeout(function(){a($("Axe in frame timed out",t))},e),axe.utils.respondable(o,"axe.start",n,void 0,function(e){clearTimeout(i),e instanceof Error==!1?r(e):a(e)})})},axe.utils.collectResultsFromFrames=function(e,t,n,o,r,a){"use strict";var i=axe.utils.queue();e.frames.forEach(function(r){var a={options:t,command:n,parameter:o,context:{initiator:!1,page:e.page,include:r.include||[],exclude:r.exclude||[]}};i.defer(function(t,e){var n=r.node;axe.utils.sendCommandToFrame(n,a,function(e){if(e)return t({results:e,frameElement:n,frame:axe.utils.getSelector(n)});t(null)},e)})}),i.then(function(e){r(axe.utils.mergeResults(e,t))}).catch(a)},axe.utils.contains=function(e,t){"use strict";if(e.shadowId||t.shadowId)return function t(e,n){return e.shadowId===n.shadowId||!!e.children.find(function(e){return t(e,n)})}(e,t);if(e.actualNode)return"function"==typeof e.actualNode.contains?e.actualNode.contains(t.actualNode):!!(16&e.actualNode.compareDocumentPosition(t.actualNode));do{if(t===e)return!0}while(t=t&&t.parent);return!1},function(axe){var e=new axe.imports.CssSelectorParser;e.registerSelectorPseudos("not"),e.registerNestingOperators(">"),e.registerAttrEqualityMods("^","$","*"),axe.utils.cssParser=e}(axe),X.prototype={get selector(){return this.spec.selector||[axe.utils.getSelector(this.element,this._options)]},get xpath(){return this.spec.xpath||[axe.utils.getXpath(this.element)]},get element(){return this._element},get fromFrame(){return this._fromFrame},toJSON:function(){"use strict";return{selector:this.selector,source:this.source,xpath:this.xpath}}},X.fromFrame=function(e,t,n){return e.selector.unshift(n.selector),e.xpath.unshift(n.xpath),new axe.utils.DqElement(n.element,t,e)},axe.utils.DqElement=X,axe.utils.matchesSelector=function(){"use strict";var n;return function(e,t){return n&&e[n]||(n=function(e){var t,n,r=["matches","matchesSelector","mozMatchesSelector","webkitMatchesSelector","msMatchesSelector"],a=r.length;for(t=0;t<a;t++)if(e[n=r[t]])return n}(e)),!!e[n]&&e[n](t)}}(),axe.utils.escapeSelector=function(e){"use strict";for(var t,n=String(e),r=n.length,a=-1,o="",i=n.charCodeAt(0);++a<r;)0!=(t=n.charCodeAt(a))?o+=1<=t&&t<=31||127==t||0==a&&48<=t&&t<=57||1==a&&48<=t&&t<=57&&45==i?"\\"+t.toString(16)+" ":(0!=a||1!=r||45!=t)&&(128<=t||45==t||95==t||48<=t&&t<=57||65<=t&&t<=90||97<=t&&t<=122)?n.charAt(a):"\\"+n.charAt(a):o+="�";return o},axe.utils.extendMetaData=function(t,n){Object.assign(t,n),Object.keys(n).filter(function(e){return"function"==typeof n[e]}).forEach(function(e){t[e]=null;try{t[e]=n[e](t)}catch(e){}})},axe.utils.finalizeRuleResult=function(e){return Object.assign(e,axe.utils.aggregateNodeResults(e.nodes)),delete e.nodes,e},axe.utils.findBy=function(e,t,n){if(Array.isArray(e))return e.find(function(e){return"object"===S(e)&&e[t]===n})},(axe=axe||{utils:{}}).utils.getFlattenedTree=function(e,t){return axe._cache.set("nodeMap",new WeakMap),function a(e,o,n){var r,t,i;function u(e,t,n){var r=a(t,o,n);return r&&(e=e.concat(r)),e}if(e.documentElement&&(e=e.documentElement),i=e.nodeName.toLowerCase(),axe.utils.isShadowRoot(e))return r=new A(e,n,o),o="a"+Math.random().toString().substring(2),t=Array.from(e.shadowRoot.childNodes),r.children=t.reduce(function(e,t){return u(e,t,r)},[]),[r];if("content"===i&&"function"==typeof e.getDistributedNodes)return(t=Array.from(e.getDistributedNodes())).reduce(function(e,t){return u(e,t,n)},[]);if("slot"!==i||"function"!=typeof e.assignedNodes)return 1===e.nodeType?(r=new A(e,n,o),t=Array.from(e.childNodes),r.children=t.reduce(function(e,t){return u(e,t,r)},[]),[r]):3===e.nodeType?[new A(e,n)]:void 0;(t=Array.from(e.assignedNodes())).length||(t=function(e){var t=[];for(e=e.firstChild;e;)t.push(e),e=e.nextSibling;return t}(e));window.getComputedStyle(e);return t.reduce(function(e,t){return u(e,t,n)},[])}(e,t)},axe.utils.getNodeFromTree=function(e,t){var n=t||e;return axe._cache.get("nodeMap")?axe._cache.get("nodeMap").get(n):null},axe.utils.getAllChecks=function(e){"use strict";return[].concat(e.any||[]).concat(e.all||[]).concat(e.none||[])},axe.utils.getBaseLang=function(e){return e?e.trim().split("-")[0].toLowerCase():""},axe.utils.getCheckOption=function(e,t,n){var r=((n.rules&&n.rules[t]||{}).checks||{})[e.id],a=(n.checks||{})[e.id],o=e.enabled,i=e.options;return a&&(a.hasOwnProperty("enabled")&&(o=a.enabled),a.hasOwnProperty("options")&&(i=a.options)),r&&(r.hasOwnProperty("enabled")&&(o=r.enabled),r.hasOwnProperty("options")&&(i=r.options)),{enabled:o,options:i,absolutePaths:n.absolutePaths}},axe.utils.getFriendlyUriEnd=function(e,t){var n=0<arguments.length&&void 0!==e?e:"",r=1<arguments.length&&void 0!==t?t:{};if(!(n.length<=1||"data:"===n.substr(0,5)||"javascript:"===n.substr(0,11)||n.includes("?"))){var a=r.currentDomain,o=r.maxLength,i=void 0===o?25:o,u=function(e){var t=e,n="",r="",a="",o="",i="";if(e.includes("#")){var u=Y(J(e,e.indexOf("#")),2);e=u[0],i=u[1]}if(e.includes("?")){var s=Y(J(e,e.indexOf("?")),2);e=s[0],o=s[1]}if(e.includes("://")){var l=Y(e.split("://"),2);n=l[0];var c=Y(J(e=l[1],e.indexOf("/")),2);r=c[0],e=c[1]}else if("//"===e.substr(0,2)){var d=Y(J(e=e.substr(2),e.indexOf("/")),2);r=d[0],e=d[1]}if("www."===r.substr(0,4)&&(r=r.substr(4)),r&&r.includes(":")){var m=Y(J(r,r.indexOf(":")),2);r=m[0],a=m[1]}return{original:t,protocol:n,domain:r,port:a,path:e,query:o,hash:i}}(n),s=u.path,l=u.domain,c=u.hash,d=s.substr(s.substr(0,s.length-2).lastIndexOf("/")+1);if(c)return d&&(d+c).length<=i?K(d+c):d.length<2&&2<c.length&&c.length<=i?K(c):void 0;if(l&&l.length<i&&s.length<=1)return K(l+s);if(s==="/"+d&&l&&a&&l!==a&&(l+s).length<=i)return K(l+s);var m=d.lastIndexOf(".");return(-1===m||1<m)&&(-1!==m||2<d.length)&&d.length<=i&&!d.match(/index(\.[a-zA-Z]{2-4})?/)&&!function(e){var t=0<arguments.length&&void 0!==e?e:"";return 0!==t.length&&(t.match(/[0-9]/g)||"").length>=t.length/2}(d)?K(d):void 0}},axe.utils.getNodeAttributes=function(e){return e.attributes instanceof window.NamedNodeMap?e.attributes:e.cloneNode(!1).attributes},axe.utils.getRootNode=function(e){var t=e.getRootNode&&e.getRootNode()||document;return t===e&&(t=document),t},axe.utils.getScroll=function(e,t){var n=1<arguments.length&&void 0!==t?t:0,r=e.scrollWidth>e.clientWidth+n,a=e.scrollHeight>e.clientHeight+n;if(r||a){var o=window.getComputedStyle(e),i=o.getPropertyValue("overflow-x"),u=o.getPropertyValue("overflow-y");return r&&("visible"!==i&&"hidden"!==i)||a&&("visible"!==u&&"hidden"!==u)?{elm:e,top:e.scrollTop,left:e.scrollLeft}:void 0}};var Z,Q,ee=axe.utils.escapeSelector,te=["class","style","id","selected","checked","disabled","tabindex","aria-checked","aria-selected","aria-invalid","aria-activedescendant","aria-busy","aria-disabled","aria-expanded","aria-grabbed","aria-pressed","aria-valuenow"],ne=31;function re(e,t){var n,r=t.name;if(-1!==r.indexOf("href")||-1!==r.indexOf("src")){var a=axe.utils.getFriendlyUriEnd(e.getAttribute(r));if(a){var o=encodeURI(a);if(!o)return;n=ee(t.name)+'$="'+ee(o)+'"'}else n=ee(t.name)+'="'+ee(e.getAttribute(r))+'"'}else n=ee(r)+'="'+ee(t.value)+'"';return n}function ae(e,t){return e.count<t.count?-1:e.count===t.count?0:1}function oe(e){return!te.includes(e.name)&&-1===e.name.indexOf(":")&&(!e.value||e.value.length<ne)}function ie(t,n){var e=t.parentNode&&Array.from(t.parentNode.children||"")||[];return e.find(function(e){return e!==t&&axe.utils.matchesSelector(e,n)})?":nth-child("+(1+e.indexOf(t))+")":""}function ue(e){if(e.getAttribute("id")){var t=e.getRootNode&&e.getRootNode()||document,n="#"+ee(e.getAttribute("id")||"");return n.match(/player_uid_/)||1!==t.querySelectorAll(n).length?void 0:n}}function se(e){return void 0===Z&&(Z=axe.utils.isXHTML(document)),ee(Z?e.localName:e.nodeName.toLowerCase())}function le(e,t){var n,r="",a=function(n,e){var r=[],a=e.classes,o=e.tags;return n.classList&&Array.from(n.classList).forEach(function(e){var t=ee(e);a[t]<o[n.nodeName]&&r.push({name:t,count:a[t],species:"class"})}),r.sort(ae)}(e,t),o=function(n,e){var r=[],a=e.attributes,o=e.tags;return n.hasAttributes()&&Array.from(axe.utils.getNodeAttributes(n)).filter(oe).forEach(function(e){var t=re(n,e);t&&a[t]<o[n.nodeName]&&r.push({name:t,count:a[t],species:"attribute"})}),r.sort(ae)}(e,t);return a.length&&1===a[0].count?n=[a[0]]:o.length&&1===o[0].count?(n=[o[0]],r=se(e)):((n=a.concat(o)).sort(ae),(n=n.slice(0,3)).some(function(e){return"class"===e.species})?n.sort(function(e,t){return e.species!==t.species&&"class"===e.species?-1:e.species===t.species?0:1}):r=se(e)),r+n.reduce(function(e,t){switch(t.species){case"class":return e+"."+t.name;case"attribute":return e+"["+t.name+"]"}return e},"")}function ce(e,t,n){if(!axe._selectorData)throw new Error("Expect axe._selectorData to be set up");var r,a,o=t.toRoot,i=void 0!==o&&o;do{var u=ue(e);u||(u=le(e,axe._selectorData),u+=ie(e,u)),r=r?u+" > "+r:u,a=a?a.filter(function(e){return axe.utils.matchesSelector(e,r)}):Array.from(n.querySelectorAll(r)),e=e.parentElement}while((1<a.length||i)&&e&&11!==e.nodeType);return 1===a.length?r:-1!==r.indexOf(" > ")?":root"+r.substring(r.indexOf(" > ")):":root"}axe.utils.getSelectorData=function(e){function t(){var e=a.pop(),n=e.actualNode;if(n.querySelectorAll){var t=n.nodeName;r.tags[t]?r.tags[t]++:r.tags[t]=1,n.classList&&Array.from(n.classList).forEach(function(e){var t=ee(e);r.classes[t]?r.classes[t]++:r.classes[t]=1}),n.hasAttributes()&&Array.from(axe.utils.getNodeAttributes(n)).filter(oe).forEach(function(e){var t=re(n,e);t&&(r.attributes[t]?r.attributes[t]++:r.attributes[t]=1)})}for(e.children.length&&(o.push(a),a=e.children.slice());!a.length&&o.length;)a=o.pop()}for(var r={classes:{},tags:{},attributes:{}},a=(e=Array.isArray(e)?e:[e]).slice(),o=[];a.length;)t();return r},axe.utils.getSelector=function(e,t){var n=1<arguments.length&&void 0!==t?t:{};if(!e)return"";var r=e.getRootNode&&e.getRootNode()||document;if(11!==r.nodeType)return ce(e,n,r);for(var a=[];11===r.nodeType;)a.push({elm:e,doc:r}),r=(e=r.host).getRootNode();return a.push({elm:e,doc:r}),a.reverse().map(function(e){return ce(e.elm,n,e.doc)})},axe.utils.getStyleSheetFactory=function(d){if(!d)throw new Error("axe.utils.getStyleSheetFactory should be invoked with an argument");return function(e){var t=e.data,n=e.isCrossOrigin,r=void 0!==n&&n,a=e.shadowId,o=e.root,i=e.priority,u=e.isLink,s=void 0!==u&&u,l=d.createElement("style");if(s){var c=d.createTextNode('@import "'.concat(t.href,'"'));l.appendChild(c)}else l.appendChild(d.createTextNode(t));return d.head.appendChild(l),{sheet:l.sheet,isCrossOrigin:r,shadowId:a,root:o,priority:i}}},axe.utils.getXpath=function(e){return function(e){return e.reduce(function(e,t){return t.id?"/".concat(t.str,"[@id='").concat(t.id,"']"):e+"/".concat(t.str)+(0<t.count?"[".concat(t.count,"]"):"")},"")}(function e(t,n){var r,a;if(!t)return[];if(!n&&9===t.nodeType)return n=[{str:"html"}];if(n=n||[],t.parentNode&&t.parentNode!==t&&(n=e(t.parentNode,n)),t.previousSibling){for(a=1,r=t.previousSibling;1===r.nodeType&&r.nodeName===t.nodeName&&a++,r=r.previousSibling;);1===a&&(a=null)}else if(t.nextSibling)for(r=t.nextSibling;r=1===r.nodeType&&r.nodeName===t.nodeName?(a=1,null):(a=null,r.previousSibling););if(1===t.nodeType){var o={};o.str=t.nodeName.toLowerCase();var i=t.getAttribute&&axe.utils.escapeSelector(t.getAttribute("id"));i&&1===t.ownerDocument.querySelectorAll("#"+i).length&&(o.id=t.getAttribute("id")),1<a&&(o.count=a),n.push(o)}return n}(e))},axe.utils.injectStyle=function(e){"use strict";if(Q&&Q.parentNode)return void 0===Q.styleSheet?Q.appendChild(document.createTextNode(e)):Q.styleSheet.cssText+=e,Q;if(e){var t=document.head||document.getElementsByTagName("head")[0];return(Q=document.createElement("style")).type="text/css",void 0===Q.styleSheet?Q.appendChild(document.createTextNode(e)):Q.styleSheet.cssText=e,t.appendChild(Q),Q}},axe.utils.isHidden=function(e,t){"use strict";var n=axe.utils.getNodeFromTree(e);if(9===e.nodeType)return!1;if(11===e.nodeType&&(e=e.host),n&&null!==n._isHidden)return n._isHidden;var r=window.getComputedStyle(e,null);if(!r||!e.parentNode||"none"===r.getPropertyValue("display")||!t&&"hidden"===r.getPropertyValue("visibility")||"true"===e.getAttribute("aria-hidden"))return!0;var a=e.assignedSlot?e.assignedSlot:e.parentNode,o=axe.utils.isHidden(a,!0);return n&&(n._isHidden=o),o};var de=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","data","datalist","dd","del","details","dfn","dialog","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","main","map","mark","math","menu","menuitem","meta","meter","nav","noscript","object","ol","optgroup","option","output","p","param","picture","pre","progress","q","rb","rp","rt","rtc","ruby","s","samp","script","section","select","slot","small","source","span","strong","style","sub","summary","sup","svg","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","u","ul","var","video","wbr"];axe.utils.isHtmlElement=function(e){var t=e.nodeName.toLowerCase();return de.includes(t)&&"http://www.w3.org/2000/svg"!==e.namespaceURI};var me,pe,fe=["article","aside","blockquote","body","div","footer","h1","h2","h3","h4","h5","h6","header","main","nav","p","section","span"];function he(e){return function(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function be(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function ge(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}function ye(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}function ve(e){return"function"==typeof e||"[object Function]"===me.call(e)}function De(e){var t=function(e){var t=Number(e);return isNaN(t)?0:0!==t&&isFinite(t)?(0<t?1:-1)*Math.floor(Math.abs(t)):t}(e);return Math.min(Math.max(t,0),pe)}function we(e){var t=e.nodeName.toUpperCase(),n=e.getAttribute("href"),r=e.getAttribute("rel"),a="LINK"===t&&n&&r&&e.rel.toUpperCase().includes("STYLESHEET");return"STYLE"===t||a&&ke(e.media)}function ke(e){return!e||!e.toUpperCase().includes("PRINT")}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function xe(a,o){"use strict";return function(e){var t=a[e.id]||{},n=t.messages||{},r=Object.assign({},t);delete r.messages,void 0===e.result?"object"===S(n.incomplete)?r.message=function(){return function(t,n){function r(e){return e.incomplete&&e.incomplete.default?e.incomplete.default:u.incompleteFallbackMessage()}if(!t||!t.missingData)return r(n);try{var e=n.incomplete[t.missingData[0].reason];if(!e)throw new Error;return e}catch(e){return"string"==typeof t.missingData?n.incomplete[t.missingData]:r(n)}}(e.data,n)}:r.message=n.incomplete:r.message=e.result===o?n.pass:n.fail,axe.utils.extendMetaData(e,r)}}axe.utils.isShadowRoot=function(e){var t=e.nodeName.toLowerCase();return!(!e.shadowRoot||!/^[a-z][a-z0-9_.-]*-[a-z0-9_.-]*$/.test(t)&&!fe.includes(t))},axe.utils.isXHTML=function(e){"use strict";return!!e.createElement&&"A"===e.createElement("A").localName},axe.utils.mergeResults=function(e,r){"use strict";var a=[];return e.forEach(function(n){var e=function(e){"use strict";return e&&e.results?Array.isArray(e.results)?e.results.length?e.results:null:[e.results]:null}(n);e&&e.length&&e.forEach(function(e){e.nodes&&n.frame&&function(e,n,t,r){"use strict";var a={element:t,selector:r,xpath:axe.utils.getXpath(t)};e.forEach(function(e){e.node=axe.utils.DqElement.fromFrame(e.node,n,a);var t=axe.utils.getAllChecks(e);t.length&&t.forEach(function(e){e.relatedNodes=e.relatedNodes.map(function(e){return axe.utils.DqElement.fromFrame(e,n,a)})})})}(e.nodes,r,n.frameElement,n.frame);var t=axe.utils.findBy(a,"id",e.id);t?e.nodes.length&&function(e,t){"use strict";for(var n,r,a=t[0].node,o=0,i=e.length;o<i;o++)if(r=e[o].node,0<(n=axe.utils.nodeSorter({actualNode:r.element},{actualNode:a.element}))||0===n&&a.selector.length<r.selector.length)return e.splice.apply(e,[o,0].concat(t));e.push.apply(e,t)}(t.nodes,e.nodes):a.push(e)})}),a},axe.utils.nodeSorter=function(e,t){return(e=e.actualNode||e)===(t=t.actualNode||t)?0:4&e.compareDocumentPosition(t)?-1:1},axe.utils.parseCrossOriginStylesheet=function(e,r,a,o,i){var t={method:"get",url:e};return o.push(e),axe.imports.axios(t).then(function(e){var t=e.data,n=r.convertDataToStylesheet({data:t,isCrossOrigin:i,priority:a,root:r.rootNode,shadowId:r.shadowId});return axe.utils.parseStylesheet(n.sheet,r,a,o,n.isCrossOrigin)})},axe.utils.parseSameOriginStylesheet=function(e,a,o,i,t){var n=4<arguments.length&&void 0!==t&&t,r=Array.from(e.cssRules);if(!r)return Promise.resolve();var u=r.filter(function(e){return 3===e.type});if(!u.length)return Promise.resolve({isCrossOrigin:n,priority:o,root:a.rootNode,shadowId:a.shadowId,sheet:e});var s=u.filter(function(e){return e.href}).map(function(e){return e.href}).filter(function(e){return!i.includes(e)}).map(function(e,t){var n=[].concat(he(o),[t]),r=/^https?:\/\/|^\/\//i.test(e);return axe.utils.parseCrossOriginStylesheet(e,a,n,i,r)}),l=r.filter(function(e){return 3!==e.type});return l.length&&s.push(Promise.resolve(a.convertDataToStylesheet({data:l.map(function(e){return e.cssText}).join(),isCrossOrigin:n,priority:o,root:a.rootNode,shadowId:a.shadowId}))),Promise.all(s)},axe.utils.parseStylesheet=function(e,t,n,r,a){var o=4<arguments.length&&void 0!==a&&a;return function(e){try{return!(!e.cssRules&&e.href)}catch(e){return!1}}(e)?axe.utils.parseSameOriginStylesheet(e,t,n,r,o):axe.utils.parseCrossOriginStylesheet(e.href,t,n,r,!0)},utils.performanceTimer=function(){"use strict";function e(){if(window.performance&&window.performance)return window.performance.now()}var t=null,n=e();return{start:function(){this.mark("mark_axe_start")},end:function(){this.mark("mark_axe_end"),this.measure("axe","mark_axe_start","mark_axe_end"),this.logMeasures("axe")},auditStart:function(){this.mark("mark_audit_start")},auditEnd:function(){this.mark("mark_audit_end"),this.measure("audit_start_to_end","mark_audit_start","mark_audit_end"),this.logMeasures()},mark:function(e){window.performance&&void 0!==window.performance.mark&&window.performance.mark(e)},measure:function(e,t,n){window.performance&&void 0!==window.performance.measure&&window.performance.measure(e,t,n)},logMeasures:function(e){function t(e){axe.log("Measure "+e.name+" took "+e.duration+"ms")}if(window.performance&&void 0!==window.performance.getEntriesByType)for(var n=window.performance.getEntriesByName("mark_axe_start")[0],r=window.performance.getEntriesByType("measure").filter(function(e){return e.startTime>=n.startTime}),a=0;a<r.length;++a){var o=r[a];if(o.name===e)return void t(o);t(o)}},timeElapsed:function(){return e()-n},reset:function(){t=t||e(),n=e()}}}(),"function"!=typeof Object.assign&&(Object.assign=function(e){"use strict";if(null==e)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(e),n=1;n<arguments.length;n++){var r=arguments[n];if(null!=r)for(var a in r)r.hasOwnProperty(a)&&(t[a]=r[a])}return t}),Array.prototype.find||Object.defineProperty(Array.prototype,"find",{value:function(e){if(null===this)throw new TypeError("Array.prototype.find called on null or undefined");if("function"!=typeof e)throw new TypeError("predicate must be a function");for(var t,n=Object(this),r=n.length>>>0,a=arguments[1],o=0;o<r;o++)if(t=n[o],e.call(a,t,o,n))return t}}),axe.utils.pollyfillElementsFromPoint=function(){if(document.elementsFromPoint)return document.elementsFromPoint;if(document.msElementsFromPoint)return document.msElementsFromPoint;var e,t=((e=document.createElement("x")).style.cssText="pointer-events:auto","auto"===e.style.pointerEvents),u=t?"pointer-events":"visibility",s=t?"none":"hidden",l=document.createElement("style");return l.innerHTML=t?"* { pointer-events: all }":"* { visibility: visible }",function(e,t){var n,r,a,o=[],i=[];for(document.head.appendChild(l);(n=document.elementFromPoint(e,t))&&-1===o.indexOf(n);)o.push(n),i.push({value:n.style.getPropertyValue(u),priority:n.style.getPropertyPriority(u)}),n.style.setProperty(u,s,"important");for(o.indexOf(document.documentElement)<o.length-1&&(o.splice(o.indexOf(document.documentElement),1),o.push(document.documentElement)),r=i.length;a=i[--r];)o[r].style.setProperty(u,a.value?a.value:"",a.priority);return document.head.removeChild(l),o}},"function"==typeof window.addEventListener&&(document.elementsFromPoint=axe.utils.pollyfillElementsFromPoint()),Array.prototype.includes||Object.defineProperty(Array.prototype,"includes",{value:function(e,t){"use strict";var n=Object(this),r=parseInt(n.length,10)||0;if(0===r)return!1;var a,o,i=parseInt(t,10)||0;for(0<=i?a=i:(a=r+i)<0&&(a=0);a<r;){if(e===(o=n[a])||e!=e&&o!=o)return!0;a++}return!1}}),Array.prototype.some||Object.defineProperty(Array.prototype,"some",{value:function(e,t){"use strict";if(null==this)throw new TypeError("Array.prototype.some called on null or undefined");if("function"!=typeof e)throw new TypeError;for(var n=Object(this),r=n.length>>>0,a=2<=arguments.length?t:void 0,o=0;o<r;o++)if(o in n&&e.call(a,n[o],o,n))return!0;return!1}}),Array.from||Object.defineProperty(Array,"from",{value:(me=Object.prototype.toString,pe=Math.pow(2,53)-1,function(e,t,n){var r=Object(e);if(null==e)throw new TypeError("Array.from requires an array-like object - not null or undefined");var a,o=1<arguments.length?t:void 0;if(void 0!==o){if(!ve(o))throw new TypeError("Array.from: when provided, the second argument must be a function");2<arguments.length&&(a=n)}for(var i,u=De(r.length),s=ve(this)?Object(new this(u)):new Array(u),l=0;l<u;)i=r[l],s[l]=o?void 0===a?o(i,l):o.call(a,i,l):i,l+=1;return s.length=u,s})}),String.prototype.includes||(String.prototype.includes=function(e,t){return"number"!=typeof t&&(t=0),!(t+e.length>this.length)&&-1!==this.indexOf(e,t)}),axe.utils.preloadCssom=function(e){var t=e.treeRoot,n=function(e){var t=[],n=axe.utils.querySelectorAllFilter(e,"*",function(e){return!t.includes(e.shadowId)&&(t.push(e.shadowId),!0)}).map(function(e){return{shadowId:e.shadowId,rootNode:axe.utils.getRootNode(e.actualNode)}});return axe.utils.uniqueArray(n,[])}(void 0===t?axe._tree[0]:t);if(!n.length)return Promise.resolve();var r=document.implementation.createHTMLDocument("Dynamic document for loading cssom");return function(e,l){var c=[];return e.forEach(function(e,t){var n=e.rootNode,r=e.shadowId,a=function(e,t,n){var r;r=11===e.nodeType&&t?function(o,i){return Array.from(o.children).filter(we).reduce(function(e,t){var n=t.nodeName.toUpperCase(),r="STYLE"===n?t.textContent:t,a=i({data:r,isLink:"LINK"===n,root:o});return e.push(a.sheet),e},[])}(e,n):function(e){return Array.from(e.styleSheets).filter(function(e){return ke(e.media.mediaText)})}(e);return function(e){var t=[];return e.filter(function(e){return!e.href||!t.includes(e.href)&&(t.push(e.href),!0)})}(r)}(n,r,l);if(!a)return Promise.all(c);var o=t+1,i={rootNode:n,shadowId:r,convertDataToStylesheet:l,rootIndex:o},u=[],s=Promise.all(a.map(function(e,t){var n=[o,t];return axe.utils.parseStylesheet(e,i,n,u)}));c.push(s)}),Promise.all(c)}(n,axe.utils.getStyleSheetFactory(r)).then(function(e){return function n(e){return e.reduce(function(e,t){return Array.isArray(t)?e.concat(n(t)):e.concat(t)},[])}(e)})},axe.utils.shouldPreload=function(e){return!e||void 0===e.preload||null===e.preload||("boolean"==typeof e.preload?e.preload:function(e){return"object"===S(e)&&Array.isArray(e.assets)}(e.preload))},axe.utils.getPreloadConfig=function(e){var t=axe.constants.preload,n=t.assets,r=t.timeout,a={assets:n,timeout:r};if(!e.preload)return a;if("boolean"==typeof e.preload)return a;if(!e.preload.assets.every(function(e){return n.includes(e.toLowerCase())}))throw new Error("Requested assets, not supported. "+"Supported assets are: ".concat(n.join(", "),"."));return a.assets=axe.utils.uniqueArray(e.preload.assets.map(function(e){return e.toLowerCase()}),[]),e.preload.timeout&&"number"==typeof e.preload.timeout&&!Number.isNaN(e.preload.timeout)&&(a.timeout=e.preload.timeout),a},axe.utils.preload=function(o){var i={cssom:axe.utils.preloadCssom};return axe.utils.shouldPreload(o)?new Promise(function(n,e){var t=axe.utils.getPreloadConfig(o),r=t.assets,a=t.timeout;setTimeout(function(){return e("Preload assets timed out.")},a),Promise.all(r.map(function(t){return i[t](o).then(function(e){return function(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}({},t,e)})})).then(function(e){var t=e.reduce(function(e,t){return R({},e,{},t)},{});n(t)})}):Promise.resolve()},axe.utils.publishMetaData=function(e){"use strict";var t=axe._audit.data.checks||{},n=axe._audit.data.rules||{},r=axe.utils.findBy(axe._audit.rules,"id",e.id)||{};e.tags=axe.utils.clone(r.tags||[]);var a=xe(t,!0),o=xe(t,!1);e.nodes.forEach(function(e){e.any.forEach(a),e.all.forEach(a),e.none.forEach(o)}),axe.utils.extendMetaData(e,axe.utils.clone(n[e.id]||{}))};var Ee=function(){},Ce=function(){};var Ae,Fe,je=(Ae=/(?=[\-\[\]{}()*+?.\\\^$|,#\s])/g,function(e){return e.replace(Ae,"\\")}),ze=/\\/g;function qe(e){if(e)return e.map(function(e){var t,n,r=e.name.replace(ze,""),a=(e.value||"").replace(ze,"");switch(e.operator){case"^=":n=new RegExp("^"+je(a));break;case"$=":n=new RegExp(je(a)+"$");break;case"~=":n=new RegExp("(^|\\s)"+je(a)+"(\\s|$)");break;case"|=":n=new RegExp("^"+je(a)+"(-|$)");break;case"=":t=function(e){return a===e};break;case"*=":t=function(e){return e&&e.includes(a)};break;case"!=":t=function(e){return a!==e};break;default:t=function(e){return!!e}}return""===a&&/^[*$^]=$/.test(e.operator)&&(t=function(){return!1}),{key:r,value:a,test:t=t||function(e){return e&&n.test(e)}}})}function Ne(e){if(e)return e.map(function(e){return{value:e=e.replace(ze,""),regexp:new RegExp("(^|\\s)"+je(e)+"(\\s|$)")}})}function Te(e){if(e)return e.map(function(e){var t;return"not"===e.name&&(t=(t=e.value).selectors?t.selectors:[t],t=Ee(t)),{name:e.name,expressions:t,value:e.value}})}function Se(e,t,n,r){var a={vNodes:e.slice(),anyLevel:t,thisLevel:n,parentShadowId:r};return a.vNodes.reverse(),a}function Re(e,t){return function(e,t){return 1===e.props.nodeType&&("*"===t.tag||e.props.nodeName===t.tag)}(e,t[0])&&function(t,e){return!e.classes||e.classes.every(function(e){return t.hasClass(e.value)})}(e,t[0])&&function(r,e){return!e.attributes||e.attributes.reduce(function(e,t){var n=r.attr(t.key);return e&&null!==n&&(!t.value||t.test(n))},!0)}(e,t[0])&&function(e,t){return!t.id||e.props.id===t.id}(e,t[0])&&function(n,e){return!(e.pseudos&&!e.pseudos.reduce(function(e,t){if("not"===t.name)return e&&!Ce([n],t.expressions,!1).length;throw new Error("the pseudo selector "+t.name+" has not yet been implemented")},!0))}(e,t[0])}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function Oe(t,e){"use strict";var n,r,a=axe._audit&&axe._audit.tagExclude?axe._audit.tagExclude:[];return r=e.hasOwnProperty("include")||e.hasOwnProperty("exclude")?(n=e.include||[],n=Array.isArray(n)?n:[n],r=e.exclude||[],(r=Array.isArray(r)?r:[r]).concat(a.filter(function(e){return-1===n.indexOf(e)}))):(n=Array.isArray(e)?e:[e],a.filter(function(e){return-1===n.indexOf(e)})),!!(n.some(function(e){return-1!==t.tags.indexOf(e)})||0===n.length&&!1!==t.enabled)&&r.every(function(e){return-1===t.tags.indexOf(e)})}function _e(e){"use strict";return e.sort(function(e,t){return axe.utils.contains(e,t)?1:-1})[0]}function Be(t,e){"use strict";var n=e.include&&_e(e.include.filter(function(e){return axe.utils.contains(e,t)})),r=e.exclude&&_e(e.exclude.filter(function(e){return axe.utils.contains(e,t)}));return!!(!r&&n||r&&axe.utils.contains(r,n))}function Le(e,t){"use strict";var n;if(0===e.length)return t;e.length<t.length&&(n=e,e=t,t=n);for(var r=0,a=t.length;r<a;r++)e.includes(t[r])||e.push(t[r]);return e}Ee=function(e){return e.map(function(e){for(var t=[],n=e.rule;n;)t.push({tag:n.tagName?n.tagName.toLowerCase():"*",combinator:n.nestingOperator?n.nestingOperator:" ",id:n.id,attributes:qe(n.attrs),classes:Ne(n.classNames),pseudos:Te(n.pseudos)}),n=n.rule;return t})},Ce=function(e,t,n,r){for(var a=[],o=Se(Array.isArray(e)?e:[e],t,[],e[0].shadowId),i=[];o.vNodes.length;){for(var u=o.vNodes.pop(),s=[],l=[],c=o.anyLevel.slice().concat(o.thisLevel),d=!1,m=0;m<c.length;m++){var p=c[m];if(Re(u,p)&&(!p[0].id||u.shadowId===o.parentShadowId))if(1===p.length)d||r&&!r(u)||(i.push(u),d=!0);else{var f=p.slice(1);if(!1===[" ",">"].includes(f[0].combinator))throw new Error("axe.utils.querySelectorAll does not support the combinator: "+p[1].combinator);">"===f[0].combinator?s.push(f):l.push(f)}!o.anyLevel.includes(p)||p[0].id&&u.shadowId!==o.parentShadowId||l.push(p)}for(u.children&&u.children.length&&n&&(a.push(o),o=Se(u.children,l,s,u.shadowId));!o.vNodes.length&&a.length;)o=a.pop()}return i},axe.utils.querySelectorAll=function(e,t){return axe.utils.querySelectorAllFilter(e,t)},axe.utils.querySelectorAllFilter=function(e,t,n){e=Array.isArray(e)?e:[e];var r=axe.utils.cssParser.parse(t);return r=r.selectors?r.selectors:[r],r=Ee(r),Ce(e,r,!0,n)},function(){"use strict";function m(){}function p(e){if("function"!=typeof e)throw new TypeError("Queue methods require functions as arguments")}axe.utils.queue=function(){function t(e){r=e,setTimeout(function(){null!=r&&axe.log("Uncaught error (of queue)",r)},1)}var r,a=[],o=0,i=0,n=m,u=!1,s=t;function l(t){return function(e){a[t]=e,(i-=1)||n===m||(u=!0,n(a))}}function c(e){return n=m,s(e),a}var d={defer:function(e){if("object"===S(e)&&e.then&&e.catch){var n=e;e=function(e,t){n.then(e).catch(t)}}if(p(e),void 0===r){if(u)throw new Error("Queue already completed");return a.push(e),++i,function(){for(var e=a.length;o<e;o++){var t=a[o];try{t.call(null,l(o),c)}catch(e){c(e)}}}(),d}},then:function(e){if(p(e),n!==m)throw new Error("queue `then` already set");return r||(n=e,i||(u=!0,n(a))),d},catch:function(e){if(p(e),s!==t)throw new Error("queue `catch` already set");return r?(e(r),r=null):s=e,d},abort:c};return d}}(),function(e){"use strict";var s={},i={},a=Object.freeze(["EvalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);function l(){var e="axeAPI",t="";return void 0!==axe&&axe._audit&&axe._audit.application&&(e=axe._audit.application),void 0!==axe&&(t=axe.version),e+"."+t}function u(e,t,n,r,a,o){var i;n instanceof Error&&(i={name:n.name,message:n.message,stack:n.stack},n=void 0);var u={uuid:r,topic:t,message:n,error:i,_respondable:!0,_source:l(),_keepalive:a};"function"==typeof o&&(s[r]=o),e.postMessage(JSON.stringify(u),"*")}function t(e,t,n,r,a){u(e,t,n,Fe.v1(),r,a)}function c(r,a,o){return function(e,t,n){u(r,a,e,o,t,n)}}function o(e){var t;if("string"==typeof e){try{t=JSON.parse(e)}catch(e){}if(function(e){if("object"!==S(e)||"string"!=typeof e.uuid||!0!==e._respondable)return!1;var t=l();return e._source===t||"axeAPI.x.y.z"===e._source||"axeAPI.x.y.z"===t}(t))return"object"===S(t.error)?t.error=function(e){var t=e.message||"Unknown error occurred",n=a.includes(e.name)?e.name:"Error",r=window[n]||Error;return e.stack&&(t+="\n"+e.stack.replace(e.message,"")),new r(t)}(t.error):t.error=void 0,t}}t.subscribe=function(e,t){i[e]=t},t.isInFrame=function(e){return!!(e=e||window).frameElement},"function"==typeof window.addEventListener&&window.addEventListener("message",function(t){var n=o(t.data);if(n){var r=n.uuid,e=n._keepalive,a=s[r];if(a)a(n.error||n.message,e,c(t.source,n.topic,r)),e||delete s[r];if(!n.error)try{!function(e,t,n){var r=t.topic,a=i[r];if(a){var o=c(e,null,t.uuid);a(t.message,n,o)}}(t.source,n,e)}catch(e){u(t.source,n.topic,e,r,!1)}}},!1),e.respondable=t}(utils),axe.utils.ruleShouldRun=function(e,t,n){"use strict";var r=n.runOnly||{},a=(n.rules||{})[e.id];return!(e.pageLevel&&!t.page)&&("rule"===r.type?-1!==r.values.indexOf(e.id):a&&"boolean"==typeof a.enabled?a.enabled:"tag"===r.type&&r.values?Oe(e,r.values):Oe(e,[]))},axe.utils.getScrollState=function(e){var t=0<arguments.length&&void 0!==e?e:window,n=t.document.documentElement;return[void 0!==t.pageXOffset?{elm:t,top:t.pageYOffset,left:t.pageXOffset}:{elm:n,top:n.scrollTop,left:n.scrollLeft}].concat(function r(e){return Array.from(e.children).reduce(function(e,t){var n=axe.utils.getScroll(t);return n&&e.push(n),e.concat(r(t))},[])}(document.body))},axe.utils.setScrollState=function(e){e.forEach(function(e){return function(e,t,n){if(e===window)return e.scroll(n,t);e.scrollTop=t,e.scrollLeft=n}(e.elm,e.top,e.left)})},axe.utils.select=function(e,t){"use strict";var n,r=[];if(axe._selectCache)for(var a=0,o=axe._selectCache.length;a<o;a++){var i=axe._selectCache[a];if(i.selector===e)return i.result}for(var u,s=(u=t,function(e){return Be(e,u)}),l=function(e){return e.reduce(function(e,t){return e.length&&axe.utils.contains(e[e.length-1],t)||e.push(t),e},[])}(t.include),c=0;c<l.length;c++)n=l[c],r=Le(r,axe.utils.querySelectorAllFilter(n,e,s));return axe._selectCache&&axe._selectCache.push({selector:e,result:r}),r},axe.utils.toArray=function(e){"use strict";return Array.prototype.slice.call(e)},axe.utils.uniqueArray=function(e,t){return e.concat(t).filter(function(e,t,n){return n.indexOf(e)===t})},axe.utils.tokenList=function(e){"use strict";return e.trim().replace(/\s{2,}/g," ").split(" ")},function(e){var i,t=e.crypto||e.msCrypto;if(!i&&t&&t.getRandomValues){var n=new Uint8Array(16);i=function(){return t.getRandomValues(n),n}}if(!i){var r=new Array(16);i=function(){for(var e,t=0;t<16;t++)0==(3&t)&&(e=4294967296*Math.random()),r[t]=e>>>((3&t)<<3)&255;return r}}for(var u="function"==typeof e.Buffer?e.Buffer:Array,a=[],o={},s=0;s<256;s++)a[s]=(s+256).toString(16).substr(1),o[a[s]]=s;function p(e,t){var n=t||0,r=a;return r[e[n++]]+r[e[n++]]+r[e[n++]]+r[e[n++]]+"-"+r[e[n++]]+r[e[n++]]+"-"+r[e[n++]]+r[e[n++]]+"-"+r[e[n++]]+r[e[n++]]+"-"+r[e[n++]]+r[e[n++]]+r[e[n++]]+r[e[n++]]+r[e[n++]]+r[e[n++]]}var l=i(),f=[1|l[0],l[1],l[2],l[3],l[4],l[5]],h=16383&(l[6]<<8|l[7]),b=0,g=0;function c(e,t,n){var r=t&&n||0;"string"==typeof e&&(t="binary"==e?new u(16):null,e=null);var a=(e=e||{}).random||(e.rng||i)();if(a[6]=15&a[6]|64,a[8]=63&a[8]|128,t)for(var o=0;o<16;o++)t[r+o]=a[o];return t||p(a)}(Fe=c).v1=function(e,t,n){var r=t&&n||0,a=t||[],o=null!=(e=e||{}).clockseq?e.clockseq:h,i=null!=e.msecs?e.msecs:(new Date).getTime(),u=null!=e.nsecs?e.nsecs:g+1,s=i-b+(u-g)/1e4;if(s<0&&null==e.clockseq&&(o=o+1&16383),(s<0||b<i)&&null==e.nsecs&&(u=0),1e4<=u)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");b=i,h=o;var l=(1e4*(268435455&(i+=122192928e5))+(g=u))%4294967296;a[r++]=l>>>24&255,a[r++]=l>>>16&255,a[r++]=l>>>8&255,a[r++]=255&l;var c=i/4294967296*1e4&268435455;a[r++]=c>>>8&255,a[r++]=255&c,a[r++]=c>>>24&15|16,a[r++]=c>>>16&255,a[r++]=o>>>8|128,a[r++]=255&o;for(var d=e.node||f,m=0;m<6;m++)a[r+m]=d[m];return t||p(a)},Fe.v4=c,Fe.parse=function(e,t,n){var r=t&&n||0,a=0;for(t=t||[],e.toLowerCase().replace(/[0-9a-f]{2}/g,function(e){a<16&&(t[r+a++]=o[e])});a<16;)t[r+a++]=0;return t},Fe.unparse=p,Fe.BufferClass=u}(window),axe.utils.validInputTypes=function(){"use strict";return["hidden","text","search","tel","url","email","password","date","month","week","time","datetime-local","number","range","color","checkbox","radio","file","submit","image","reset","button"]};var Ie=["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da","de","dv","dz","ee","el","en","eo","es","et","eu","fa","ff","fi","fj","fo","fr","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik","in","io","is","it","iu","iw","ja","ji","jv","jw","ka","kg","ki","kj","kk","kl","km","kn","ko","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml","mn","mo","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","pl","ps","pt","qu","rm","rn","ro","ru","rw","sa","sc","sd","se","sg","sh","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur","uz","ve","vi","vo","wa","wo","xh","yi","yo","za","zh","zu","aaa","aab","aac","aad","aae","aaf","aag","aah","aai","aak","aal","aam","aan","aao","aap","aaq","aas","aat","aau","aav","aaw","aax","aaz","aba","abb","abc","abd","abe","abf","abg","abh","abi","abj","abl","abm","abn","abo","abp","abq","abr","abs","abt","abu","abv","abw","abx","aby","abz","aca","acb","acd","ace","acf","ach","aci","ack","acl","acm","acn","acp","acq","acr","acs","act","acu","acv","acw","acx","acy","acz","ada","adb","add","ade","adf","adg","adh","adi","adj","adl","adn","ado","adp","adq","adr","ads","adt","adu","adw","adx","ady","adz","aea","aeb","aec","aed","aee","aek","ael","aem","aen","aeq","aer","aes","aeu","aew","aey","aez","afa","afb","afd","afe","afg","afh","afi","afk","afn","afo","afp","afs","aft","afu","afz","aga","agb","agc","agd","age","agf","agg","agh","agi","agj","agk","agl","agm","agn","ago","agp","agq","agr","ags","agt","agu","agv","agw","agx","agy","agz","aha","ahb","ahg","ahh","ahi","ahk","ahl","ahm","ahn","aho","ahp","ahr","ahs","aht","aia","aib","aic","aid","aie","aif","aig","aih","aii","aij","aik","ail","aim","ain","aio","aip","aiq","air","ais","ait","aiw","aix","aiy","aja","ajg","aji","ajn","ajp","ajt","aju","ajw","ajz","akb","akc","akd","ake","akf","akg","akh","aki","akj","akk","akl","akm","ako","akp","akq","akr","aks","akt","aku","akv","akw","akx","aky","akz","ala","alc","ald","ale","alf","alg","alh","ali","alj","alk","all","alm","aln","alo","alp","alq","alr","als","alt","alu","alv","alw","alx","aly","alz","ama","amb","amc","ame","amf","amg","ami","amj","amk","aml","amm","amn","amo","amp","amq","amr","ams","amt","amu","amv","amw","amx","amy","amz","ana","anb","anc","and","ane","anf","ang","anh","ani","anj","ank","anl","anm","ann","ano","anp","anq","anr","ans","ant","anu","anv","anw","anx","any","anz","aoa","aob","aoc","aod","aoe","aof","aog","aoh","aoi","aoj","aok","aol","aom","aon","aor","aos","aot","aou","aox","aoz","apa","apb","apc","apd","ape","apf","apg","aph","api","apj","apk","apl","apm","apn","apo","app","apq","apr","aps","apt","apu","apv","apw","apx","apy","apz","aqa","aqc","aqd","aqg","aql","aqm","aqn","aqp","aqr","aqt","aqz","arb","arc","ard","are","arh","ari","arj","ark","arl","arn","aro","arp","arq","arr","ars","art","aru","arv","arw","arx","ary","arz","asa","asb","asc","asd","ase","asf","asg","ash","asi","asj","ask","asl","asn","aso","asp","asq","asr","ass","ast","asu","asv","asw","asx","asy","asz","ata","atb","atc","atd","ate","atg","ath","ati","atj","atk","atl","atm","atn","ato","atp","atq","atr","ats","att","atu","atv","atw","atx","aty","atz","aua","aub","auc","aud","aue","auf","aug","auh","aui","auj","auk","aul","aum","aun","auo","aup","auq","aur","aus","aut","auu","auw","aux","auy","auz","avb","avd","avi","avk","avl","avm","avn","avo","avs","avt","avu","avv","awa","awb","awc","awd","awe","awg","awh","awi","awk","awm","awn","awo","awr","aws","awt","awu","awv","aww","awx","awy","axb","axe","axg","axk","axl","axm","axx","aya","ayb","ayc","ayd","aye","ayg","ayh","ayi","ayk","ayl","ayn","ayo","ayp","ayq","ayr","ays","ayt","ayu","ayx","ayy","ayz","aza","azb","azc","azd","azg","azj","azm","azn","azo","azt","azz","baa","bab","bac","bad","bae","baf","bag","bah","bai","baj","bal","ban","bao","bap","bar","bas","bat","bau","bav","baw","bax","bay","baz","bba","bbb","bbc","bbd","bbe","bbf","bbg","bbh","bbi","bbj","bbk","bbl","bbm","bbn","bbo","bbp","bbq","bbr","bbs","bbt","bbu","bbv","bbw","bbx","bby","bbz","bca","bcb","bcc","bcd","bce","bcf","bcg","bch","bci","bcj","bck","bcl","bcm","bcn","bco","bcp","bcq","bcr","bcs","bct","bcu","bcv","bcw","bcy","bcz","bda","bdb","bdc","bdd","bde","bdf","bdg","bdh","bdi","bdj","bdk","bdl","bdm","bdn","bdo","bdp","bdq","bdr","bds","bdt","bdu","bdv","bdw","bdx","bdy","bdz","bea","beb","bec","bed","bee","bef","beg","beh","bei","bej","bek","bem","beo","bep","beq","ber","bes","bet","beu","bev","bew","bex","bey","bez","bfa","bfb","bfc","bfd","bfe","bff","bfg","bfh","bfi","bfj","bfk","bfl","bfm","bfn","bfo","bfp","bfq","bfr","bfs","bft","bfu","bfw","bfx","bfy","bfz","bga","bgb","bgc","bgd","bge","bgf","bgg","bgi","bgj","bgk","bgl","bgm","bgn","bgo","bgp","bgq","bgr","bgs","bgt","bgu","bgv","bgw","bgx","bgy","bgz","bha","bhb","bhc","bhd","bhe","bhf","bhg","bhh","bhi","bhj","bhk","bhl","bhm","bhn","bho","bhp","bhq","bhr","bhs","bht","bhu","bhv","bhw","bhx","bhy","bhz","bia","bib","bic","bid","bie","bif","big","bij","bik","bil","bim","bin","bio","bip","biq","bir","bit","biu","biv","biw","bix","biy","biz","bja","bjb","bjc","bjd","bje","bjf","bjg","bjh","bji","bjj","bjk","bjl","bjm","bjn","bjo","bjp","bjq","bjr","bjs","bjt","bju","bjv","bjw","bjx","bjy","bjz","bka","bkb","bkc","bkd","bkf","bkg","bkh","bki","bkj","bkk","bkl","bkm","bkn","bko","bkp","bkq","bkr","bks","bkt","bku","bkv","bkw","bkx","bky","bkz","bla","blb","blc","bld","ble","blf","blg","blh","bli","blj","blk","bll","blm","bln","blo","blp","blq","blr","bls","blt","blv","blw","blx","bly","blz","bma","bmb","bmc","bmd","bme","bmf","bmg","bmh","bmi","bmj","bmk","bml","bmm","bmn","bmo","bmp","bmq","bmr","bms","bmt","bmu","bmv","bmw","bmx","bmy","bmz","bna","bnb","bnc","bnd","bne","bnf","bng","bni","bnj","bnk","bnl","bnm","bnn","bno","bnp","bnq","bnr","bns","bnt","bnu","bnv","bnw","bnx","bny","bnz","boa","bob","boe","bof","bog","boh","boi","boj","bok","bol","bom","bon","boo","bop","boq","bor","bot","bou","bov","bow","box","boy","boz","bpa","bpb","bpd","bpg","bph","bpi","bpj","bpk","bpl","bpm","bpn","bpo","bpp","bpq","bpr","bps","bpt","bpu","bpv","bpw","bpx","bpy","bpz","bqa","bqb","bqc","bqd","bqf","bqg","bqh","bqi","bqj","bqk","bql","bqm","bqn","bqo","bqp","bqq","bqr","bqs","bqt","bqu","bqv","bqw","bqx","bqy","bqz","bra","brb","brc","brd","brf","brg","brh","bri","brj","brk","brl","brm","brn","bro","brp","brq","brr","brs","brt","bru","brv","brw","brx","bry","brz","bsa","bsb","bsc","bse","bsf","bsg","bsh","bsi","bsj","bsk","bsl","bsm","bsn","bso","bsp","bsq","bsr","bss","bst","bsu","bsv","bsw","bsx","bsy","bta","btb","btc","btd","bte","btf","btg","bth","bti","btj","btk","btl","btm","btn","bto","btp","btq","btr","bts","btt","btu","btv","btw","btx","bty","btz","bua","bub","buc","bud","bue","buf","bug","buh","bui","buj","buk","bum","bun","buo","bup","buq","bus","but","buu","buv","buw","bux","buy","buz","bva","bvb","bvc","bvd","bve","bvf","bvg","bvh","bvi","bvj","bvk","bvl","bvm","bvn","bvo","bvp","bvq","bvr","bvt","bvu","bvv","bvw","bvx","bvy","bvz","bwa","bwb","bwc","bwd","bwe","bwf","bwg","bwh","bwi","bwj","bwk","bwl","bwm","bwn","bwo","bwp","bwq","bwr","bws","bwt","bwu","bww","bwx","bwy","bwz","bxa","bxb","bxc","bxd","bxe","bxf","bxg","bxh","bxi","bxj","bxk","bxl","bxm","bxn","bxo","bxp","bxq","bxr","bxs","bxu","bxv","bxw","bxx","bxz","bya","byb","byc","byd","bye","byf","byg","byh","byi","byj","byk","byl","bym","byn","byo","byp","byq","byr","bys","byt","byv","byw","byx","byy","byz","bza","bzb","bzc","bzd","bze","bzf","bzg","bzh","bzi","bzj","bzk","bzl","bzm","bzn","bzo","bzp","bzq","bzr","bzs","bzt","bzu","bzv","bzw","bzx","bzy","bzz","caa","cab","cac","cad","cae","caf","cag","cah","cai","caj","cak","cal","cam","can","cao","cap","caq","car","cas","cau","cav","caw","cax","cay","caz","cba","cbb","cbc","cbd","cbe","cbg","cbh","cbi","cbj","cbk","cbl","cbn","cbo","cbq","cbr","cbs","cbt","cbu","cbv","cbw","cby","cca","ccc","ccd","cce","ccg","cch","ccj","ccl","ccm","ccn","cco","ccp","ccq","ccr","ccs","cda","cdc","cdd","cde","cdf","cdg","cdh","cdi","cdj","cdm","cdn","cdo","cdr","cds","cdy","cdz","cea","ceb","ceg","cek","cel","cen","cet","cfa","cfd","cfg","cfm","cga","cgc","cgg","cgk","chb","chc","chd","chf","chg","chh","chj","chk","chl","chm","chn","cho","chp","chq","chr","cht","chw","chx","chy","chz","cia","cib","cic","cid","cie","cih","cik","cim","cin","cip","cir","ciw","ciy","cja","cje","cjh","cji","cjk","cjm","cjn","cjo","cjp","cjr","cjs","cjv","cjy","cka","ckb","ckh","ckl","ckn","cko","ckq","ckr","cks","ckt","cku","ckv","ckx","cky","ckz","cla","clc","cld","cle","clh","cli","clj","clk","cll","clm","clo","clt","clu","clw","cly","cma","cmc","cme","cmg","cmi","cmk","cml","cmm","cmn","cmo","cmr","cms","cmt","cna","cnb","cnc","cng","cnh","cni","cnk","cnl","cno","cnr","cns","cnt","cnu","cnw","cnx","coa","cob","coc","cod","coe","cof","cog","coh","coj","cok","col","com","con","coo","cop","coq","cot","cou","cov","cow","cox","coy","coz","cpa","cpb","cpc","cpe","cpf","cpg","cpi","cpn","cpo","cpp","cps","cpu","cpx","cpy","cqd","cqu","cra","crb","crc","crd","crf","crg","crh","cri","crj","crk","crl","crm","crn","cro","crp","crq","crr","crs","crt","crv","crw","crx","cry","crz","csa","csb","csc","csd","cse","csf","csg","csh","csi","csj","csk","csl","csm","csn","cso","csq","csr","css","cst","csu","csv","csw","csy","csz","cta","ctc","ctd","cte","ctg","cth","ctl","ctm","ctn","cto","ctp","cts","ctt","ctu","ctz","cua","cub","cuc","cug","cuh","cui","cuj","cuk","cul","cum","cuo","cup","cuq","cur","cus","cut","cuu","cuv","cuw","cux","cuy","cvg","cvn","cwa","cwb","cwd","cwe","cwg","cwt","cya","cyb","cyo","czh","czk","czn","czo","czt","daa","dac","dad","dae","daf","dag","dah","dai","daj","dak","dal","dam","dao","dap","daq","dar","das","dau","dav","daw","dax","day","daz","dba","dbb","dbd","dbe","dbf","dbg","dbi","dbj","dbl","dbm","dbn","dbo","dbp","dbq","dbr","dbt","dbu","dbv","dbw","dby","dcc","dcr","dda","ddd","dde","ddg","ddi","ddj","ddn","ddo","ddr","dds","ddw","dec","ded","dee","def","deg","deh","dei","dek","del","dem","den","dep","deq","der","des","dev","dez","dga","dgb","dgc","dgd","dge","dgg","dgh","dgi","dgk","dgl","dgn","dgo","dgr","dgs","dgt","dgu","dgw","dgx","dgz","dha","dhd","dhg","dhi","dhl","dhm","dhn","dho","dhr","dhs","dhu","dhv","dhw","dhx","dia","dib","dic","did","dif","dig","dih","dii","dij","dik","dil","dim","din","dio","dip","diq","dir","dis","dit","diu","diw","dix","diy","diz","dja","djb","djc","djd","dje","djf","dji","djj","djk","djl","djm","djn","djo","djr","dju","djw","dka","dkk","dkl","dkr","dks","dkx","dlg","dlk","dlm","dln","dma","dmb","dmc","dmd","dme","dmg","dmk","dml","dmm","dmn","dmo","dmr","dms","dmu","dmv","dmw","dmx","dmy","dna","dnd","dne","dng","dni","dnj","dnk","dnn","dnr","dnt","dnu","dnv","dnw","dny","doa","dob","doc","doe","dof","doh","doi","dok","dol","don","doo","dop","doq","dor","dos","dot","dov","dow","dox","doy","doz","dpp","dra","drb","drc","drd","dre","drg","drh","dri","drl","drn","dro","drq","drr","drs","drt","dru","drw","dry","dsb","dse","dsh","dsi","dsl","dsn","dso","dsq","dta","dtb","dtd","dth","dti","dtk","dtm","dtn","dto","dtp","dtr","dts","dtt","dtu","dty","dua","dub","duc","dud","due","duf","dug","duh","dui","duj","duk","dul","dum","dun","duo","dup","duq","dur","dus","duu","duv","duw","dux","duy","duz","dva","dwa","dwl","dwr","dws","dwu","dww","dwy","dya","dyb","dyd","dyg","dyi","dym","dyn","dyo","dyu","dyy","dza","dzd","dze","dzg","dzl","dzn","eaa","ebg","ebk","ebo","ebr","ebu","ecr","ecs","ecy","eee","efa","efe","efi","ega","egl","ego","egx","egy","ehu","eip","eit","eiv","eja","eka","ekc","eke","ekg","eki","ekk","ekl","ekm","eko","ekp","ekr","eky","ele","elh","eli","elk","elm","elo","elp","elu","elx","ema","emb","eme","emg","emi","emk","emm","emn","emo","emp","ems","emu","emw","emx","emy","ena","enb","enc","end","enf","enh","enl","enm","enn","eno","enq","enr","enu","env","enw","enx","eot","epi","era","erg","erh","eri","erk","ero","err","ers","ert","erw","ese","esg","esh","esi","esk","esl","esm","esn","eso","esq","ess","esu","esx","esy","etb","etc","eth","etn","eto","etr","ets","ett","etu","etx","etz","euq","eve","evh","evn","ewo","ext","eya","eyo","eza","eze","faa","fab","fad","faf","fag","fah","fai","faj","fak","fal","fam","fan","fap","far","fat","fau","fax","fay","faz","fbl","fcs","fer","ffi","ffm","fgr","fia","fie","fil","fip","fir","fit","fiu","fiw","fkk","fkv","fla","flh","fli","fll","fln","flr","fly","fmp","fmu","fnb","fng","fni","fod","foi","fom","fon","for","fos","fox","fpe","fqs","frc","frd","frk","frm","fro","frp","frq","frr","frs","frt","fse","fsl","fss","fub","fuc","fud","fue","fuf","fuh","fui","fuj","fum","fun","fuq","fur","fut","fuu","fuv","fuy","fvr","fwa","fwe","gaa","gab","gac","gad","gae","gaf","gag","gah","gai","gaj","gak","gal","gam","gan","gao","gap","gaq","gar","gas","gat","gau","gav","gaw","gax","gay","gaz","gba","gbb","gbc","gbd","gbe","gbf","gbg","gbh","gbi","gbj","gbk","gbl","gbm","gbn","gbo","gbp","gbq","gbr","gbs","gbu","gbv","gbw","gbx","gby","gbz","gcc","gcd","gce","gcf","gcl","gcn","gcr","gct","gda","gdb","gdc","gdd","gde","gdf","gdg","gdh","gdi","gdj","gdk","gdl","gdm","gdn","gdo","gdq","gdr","gds","gdt","gdu","gdx","gea","geb","gec","ged","geg","geh","gei","gej","gek","gel","gem","geq","ges","gev","gew","gex","gey","gez","gfk","gft","gfx","gga","ggb","ggd","gge","ggg","ggk","ggl","ggn","ggo","ggr","ggt","ggu","ggw","gha","ghc","ghe","ghh","ghk","ghl","ghn","gho","ghr","ghs","ght","gia","gib","gic","gid","gie","gig","gih","gil","gim","gin","gio","gip","giq","gir","gis","git","giu","giw","gix","giy","giz","gji","gjk","gjm","gjn","gjr","gju","gka","gkd","gke","gkn","gko","gkp","gku","glc","gld","glh","gli","glj","glk","gll","glo","glr","glu","glw","gly","gma","gmb","gmd","gme","gmg","gmh","gml","gmm","gmn","gmq","gmu","gmv","gmw","gmx","gmy","gmz","gna","gnb","gnc","gnd","gne","gng","gnh","gni","gnj","gnk","gnl","gnm","gnn","gno","gnq","gnr","gnt","gnu","gnw","gnz","goa","gob","goc","god","goe","gof","gog","goh","goi","goj","gok","gol","gom","gon","goo","gop","goq","gor","gos","got","gou","gow","gox","goy","goz","gpa","gpe","gpn","gqa","gqi","gqn","gqr","gqu","gra","grb","grc","grd","grg","grh","gri","grj","grk","grm","gro","grq","grr","grs","grt","gru","grv","grw","grx","gry","grz","gse","gsg","gsl","gsm","gsn","gso","gsp","gss","gsw","gta","gti","gtu","gua","gub","guc","gud","gue","guf","gug","guh","gui","guk","gul","gum","gun","guo","gup","guq","gur","gus","gut","guu","guv","guw","gux","guz","gva","gvc","gve","gvf","gvj","gvl","gvm","gvn","gvo","gvp","gvr","gvs","gvy","gwa","gwb","gwc","gwd","gwe","gwf","gwg","gwi","gwj","gwm","gwn","gwr","gwt","gwu","gww","gwx","gxx","gya","gyb","gyd","gye","gyf","gyg","gyi","gyl","gym","gyn","gyo","gyr","gyy","gza","gzi","gzn","haa","hab","hac","had","hae","haf","hag","hah","hai","haj","hak","hal","ham","han","hao","hap","haq","har","has","hav","haw","hax","hay","haz","hba","hbb","hbn","hbo","hbu","hca","hch","hdn","hds","hdy","hea","hed","heg","heh","hei","hem","hgm","hgw","hhi","hhr","hhy","hia","hib","hid","hif","hig","hih","hii","hij","hik","hil","him","hio","hir","hit","hiw","hix","hji","hka","hke","hkk","hkn","hks","hla","hlb","hld","hle","hlt","hlu","hma","hmb","hmc","hmd","hme","hmf","hmg","hmh","hmi","hmj","hmk","hml","hmm","hmn","hmp","hmq","hmr","hms","hmt","hmu","hmv","hmw","hmx","hmy","hmz","hna","hnd","hne","hnh","hni","hnj","hnn","hno","hns","hnu","hoa","hob","hoc","hod","hoe","hoh","hoi","hoj","hok","hol","hom","hoo","hop","hor","hos","hot","hov","how","hoy","hoz","hpo","hps","hra","hrc","hre","hrk","hrm","hro","hrp","hrr","hrt","hru","hrw","hrx","hrz","hsb","hsh","hsl","hsn","hss","hti","hto","hts","htu","htx","hub","huc","hud","hue","huf","hug","huh","hui","huj","huk","hul","hum","huo","hup","huq","hur","hus","hut","huu","huv","huw","hux","huy","huz","hvc","hve","hvk","hvn","hvv","hwa","hwc","hwo","hya","hyw","hyx","iai","ian","iap","iar","iba","ibb","ibd","ibe","ibg","ibh","ibi","ibl","ibm","ibn","ibr","ibu","iby","ica","ich","icl","icr","ida","idb","idc","idd","ide","idi","idr","ids","idt","idu","ifa","ifb","ife","iff","ifk","ifm","ifu","ify","igb","ige","igg","igl","igm","ign","igo","igs","igw","ihb","ihi","ihp","ihw","iin","iir","ijc","ije","ijj","ijn","ijo","ijs","ike","iki","ikk","ikl","iko","ikp","ikr","iks","ikt","ikv","ikw","ikx","ikz","ila","ilb","ilg","ili","ilk","ill","ilm","ilo","ilp","ils","ilu","ilv","ilw","ima","ime","imi","iml","imn","imo","imr","ims","imy","inb","inc","ine","ing","inh","inj","inl","inm","inn","ino","inp","ins","int","inz","ior","iou","iow","ipi","ipo","iqu","iqw","ira","ire","irh","iri","irk","irn","iro","irr","iru","irx","iry","isa","isc","isd","ise","isg","ish","isi","isk","ism","isn","iso","isr","ist","isu","itb","itc","itd","ite","iti","itk","itl","itm","ito","itr","its","itt","itv","itw","itx","ity","itz","ium","ivb","ivv","iwk","iwm","iwo","iws","ixc","ixl","iya","iyo","iyx","izh","izi","izr","izz","jaa","jab","jac","jad","jae","jaf","jah","jaj","jak","jal","jam","jan","jao","jaq","jar","jas","jat","jau","jax","jay","jaz","jbe","jbi","jbj","jbk","jbn","jbo","jbr","jbt","jbu","jbw","jcs","jct","jda","jdg","jdt","jeb","jee","jeg","jeh","jei","jek","jel","jen","jer","jet","jeu","jgb","jge","jgk","jgo","jhi","jhs","jia","jib","jic","jid","jie","jig","jih","jii","jil","jim","jio","jiq","jit","jiu","jiv","jiy","jje","jjr","jka","jkm","jko","jkp","jkr","jku","jle","jls","jma","jmb","jmc","jmd","jmi","jml","jmn","jmr","jms","jmw","jmx","jna","jnd","jng","jni","jnj","jnl","jns","job","jod","jog","jor","jos","jow","jpa","jpr","jpx","jqr","jra","jrb","jrr","jrt","jru","jsl","jua","jub","juc","jud","juh","jui","juk","jul","jum","jun","juo","jup","jur","jus","jut","juu","juw","juy","jvd","jvn","jwi","jya","jye","jyy","kaa","kab","kac","kad","kae","kaf","kag","kah","kai","kaj","kak","kam","kao","kap","kaq","kar","kav","kaw","kax","kay","kba","kbb","kbc","kbd","kbe","kbf","kbg","kbh","kbi","kbj","kbk","kbl","kbm","kbn","kbo","kbp","kbq","kbr","kbs","kbt","kbu","kbv","kbw","kbx","kby","kbz","kca","kcb","kcc","kcd","kce","kcf","kcg","kch","kci","kcj","kck","kcl","kcm","kcn","kco","kcp","kcq","kcr","kcs","kct","kcu","kcv","kcw","kcx","kcy","kcz","kda","kdc","kdd","kde","kdf","kdg","kdh","kdi","kdj","kdk","kdl","kdm","kdn","kdo","kdp","kdq","kdr","kdt","kdu","kdv","kdw","kdx","kdy","kdz","kea","keb","kec","ked","kee","kef","keg","keh","kei","kej","kek","kel","kem","ken","keo","kep","keq","ker","kes","ket","keu","kev","kew","kex","key","kez","kfa","kfb","kfc","kfd","kfe","kff","kfg","kfh","kfi","kfj","kfk","kfl","kfm","kfn","kfo","kfp","kfq","kfr","kfs","kft","kfu","kfv","kfw","kfx","kfy","kfz","kga","kgb","kgc","kgd","kge","kgf","kgg","kgh","kgi","kgj","kgk","kgl","kgm","kgn","kgo","kgp","kgq","kgr","kgs","kgt","kgu","kgv","kgw","kgx","kgy","kha","khb","khc","khd","khe","khf","khg","khh","khi","khj","khk","khl","khn","kho","khp","khq","khr","khs","kht","khu","khv","khw","khx","khy","khz","kia","kib","kic","kid","kie","kif","kig","kih","kii","kij","kil","kim","kio","kip","kiq","kis","kit","kiu","kiv","kiw","kix","kiy","kiz","kja","kjb","kjc","kjd","kje","kjf","kjg","kjh","kji","kjj","kjk","kjl","kjm","kjn","kjo","kjp","kjq","kjr","kjs","kjt","kju","kjv","kjx","kjy","kjz","kka","kkb","kkc","kkd","kke","kkf","kkg","kkh","kki","kkj","kkk","kkl","kkm","kkn","kko","kkp","kkq","kkr","kks","kkt","kku","kkv","kkw","kkx","kky","kkz","kla","klb","klc","kld","kle","klf","klg","klh","kli","klj","klk","kll","klm","kln","klo","klp","klq","klr","kls","klt","klu","klv","klw","klx","kly","klz","kma","kmb","kmc","kmd","kme","kmf","kmg","kmh","kmi","kmj","kmk","kml","kmm","kmn","kmo","kmp","kmq","kmr","kms","kmt","kmu","kmv","kmw","kmx","kmy","kmz","kna","knb","knc","knd","kne","knf","kng","kni","knj","knk","knl","knm","knn","kno","knp","knq","knr","kns","knt","knu","knv","knw","knx","kny","knz","koa","koc","kod","koe","kof","kog","koh","koi","koj","kok","kol","koo","kop","koq","kos","kot","kou","kov","kow","kox","koy","koz","kpa","kpb","kpc","kpd","kpe","kpf","kpg","kph","kpi","kpj","kpk","kpl","kpm","kpn","kpo","kpp","kpq","kpr","kps","kpt","kpu","kpv","kpw","kpx","kpy","kpz","kqa","kqb","kqc","kqd","kqe","kqf","kqg","kqh","kqi","kqj","kqk","kql","kqm","kqn","kqo","kqp","kqq","kqr","kqs","kqt","kqu","kqv","kqw","kqx","kqy","kqz","kra","krb","krc","krd","kre","krf","krh","kri","krj","krk","krl","krm","krn","kro","krp","krr","krs","krt","kru","krv","krw","krx","kry","krz","ksa","ksb","ksc","ksd","kse","ksf","ksg","ksh","ksi","ksj","ksk","ksl","ksm","ksn","kso","ksp","ksq","ksr","kss","kst","ksu","ksv","ksw","ksx","ksy","ksz","kta","ktb","ktc","ktd","kte","ktf","ktg","kth","kti","ktj","ktk","ktl","ktm","ktn","kto","ktp","ktq","ktr","kts","ktt","ktu","ktv","ktw","ktx","kty","ktz","kub","kuc","kud","kue","kuf","kug","kuh","kui","kuj","kuk","kul","kum","kun","kuo","kup","kuq","kus","kut","kuu","kuv","kuw","kux","kuy","kuz","kva","kvb","kvc","kvd","kve","kvf","kvg","kvh","kvi","kvj","kvk","kvl","kvm","kvn","kvo","kvp","kvq","kvr","kvs","kvt","kvu","kvv","kvw","kvx","kvy","kvz","kwa","kwb","kwc","kwd","kwe","kwf","kwg","kwh","kwi","kwj","kwk","kwl","kwm","kwn","kwo","kwp","kwq","kwr","kws","kwt","kwu","kwv","kww","kwx","kwy","kwz","kxa","kxb","kxc","kxd","kxe","kxf","kxh","kxi","kxj","kxk","kxl","kxm","kxn","kxo","kxp","kxq","kxr","kxs","kxt","kxu","kxv","kxw","kxx","kxy","kxz","kya","kyb","kyc","kyd","kye","kyf","kyg","kyh","kyi","kyj","kyk","kyl","kym","kyn","kyo","kyp","kyq","kyr","kys","kyt","kyu","kyv","kyw","kyx","kyy","kyz","kza","kzb","kzc","kzd","kze","kzf","kzg","kzh","kzi","kzj","kzk","kzl","kzm","kzn","kzo","kzp","kzq","kzr","kzs","kzt","kzu","kzv","kzw","kzx","kzy","kzz","laa","lab","lac","lad","lae","laf","lag","lah","lai","laj","lak","lal","lam","lan","lap","laq","lar","las","lau","law","lax","lay","laz","lba","lbb","lbc","lbe","lbf","lbg","lbi","lbj","lbk","lbl","lbm","lbn","lbo","lbq","lbr","lbs","lbt","lbu","lbv","lbw","lbx","lby","lbz","lcc","lcd","lce","lcf","lch","lcl","lcm","lcp","lcq","lcs","lda","ldb","ldd","ldg","ldh","ldi","ldj","ldk","ldl","ldm","ldn","ldo","ldp","ldq","lea","leb","lec","led","lee","lef","leg","leh","lei","lej","lek","lel","lem","len","leo","lep","leq","ler","les","let","leu","lev","lew","lex","ley","lez","lfa","lfn","lga","lgb","lgg","lgh","lgi","lgk","lgl","lgm","lgn","lgq","lgr","lgt","lgu","lgz","lha","lhh","lhi","lhl","lhm","lhn","lhp","lhs","lht","lhu","lia","lib","lic","lid","lie","lif","lig","lih","lii","lij","lik","lil","lio","lip","liq","lir","lis","liu","liv","liw","lix","liy","liz","lja","lje","lji","ljl","ljp","ljw","ljx","lka","lkb","lkc","lkd","lke","lkh","lki","lkj","lkl","lkm","lkn","lko","lkr","lks","lkt","lku","lky","lla","llb","llc","lld","lle","llf","llg","llh","lli","llj","llk","lll","llm","lln","llo","llp","llq","lls","llu","llx","lma","lmb","lmc","lmd","lme","lmf","lmg","lmh","lmi","lmj","lmk","lml","lmm","lmn","lmo","lmp","lmq","lmr","lmu","lmv","lmw","lmx","lmy","lmz","lna","lnb","lnd","lng","lnh","lni","lnj","lnl","lnm","lnn","lno","lns","lnu","lnw","lnz","loa","lob","loc","loe","lof","log","loh","loi","loj","lok","lol","lom","lon","loo","lop","loq","lor","los","lot","lou","lov","low","lox","loy","loz","lpa","lpe","lpn","lpo","lpx","lra","lrc","lre","lrg","lri","lrk","lrl","lrm","lrn","lro","lrr","lrt","lrv","lrz","lsa","lsd","lse","lsg","lsh","lsi","lsl","lsm","lso","lsp","lsr","lss","lst","lsy","ltc","ltg","lth","lti","ltn","lto","lts","ltu","lua","luc","lud","lue","luf","lui","luj","luk","lul","lum","lun","luo","lup","luq","lur","lus","lut","luu","luv","luw","luy","luz","lva","lvk","lvs","lvu","lwa","lwe","lwg","lwh","lwl","lwm","lwo","lws","lwt","lwu","lww","lya","lyg","lyn","lzh","lzl","lzn","lzz","maa","mab","mad","mae","maf","mag","mai","maj","mak","mam","man","map","maq","mas","mat","mau","mav","maw","max","maz","mba","mbb","mbc","mbd","mbe","mbf","mbh","mbi","mbj","mbk","mbl","mbm","mbn","mbo","mbp","mbq","mbr","mbs","mbt","mbu","mbv","mbw","mbx","mby","mbz","mca","mcb","mcc","mcd","mce","mcf","mcg","mch","mci","mcj","mck","mcl","mcm","mcn","mco","mcp","mcq","mcr","mcs","mct","mcu","mcv","mcw","mcx","mcy","mcz","mda","mdb","mdc","mdd","mde","mdf","mdg","mdh","mdi","mdj","mdk","mdl","mdm","mdn","mdp","mdq","mdr","mds","mdt","mdu","mdv","mdw","mdx","mdy","mdz","mea","meb","mec","med","mee","mef","meg","meh","mei","mej","mek","mel","mem","men","meo","mep","meq","mer","mes","met","meu","mev","mew","mey","mez","mfa","mfb","mfc","mfd","mfe","mff","mfg","mfh","mfi","mfj","mfk","mfl","mfm","mfn","mfo","mfp","mfq","mfr","mfs","mft","mfu","mfv","mfw","mfx","mfy","mfz","mga","mgb","mgc","mgd","mge","mgf","mgg","mgh","mgi","mgj","mgk","mgl","mgm","mgn","mgo","mgp","mgq","mgr","mgs","mgt","mgu","mgv","mgw","mgx","mgy","mgz","mha","mhb","mhc","mhd","mhe","mhf","mhg","mhh","mhi","mhj","mhk","mhl","mhm","mhn","mho","mhp","mhq","mhr","mhs","mht","mhu","mhw","mhx","mhy","mhz","mia","mib","mic","mid","mie","mif","mig","mih","mii","mij","mik","mil","mim","min","mio","mip","miq","mir","mis","mit","miu","miw","mix","miy","miz","mja","mjb","mjc","mjd","mje","mjg","mjh","mji","mjj","mjk","mjl","mjm","mjn","mjo","mjp","mjq","mjr","mjs","mjt","mju","mjv","mjw","mjx","mjy","mjz","mka","mkb","mkc","mke","mkf","mkg","mkh","mki","mkj","mkk","mkl","mkm","mkn","mko","mkp","mkq","mkr","mks","mkt","mku","mkv","mkw","mkx","mky","mkz","mla","mlb","mlc","mld","mle","mlf","mlh","mli","mlj","mlk","mll","mlm","mln","mlo","mlp","mlq","mlr","mls","mlu","mlv","mlw","mlx","mlz","mma","mmb","mmc","mmd","mme","mmf","mmg","mmh","mmi","mmj","mmk","mml","mmm","mmn","mmo","mmp","mmq","mmr","mmt","mmu","mmv","mmw","mmx","mmy","mmz","mna","mnb","mnc","mnd","mne","mnf","mng","mnh","mni","mnj","mnk","mnl","mnm","mnn","mno","mnp","mnq","mnr","mns","mnt","mnu","mnv","mnw","mnx","mny","mnz","moa","moc","mod","moe","mof","mog","moh","moi","moj","mok","mom","moo","mop","moq","mor","mos","mot","mou","mov","mow","mox","moy","moz","mpa","mpb","mpc","mpd","mpe","mpg","mph","mpi","mpj","mpk","mpl","mpm","mpn","mpo","mpp","mpq","mpr","mps","mpt","mpu","mpv","mpw","mpx","mpy","mpz","mqa","mqb","mqc","mqe","mqf","mqg","mqh","mqi","mqj","mqk","mql","mqm","mqn","mqo","mqp","mqq","mqr","mqs","mqt","mqu","mqv","mqw","mqx","mqy","mqz","mra","mrb","mrc","mrd","mre","mrf","mrg","mrh","mrj","mrk","mrl","mrm","mrn","mro","mrp","mrq","mrr","mrs","mrt","mru","mrv","mrw","mrx","mry","mrz","msb","msc","msd","mse","msf","msg","msh","msi","msj","msk","msl","msm","msn","mso","msp","msq","msr","mss","mst","msu","msv","msw","msx","msy","msz","mta","mtb","mtc","mtd","mte","mtf","mtg","mth","mti","mtj","mtk","mtl","mtm","mtn","mto","mtp","mtq","mtr","mts","mtt","mtu","mtv","mtw","mtx","mty","mua","mub","muc","mud","mue","mug","muh","mui","muj","muk","mul","mum","mun","muo","mup","muq","mur","mus","mut","muu","muv","mux","muy","muz","mva","mvb","mvd","mve","mvf","mvg","mvh","mvi","mvk","mvl","mvm","mvn","mvo","mvp","mvq","mvr","mvs","mvt","mvu","mvv","mvw","mvx","mvy","mvz","mwa","mwb","mwc","mwd","mwe","mwf","mwg","mwh","mwi","mwj","mwk","mwl","mwm","mwn","mwo","mwp","mwq","mwr","mws","mwt","mwu","mwv","mww","mwx","mwy","mwz","mxa","mxb","mxc","mxd","mxe","mxf","mxg","mxh","mxi","mxj","mxk","mxl","mxm","mxn","mxo","mxp","mxq","mxr","mxs","mxt","mxu","mxv","mxw","mxx","mxy","mxz","myb","myc","myd","mye","myf","myg","myh","myi","myj","myk","myl","mym","myn","myo","myp","myq","myr","mys","myt","myu","myv","myw","myx","myy","myz","mza","mzb","mzc","mzd","mze","mzg","mzh","mzi","mzj","mzk","mzl","mzm","mzn","mzo","mzp","mzq","mzr","mzs","mzt","mzu","mzv","mzw","mzx","mzy","mzz","naa","nab","nac","nad","nae","naf","nag","nah","nai","naj","nak","nal","nam","nan","nao","nap","naq","nar","nas","nat","naw","nax","nay","naz","nba","nbb","nbc","nbd","nbe","nbf","nbg","nbh","nbi","nbj","nbk","nbm","nbn","nbo","nbp","nbq","nbr","nbs","nbt","nbu","nbv","nbw","nbx","nby","nca","ncb","ncc","ncd","nce","ncf","ncg","nch","nci","ncj","nck","ncl","ncm","ncn","nco","ncp","ncq","ncr","ncs","nct","ncu","ncx","ncz","nda","ndb","ndc","ndd","ndf","ndg","ndh","ndi","ndj","ndk","ndl","ndm","ndn","ndp","ndq","ndr","nds","ndt","ndu","ndv","ndw","ndx","ndy","ndz","nea","neb","nec","ned","nee","nef","neg","neh","nei","nej","nek","nem","nen","neo","neq","ner","nes","net","neu","nev","new","nex","ney","nez","nfa","nfd","nfl","nfr","nfu","nga","ngb","ngc","ngd","nge","ngf","ngg","ngh","ngi","ngj","ngk","ngl","ngm","ngn","ngo","ngp","ngq","ngr","ngs","ngt","ngu","ngv","ngw","ngx","ngy","ngz","nha","nhb","nhc","nhd","nhe","nhf","nhg","nhh","nhi","nhk","nhm","nhn","nho","nhp","nhq","nhr","nht","nhu","nhv","nhw","nhx","nhy","nhz","nia","nib","nic","nid","nie","nif","nig","nih","nii","nij","nik","nil","nim","nin","nio","niq","nir","nis","nit","niu","niv","niw","nix","niy","niz","nja","njb","njd","njh","nji","njj","njl","njm","njn","njo","njr","njs","njt","nju","njx","njy","njz","nka","nkb","nkc","nkd","nke","nkf","nkg","nkh","nki","nkj","nkk","nkm","nkn","nko","nkp","nkq","nkr","nks","nkt","nku","nkv","nkw","nkx","nkz","nla","nlc","nle","nlg","nli","nlj","nlk","nll","nlm","nln","nlo","nlq","nlr","nlu","nlv","nlw","nlx","nly","nlz","nma","nmb","nmc","nmd","nme","nmf","nmg","nmh","nmi","nmj","nmk","nml","nmm","nmn","nmo","nmp","nmq","nmr","nms","nmt","nmu","nmv","nmw","nmx","nmy","nmz","nna","nnb","nnc","nnd","nne","nnf","nng","nnh","nni","nnj","nnk","nnl","nnm","nnn","nnp","nnq","nnr","nns","nnt","nnu","nnv","nnw","nnx","nny","nnz","noa","noc","nod","noe","nof","nog","noh","noi","noj","nok","nol","nom","non","noo","nop","noq","nos","not","nou","nov","now","noy","noz","npa","npb","npg","nph","npi","npl","npn","npo","nps","npu","npx","npy","nqg","nqk","nql","nqm","nqn","nqo","nqq","nqy","nra","nrb","nrc","nre","nrf","nrg","nri","nrk","nrl","nrm","nrn","nrp","nrr","nrt","nru","nrx","nrz","nsa","nsc","nsd","nse","nsf","nsg","nsh","nsi","nsk","nsl","nsm","nsn","nso","nsp","nsq","nsr","nss","nst","nsu","nsv","nsw","nsx","nsy","nsz","ntd","nte","ntg","nti","ntj","ntk","ntm","nto","ntp","ntr","nts","ntu","ntw","ntx","nty","ntz","nua","nub","nuc","nud","nue","nuf","nug","nuh","nui","nuj","nuk","nul","num","nun","nuo","nup","nuq","nur","nus","nut","nuu","nuv","nuw","nux","nuy","nuz","nvh","nvm","nvo","nwa","nwb","nwc","nwe","nwg","nwi","nwm","nwo","nwr","nwx","nwy","nxa","nxd","nxe","nxg","nxi","nxk","nxl","nxm","nxn","nxo","nxq","nxr","nxu","nxx","nyb","nyc","nyd","nye","nyf","nyg","nyh","nyi","nyj","nyk","nyl","nym","nyn","nyo","nyp","nyq","nyr","nys","nyt","nyu","nyv","nyw","nyx","nyy","nza","nzb","nzd","nzi","nzk","nzm","nzs","nzu","nzy","nzz","oaa","oac","oar","oav","obi","obk","obl","obm","obo","obr","obt","obu","oca","och","oco","ocu","oda","odk","odt","odu","ofo","ofs","ofu","ogb","ogc","oge","ogg","ogo","ogu","oht","ohu","oia","oin","ojb","ojc","ojg","ojp","ojs","ojv","ojw","oka","okb","okd","oke","okg","okh","oki","okj","okk","okl","okm","okn","oko","okr","oks","oku","okv","okx","ola","old","ole","olk","olm","olo","olr","olt","olu","oma","omb","omc","ome","omg","omi","omk","oml","omn","omo","omp","omq","omr","omt","omu","omv","omw","omx","ona","onb","one","ong","oni","onj","onk","onn","ono","onp","onr","ons","ont","onu","onw","onx","ood","oog","oon","oor","oos","opa","opk","opm","opo","opt","opy","ora","orc","ore","org","orh","orn","oro","orr","ors","ort","oru","orv","orw","orx","ory","orz","osa","osc","osi","oso","osp","ost","osu","osx","ota","otb","otd","ote","oti","otk","otl","otm","otn","oto","otq","otr","ots","ott","otu","otw","otx","oty","otz","oua","oub","oue","oui","oum","oun","ovd","owi","owl","oyb","oyd","oym","oyy","ozm","paa","pab","pac","pad","pae","paf","pag","pah","pai","pak","pal","pam","pao","pap","paq","par","pas","pat","pau","pav","paw","pax","pay","paz","pbb","pbc","pbe","pbf","pbg","pbh","pbi","pbl","pbm","pbn","pbo","pbp","pbr","pbs","pbt","pbu","pbv","pby","pbz","pca","pcb","pcc","pcd","pce","pcf","pcg","pch","pci","pcj","pck","pcl","pcm","pcn","pcp","pcr","pcw","pda","pdc","pdi","pdn","pdo","pdt","pdu","pea","peb","ped","pee","pef","peg","peh","pei","pej","pek","pel","pem","peo","pep","peq","pes","pev","pex","pey","pez","pfa","pfe","pfl","pga","pgd","pgg","pgi","pgk","pgl","pgn","pgs","pgu","pgy","pgz","pha","phd","phg","phh","phi","phk","phl","phm","phn","pho","phq","phr","pht","phu","phv","phw","pia","pib","pic","pid","pie","pif","pig","pih","pii","pij","pil","pim","pin","pio","pip","pir","pis","pit","piu","piv","piw","pix","piy","piz","pjt","pka","pkb","pkc","pkg","pkh","pkn","pko","pkp","pkr","pks","pkt","pku","pla","plb","plc","pld","ple","plf","plg","plh","plj","plk","pll","pln","plo","plp","plq","plr","pls","plt","plu","plv","plw","ply","plz","pma","pmb","pmc","pmd","pme","pmf","pmh","pmi","pmj","pmk","pml","pmm","pmn","pmo","pmq","pmr","pms","pmt","pmu","pmw","pmx","pmy","pmz","pna","pnb","pnc","pne","png","pnh","pni","pnj","pnk","pnl","pnm","pnn","pno","pnp","pnq","pnr","pns","pnt","pnu","pnv","pnw","pnx","pny","pnz","poc","pod","poe","pof","pog","poh","poi","pok","pom","pon","poo","pop","poq","pos","pot","pov","pow","pox","poy","poz","ppa","ppe","ppi","ppk","ppl","ppm","ppn","ppo","ppp","ppq","ppr","pps","ppt","ppu","pqa","pqe","pqm","pqw","pra","prb","prc","prd","pre","prf","prg","prh","pri","prk","prl","prm","prn","pro","prp","prq","prr","prs","prt","pru","prw","prx","pry","prz","psa","psc","psd","pse","psg","psh","psi","psl","psm","psn","pso","psp","psq","psr","pss","pst","psu","psw","psy","pta","pth","pti","ptn","pto","ptp","ptq","ptr","ptt","ptu","ptv","ptw","pty","pua","pub","puc","pud","pue","puf","pug","pui","puj","puk","pum","puo","pup","puq","pur","put","puu","puw","pux","puy","puz","pwa","pwb","pwg","pwi","pwm","pwn","pwo","pwr","pww","pxm","pye","pym","pyn","pys","pyu","pyx","pyy","pzn","qaa..qtz","qua","qub","quc","qud","quf","qug","quh","qui","quk","qul","qum","qun","qup","quq","qur","qus","quv","quw","qux","quy","quz","qva","qvc","qve","qvh","qvi","qvj","qvl","qvm","qvn","qvo","qvp","qvs","qvw","qvy","qvz","qwa","qwc","qwe","qwh","qwm","qws","qwt","qxa","qxc","qxh","qxl","qxn","qxo","qxp","qxq","qxr","qxs","qxt","qxu","qxw","qya","qyp","raa","rab","rac","rad","raf","rag","rah","rai","raj","rak","ral","ram","ran","rao","rap","raq","rar","ras","rat","rau","rav","raw","rax","ray","raz","rbb","rbk","rbl","rbp","rcf","rdb","rea","reb","ree","reg","rei","rej","rel","rem","ren","rer","res","ret","rey","rga","rge","rgk","rgn","rgr","rgs","rgu","rhg","rhp","ria","rie","rif","ril","rim","rin","rir","rit","riu","rjg","rji","rjs","rka","rkb","rkh","rki","rkm","rkt","rkw","rma","rmb","rmc","rmd","rme","rmf","rmg","rmh","rmi","rmk","rml","rmm","rmn","rmo","rmp","rmq","rmr","rms","rmt","rmu","rmv","rmw","rmx","rmy","rmz","rna","rnd","rng","rnl","rnn","rnp","rnr","rnw","roa","rob","roc","rod","roe","rof","rog","rol","rom","roo","rop","ror","rou","row","rpn","rpt","rri","rro","rrt","rsb","rsi","rsl","rsm","rtc","rth","rtm","rts","rtw","rub","ruc","rue","ruf","rug","ruh","rui","ruk","ruo","rup","ruq","rut","ruu","ruy","ruz","rwa","rwk","rwm","rwo","rwr","rxd","rxw","ryn","rys","ryu","rzh","saa","sab","sac","sad","sae","saf","sah","sai","saj","sak","sal","sam","sao","sap","saq","sar","sas","sat","sau","sav","saw","sax","say","saz","sba","sbb","sbc","sbd","sbe","sbf","sbg","sbh","sbi","sbj","sbk","sbl","sbm","sbn","sbo","sbp","sbq","sbr","sbs","sbt","sbu","sbv","sbw","sbx","sby","sbz","sca","scb","sce","scf","scg","sch","sci","sck","scl","scn","sco","scp","scq","scs","sct","scu","scv","scw","scx","sda","sdb","sdc","sde","sdf","sdg","sdh","sdj","sdk","sdl","sdm","sdn","sdo","sdp","sdr","sds","sdt","sdu","sdv","sdx","sdz","sea","seb","sec","sed","see","sef","seg","seh","sei","sej","sek","sel","sem","sen","seo","sep","seq","ser","ses","set","seu","sev","sew","sey","sez","sfb","sfe","sfm","sfs","sfw","sga","sgb","sgc","sgd","sge","sgg","sgh","sgi","sgj","sgk","sgl","sgm","sgn","sgo","sgp","sgr","sgs","sgt","sgu","sgw","sgx","sgy","sgz","sha","shb","shc","shd","she","shg","shh","shi","shj","shk","shl","shm","shn","sho","shp","shq","shr","shs","sht","shu","shv","shw","shx","shy","shz","sia","sib","sid","sie","sif","sig","sih","sii","sij","sik","sil","sim","sio","sip","siq","sir","sis","sit","siu","siv","siw","six","siy","siz","sja","sjb","sjd","sje","sjg","sjk","sjl","sjm","sjn","sjo","sjp","sjr","sjs","sjt","sju","sjw","ska","skb","skc","skd","ske","skf","skg","skh","ski","skj","skk","skm","skn","sko","skp","skq","skr","sks","skt","sku","skv","skw","skx","sky","skz","sla","slc","sld","sle","slf","slg","slh","sli","slj","sll","slm","sln","slp","slq","slr","sls","slt","slu","slw","slx","sly","slz","sma","smb","smc","smd","smf","smg","smh","smi","smj","smk","sml","smm","smn","smp","smq","smr","sms","smt","smu","smv","smw","smx","smy","smz","snb","snc","sne","snf","sng","snh","sni","snj","snk","snl","snm","snn","sno","snp","snq","snr","sns","snu","snv","snw","snx","sny","snz","soa","sob","soc","sod","soe","sog","soh","soi","soj","sok","sol","son","soo","sop","soq","sor","sos","sou","sov","sow","sox","soy","soz","spb","spc","spd","spe","spg","spi","spk","spl","spm","spn","spo","spp","spq","spr","sps","spt","spu","spv","spx","spy","sqa","sqh","sqj","sqk","sqm","sqn","sqo","sqq","sqr","sqs","sqt","squ","sra","srb","src","sre","srf","srg","srh","sri","srk","srl","srm","srn","sro","srq","srr","srs","srt","sru","srv","srw","srx","sry","srz","ssa","ssb","ssc","ssd","sse","ssf","ssg","ssh","ssi","ssj","ssk","ssl","ssm","ssn","sso","ssp","ssq","ssr","sss","sst","ssu","ssv","ssx","ssy","ssz","sta","stb","std","ste","stf","stg","sth","sti","stj","stk","stl","stm","stn","sto","stp","stq","str","sts","stt","stu","stv","stw","sty","sua","sub","suc","sue","sug","sui","suj","suk","sul","sum","suq","sur","sus","sut","suv","suw","sux","suy","suz","sva","svb","svc","sve","svk","svm","svr","svs","svx","swb","swc","swf","swg","swh","swi","swj","swk","swl","swm","swn","swo","swp","swq","swr","sws","swt","swu","swv","sww","swx","swy","sxb","sxc","sxe","sxg","sxk","sxl","sxm","sxn","sxo","sxr","sxs","sxu","sxw","sya","syb","syc","syd","syi","syk","syl","sym","syn","syo","syr","sys","syw","syx","syy","sza","szb","szc","szd","sze","szg","szl","szn","szp","szs","szv","szw","taa","tab","tac","tad","tae","taf","tag","tai","taj","tak","tal","tan","tao","tap","taq","tar","tas","tau","tav","taw","tax","tay","taz","tba","tbb","tbc","tbd","tbe","tbf","tbg","tbh","tbi","tbj","tbk","tbl","tbm","tbn","tbo","tbp","tbq","tbr","tbs","tbt","tbu","tbv","tbw","tbx","tby","tbz","tca","tcb","tcc","tcd","tce","tcf","tcg","tch","tci","tck","tcl","tcm","tcn","tco","tcp","tcq","tcs","tct","tcu","tcw","tcx","tcy","tcz","tda","tdb","tdc","tdd","tde","tdf","tdg","tdh","tdi","tdj","tdk","tdl","tdm","tdn","tdo","tdq","tdr","tds","tdt","tdu","tdv","tdx","tdy","tea","teb","tec","ted","tee","tef","teg","teh","tei","tek","tem","ten","teo","tep","teq","ter","tes","tet","teu","tev","tew","tex","tey","tez","tfi","tfn","tfo","tfr","tft","tga","tgb","tgc","tgd","tge","tgf","tgg","tgh","tgi","tgj","tgn","tgo","tgp","tgq","tgr","tgs","tgt","tgu","tgv","tgw","tgx","tgy","tgz","thc","thd","the","thf","thh","thi","thk","thl","thm","thn","thp","thq","thr","ths","tht","thu","thv","thw","thx","thy","thz","tia","tic","tid","tie","tif","tig","tih","tii","tij","tik","til","tim","tin","tio","tip","tiq","tis","tit","tiu","tiv","tiw","tix","tiy","tiz","tja","tjg","tji","tjl","tjm","tjn","tjo","tjs","tju","tjw","tka","tkb","tkd","tke","tkf","tkg","tkk","tkl","tkm","tkn","tkp","tkq","tkr","tks","tkt","tku","tkv","tkw","tkx","tkz","tla","tlb","tlc","tld","tlf","tlg","tlh","tli","tlj","tlk","tll","tlm","tln","tlo","tlp","tlq","tlr","tls","tlt","tlu","tlv","tlw","tlx","tly","tma","tmb","tmc","tmd","tme","tmf","tmg","tmh","tmi","tmj","tmk","tml","tmm","tmn","tmo","tmp","tmq","tmr","tms","tmt","tmu","tmv","tmw","tmy","tmz","tna","tnb","tnc","tnd","tne","tnf","tng","tnh","tni","tnk","tnl","tnm","tnn","tno","tnp","tnq","tnr","tns","tnt","tnu","tnv","tnw","tnx","tny","tnz","tob","toc","tod","toe","tof","tog","toh","toi","toj","tol","tom","too","top","toq","tor","tos","tou","tov","tow","tox","toy","toz","tpa","tpc","tpe","tpf","tpg","tpi","tpj","tpk","tpl","tpm","tpn","tpo","tpp","tpq","tpr","tpt","tpu","tpv","tpw","tpx","tpy","tpz","tqb","tql","tqm","tqn","tqo","tqp","tqq","tqr","tqt","tqu","tqw","tra","trb","trc","trd","tre","trf","trg","trh","tri","trj","trk","trl","trm","trn","tro","trp","trq","trr","trs","trt","tru","trv","trw","trx","try","trz","tsa","tsb","tsc","tsd","tse","tsf","tsg","tsh","tsi","tsj","tsk","tsl","tsm","tsp","tsq","tsr","tss","tst","tsu","tsv","tsw","tsx","tsy","tsz","tta","ttb","ttc","ttd","tte","ttf","ttg","tth","tti","ttj","ttk","ttl","ttm","ttn","tto","ttp","ttq","ttr","tts","ttt","ttu","ttv","ttw","tty","ttz","tua","tub","tuc","tud","tue","tuf","tug","tuh","tui","tuj","tul","tum","tun","tuo","tup","tuq","tus","tut","tuu","tuv","tuw","tux","tuy","tuz","tva","tvd","tve","tvk","tvl","tvm","tvn","tvo","tvs","tvt","tvu","tvw","tvy","twa","twb","twc","twd","twe","twf","twg","twh","twl","twm","twn","two","twp","twq","twr","twt","twu","tww","twx","twy","txa","txb","txc","txe","txg","txh","txi","txj","txm","txn","txo","txq","txr","txs","txt","txu","txx","txy","tya","tye","tyh","tyi","tyj","tyl","tyn","typ","tyr","tys","tyt","tyu","tyv","tyx","tyz","tza","tzh","tzj","tzl","tzm","tzn","tzo","tzx","uam","uan","uar","uba","ubi","ubl","ubr","ubu","uby","uda","ude","udg","udi","udj","udl","udm","udu","ues","ufi","uga","ugb","uge","ugn","ugo","ugy","uha","uhn","uis","uiv","uji","uka","ukg","ukh","ukk","ukl","ukp","ukq","uks","uku","ukw","uky","ula","ulb","ulc","ule","ulf","uli","ulk","ull","ulm","uln","ulu","ulw","uma","umb","umc","umd","umg","umi","umm","umn","umo","ump","umr","ums","umu","una","und","une","ung","unk","unm","unn","unp","unr","unu","unx","unz","uok","upi","upv","ura","urb","urc","ure","urf","urg","urh","uri","urj","urk","url","urm","urn","uro","urp","urr","urt","uru","urv","urw","urx","ury","urz","usa","ush","usi","usk","usp","usu","uta","ute","utp","utr","utu","uum","uun","uur","uuu","uve","uvh","uvl","uwa","uya","uzn","uzs","vaa","vae","vaf","vag","vah","vai","vaj","val","vam","van","vao","vap","var","vas","vau","vav","vay","vbb","vbk","vec","ved","vel","vem","veo","vep","ver","vgr","vgt","vic","vid","vif","vig","vil","vin","vis","vit","viv","vka","vki","vkj","vkk","vkl","vkm","vko","vkp","vkt","vku","vlp","vls","vma","vmb","vmc","vmd","vme","vmf","vmg","vmh","vmi","vmj","vmk","vml","vmm","vmp","vmq","vmr","vms","vmu","vmv","vmw","vmx","vmy","vmz","vnk","vnm","vnp","vor","vot","vra","vro","vrs","vrt","vsi","vsl","vsv","vto","vum","vun","vut","vwa","waa","wab","wac","wad","wae","waf","wag","wah","wai","waj","wak","wal","wam","wan","wao","wap","waq","war","was","wat","wau","wav","waw","wax","way","waz","wba","wbb","wbe","wbf","wbh","wbi","wbj","wbk","wbl","wbm","wbp","wbq","wbr","wbs","wbt","wbv","wbw","wca","wci","wdd","wdg","wdj","wdk","wdu","wdy","wea","wec","wed","weg","weh","wei","wem","wen","weo","wep","wer","wes","wet","weu","wew","wfg","wga","wgb","wgg","wgi","wgo","wgu","wgw","wgy","wha","whg","whk","whu","wib","wic","wie","wif","wig","wih","wii","wij","wik","wil","wim","win","wir","wit","wiu","wiv","wiw","wiy","wja","wji","wka","wkb","wkd","wkl","wku","wkw","wky","wla","wlc","wle","wlg","wli","wlk","wll","wlm","wlo","wlr","wls","wlu","wlv","wlw","wlx","wly","wma","wmb","wmc","wmd","wme","wmh","wmi","wmm","wmn","wmo","wms","wmt","wmw","wmx","wnb","wnc","wnd","wne","wng","wni","wnk","wnm","wnn","wno","wnp","wnu","wnw","wny","woa","wob","woc","wod","woe","wof","wog","woi","wok","wom","won","woo","wor","wos","wow","woy","wpc","wra","wrb","wrd","wrg","wrh","wri","wrk","wrl","wrm","wrn","wro","wrp","wrr","wrs","wru","wrv","wrw","wrx","wry","wrz","wsa","wsg","wsi","wsk","wsr","wss","wsu","wsv","wtf","wth","wti","wtk","wtm","wtw","wua","wub","wud","wuh","wul","wum","wun","wur","wut","wuu","wuv","wux","wuy","wwa","wwb","wwo","wwr","www","wxa","wxw","wya","wyb","wyi","wym","wyr","wyy","xaa","xab","xac","xad","xae","xag","xai","xaj","xak","xal","xam","xan","xao","xap","xaq","xar","xas","xat","xau","xav","xaw","xay","xba","xbb","xbc","xbd","xbe","xbg","xbi","xbj","xbm","xbn","xbo","xbp","xbr","xbw","xbx","xby","xcb","xcc","xce","xcg","xch","xcl","xcm","xcn","xco","xcr","xct","xcu","xcv","xcw","xcy","xda","xdc","xdk","xdm","xdo","xdy","xeb","xed","xeg","xel","xem","xep","xer","xes","xet","xeu","xfa","xga","xgb","xgd","xgf","xgg","xgi","xgl","xgm","xgn","xgr","xgu","xgw","xha","xhc","xhd","xhe","xhr","xht","xhu","xhv","xia","xib","xii","xil","xin","xip","xir","xis","xiv","xiy","xjb","xjt","xka","xkb","xkc","xkd","xke","xkf","xkg","xkh","xki","xkj","xkk","xkl","xkn","xko","xkp","xkq","xkr","xks","xkt","xku","xkv","xkw","xkx","xky","xkz","xla","xlb","xlc","xld","xle","xlg","xli","xln","xlo","xlp","xls","xlu","xly","xma","xmb","xmc","xmd","xme","xmf","xmg","xmh","xmj","xmk","xml","xmm","xmn","xmo","xmp","xmq","xmr","xms","xmt","xmu","xmv","xmw","xmx","xmy","xmz","xna","xnb","xnd","xng","xnh","xni","xnk","xnn","xno","xnr","xns","xnt","xnu","xny","xnz","xoc","xod","xog","xoi","xok","xom","xon","xoo","xop","xor","xow","xpa","xpc","xpe","xpg","xpi","xpj","xpk","xpm","xpn","xpo","xpp","xpq","xpr","xps","xpt","xpu","xpy","xqa","xqt","xra","xrb","xrd","xre","xrg","xri","xrm","xrn","xrq","xrr","xrt","xru","xrw","xsa","xsb","xsc","xsd","xse","xsh","xsi","xsj","xsl","xsm","xsn","xso","xsp","xsq","xsr","xss","xsu","xsv","xsy","xta","xtb","xtc","xtd","xte","xtg","xth","xti","xtj","xtl","xtm","xtn","xto","xtp","xtq","xtr","xts","xtt","xtu","xtv","xtw","xty","xtz","xua","xub","xud","xug","xuj","xul","xum","xun","xuo","xup","xur","xut","xuu","xve","xvi","xvn","xvo","xvs","xwa","xwc","xwd","xwe","xwg","xwj","xwk","xwl","xwo","xwr","xwt","xww","xxb","xxk","xxm","xxr","xxt","xya","xyb","xyj","xyk","xyl","xyt","xyy","xzh","xzm","xzp","yaa","yab","yac","yad","yae","yaf","yag","yah","yai","yaj","yak","yal","yam","yan","yao","yap","yaq","yar","yas","yat","yau","yav","yaw","yax","yay","yaz","yba","ybb","ybd","ybe","ybh","ybi","ybj","ybk","ybl","ybm","ybn","ybo","ybx","yby","ych","ycl","ycn","ycp","yda","ydd","yde","ydg","ydk","yds","yea","yec","yee","yei","yej","yel","yen","yer","yes","yet","yeu","yev","yey","yga","ygi","ygl","ygm","ygp","ygr","ygs","ygu","ygw","yha","yhd","yhl","yhs","yia","yif","yig","yih","yii","yij","yik","yil","yim","yin","yip","yiq","yir","yis","yit","yiu","yiv","yix","yiy","yiz","yka","ykg","yki","ykk","ykl","ykm","ykn","yko","ykr","ykt","yku","yky","yla","ylb","yle","ylg","yli","yll","ylm","yln","ylo","ylr","ylu","yly","yma","ymb","ymc","ymd","yme","ymg","ymh","ymi","ymk","yml","ymm","ymn","ymo","ymp","ymq","ymr","yms","ymt","ymx","ymz","yna","ynd","yne","yng","ynh","ynk","ynl","ynn","yno","ynq","yns","ynu","yob","yog","yoi","yok","yol","yom","yon","yos","yot","yox","yoy","ypa","ypb","ypg","yph","ypk","ypm","ypn","ypo","ypp","ypz","yra","yrb","yre","yri","yrk","yrl","yrm","yrn","yro","yrs","yrw","yry","ysc","ysd","ysg","ysl","ysn","yso","ysp","ysr","yss","ysy","yta","ytl","ytp","ytw","yty","yua","yub","yuc","yud","yue","yuf","yug","yui","yuj","yuk","yul","yum","yun","yup","yuq","yur","yut","yuu","yuw","yux","yuy","yuz","yva","yvt","ywa","ywg","ywl","ywn","ywq","ywr","ywt","ywu","yww","yxa","yxg","yxl","yxm","yxu","yxy","yyr","yyu","yyz","yzg","yzk","zaa","zab","zac","zad","zae","zaf","zag","zah","zai","zaj","zak","zal","zam","zao","zap","zaq","zar","zas","zat","zau","zav","zaw","zax","zay","zaz","zbc","zbe","zbl","zbt","zbw","zca","zch","zdj","zea","zeg","zeh","zen","zga","zgb","zgh","zgm","zgn","zgr","zhb","zhd","zhi","zhn","zhw","zhx","zia","zib","zik","zil","zim","zin","zir","ziw","ziz","zka","zkb","zkd","zkg","zkh","zkk","zkn","zko","zkp","zkr","zkt","zku","zkv","zkz","zle","zlj","zlm","zln","zlq","zls","zlw","zma","zmb","zmc","zmd","zme","zmf","zmg","zmh","zmi","zmj","zmk","zml","zmm","zmn","zmo","zmp","zmq","zmr","zms","zmt","zmu","zmv","zmw","zmx","zmy","zmz","zna","znd","zne","zng","znk","zns","zoc","zoh","zom","zoo","zoq","zor","zos","zpa","zpb","zpc","zpd","zpe","zpf","zpg","zph","zpi","zpj","zpk","zpl","zpm","zpn","zpo","zpp","zpq","zpr","zps","zpt","zpu","zpv","zpw","zpx","zpy","zpz","zqe","zra","zrg","zrn","zro","zrp","zrs","zsa","zsk","zsl","zsm","zsr","zsu","zte","ztg","ztl","ztm","ztn","ztp","ztq","zts","ztt","ztu","ztx","zty","zua","zuh","zum","zun","zuy","zwa","zxx","zyb","zyg","zyj","zyn","zyp","zza","zzj"];function he(e){return ye(e)||ge(e)||be()}function be(){throw new TypeError("Invalid attempt to spread non-iterable instance")}function ge(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}function ye(e){if(Array.isArray(e)){for(var t=0,n=new Array(e.length);t<e.length;t++)n[t]=e[t];return n}}function R(){return(R=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function S(e){return(S="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}axe.utils.validLangs=function(){"use strict";return Ie},axe._load({data:{rules:{accesskeys:{description:"Ensures every accesskey attribute value is unique",help:"accesskey attribute value must be unique"},"area-alt":{description:"Ensures <area> elements of image maps have alternate text",help:"Active <area> elements must have alternate text"},"aria-allowed-attr":{description:"Ensures ARIA attributes are allowed for an element's role",help:"Elements must only use allowed ARIA attributes"},"aria-allowed-role":{description:"Ensures role attribute has an appropriate value for the element",help:"ARIA role must be appropriate for the element"},"aria-dpub-role-fallback":{description:"Ensures unsupported DPUB roles are only used on elements with implicit fallback roles",help:"Unsupported DPUB ARIA roles should be used on elements with implicit fallback roles"},"aria-hidden-body":{description:"Ensures aria-hidden='true' is not present on the document body.",help:"aria-hidden='true' must not be present on the document body"},"aria-hidden-focus":{description:"Ensures aria-hidden elements do not contain focusable elements",help:"ARIA hidden element must not contain focusable elements"},"aria-input-field-name":{description:"Ensures every ARIA input field has an accessible name",help:"ARIA input fields have an accessible name"},"aria-required-attr":{description:"Ensures elements with ARIA roles have all required ARIA attributes",help:"Required ARIA attributes must be provided"},"aria-required-children":{description:"Ensures elements with an ARIA role that require child roles contain them",help:"Certain ARIA roles must contain particular children"},"aria-required-parent":{description:"Ensures elements with an ARIA role that require parent roles are contained by them",help:"Certain ARIA roles must be contained by particular parents"},"aria-roles":{description:"Ensures all elements with a role attribute use a valid value",help:"ARIA roles used must conform to valid values"},"aria-toggle-field-name":{description:"Ensures every ARIA toggle field has an accessible name",help:"ARIA toggle fields have an accessible name"},"aria-valid-attr-value":{description:"Ensures all ARIA attributes have valid values",help:"ARIA attributes must conform to valid values"},"aria-valid-attr":{description:"Ensures attributes that begin with aria- are valid ARIA attributes",help:"ARIA attributes must conform to valid names"},"audio-caption":{description:"Ensures <audio> elements have captions",help:"<audio> elements must have a captions track"},"autocomplete-valid":{description:"Ensure the autocomplete attribute is correct and suitable for the form field",help:"autocomplete attribute must be used correctly"},"avoid-inline-spacing":{description:"Ensure that text spacing set through style attributes can be adjusted with custom stylesheets",help:"Inline text spacing must be adjustable with custom stylesheets"},blink:{description:"Ensures <blink> elements are not used",help:"<blink> elements are deprecated and must not be used"},"button-name":{description:"Ensures buttons have discernible text",help:"Buttons must have discernible text"},bypass:{description:"Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content",help:"Page must have means to bypass repeated blocks"},checkboxgroup:{description:'Ensures related <input type="checkbox"> elements have a group and that the group designation is consistent',help:"Checkbox inputs with the same name attribute value must be part of a group"},"color-contrast":{description:"Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds",help:"Elements must have sufficient color contrast"},"css-orientation-lock":{description:"Ensures content is not locked to any specific display orientation, and the content is operable in all display orientations",help:"CSS Media queries are not used to lock display orientation"},"definition-list":{description:"Ensures <dl> elements are structured correctly",help:"<dl> elements must only directly contain properly-ordered <dt> and <dd> groups, <script> or <template> elements"},dlitem:{description:"Ensures <dt> and <dd> elements are contained by a <dl>",help:"<dt> and <dd> elements must be contained by a <dl>"},"document-title":{description:"Ensures each HTML document contains a non-empty <title> element",help:"Documents must have <title> element to aid in navigation"},"duplicate-id-active":{description:"Ensures every id attribute value of active elements is unique",help:"IDs of active elements must be unique"},"duplicate-id-aria":{description:"Ensures every id attribute value used in ARIA and in labels is unique",help:"IDs used in ARIA and labels must be unique"},"duplicate-id":{description:"Ensures every id attribute value is unique",help:"id attribute value must be unique"},"empty-heading":{description:"Ensures headings have discernible text",help:"Headings must not be empty"},"focus-order-semantics":{description:"Ensures elements in the focus order have an appropriate role",help:"Elements in the focus order need a role appropriate for interactive content"},"form-field-multiple-labels":{description:"Ensures form field does not have multiple label elements",help:"Form field must not have multiple label elements"},"frame-tested":{description:"Ensures <iframe> and <frame> elements contain the axe-core script",help:"Frames must be tested with axe-core"},"frame-title-unique":{description:"Ensures <iframe> and <frame> elements contain a unique title attribute",help:"Frames must have a unique title attribute"},"frame-title":{description:"Ensures <iframe> and <frame> elements contain a non-empty title attribute",help:"Frames must have title attribute"},"heading-order":{description:"Ensures the order of headings is semantically correct",help:"Heading levels should only increase by one"},"hidden-content":{description:"Informs users about hidden content.",help:"Hidden content on the page cannot be analyzed"},"html-has-lang":{description:"Ensures every HTML document has a lang attribute",help:"<html> element must have a lang attribute"},"html-lang-valid":{description:"Ensures the lang attribute of the <html> element has a valid value",help:"<html> element must have a valid value for the lang attribute"},"html-xml-lang-mismatch":{description:"Ensure that HTML elements with both valid lang and xml:lang attributes agree on the base language of the page",help:"HTML elements with lang and xml:lang must have the same base language"},"image-alt":{description:"Ensures <img> elements have alternate text or a role of none or presentation",help:"Images must have alternate text"},"image-redundant-alt":{description:"Ensure image alternative is not repeated as text",help:"Alternative text of images should not be repeated as text"},"input-button-name":{description:"Ensures input buttons have discernible text",help:"Input buttons must have discernible text"},"input-image-alt":{description:'Ensures <input type="image"> elements have alternate text',help:"Image buttons must have alternate text"},"label-content-name-mismatch":{description:"Ensures that elements labelled through their content must have their visible text as part of their accessible name",help:"Elements must have their visible text as part of their accessible name"},"label-title-only":{description:"Ensures that every form element is not solely labeled using the title or aria-describedby attributes",help:"Form elements should have a visible label"},label:{description:"Ensures every form element has a label",help:"Form elements must have labels"},"landmark-banner-is-top-level":{description:"Ensures the banner landmark is at top level",help:"Banner landmark must not be contained in another landmark"},"landmark-complementary-is-top-level":{description:"Ensures the complementary landmark or aside is at top level",help:"Aside must not be contained in another landmark"},"landmark-contentinfo-is-top-level":{description:"Ensures the contentinfo landmark is at top level",help:"Contentinfo landmark must not be contained in another landmark"},"landmark-main-is-top-level":{description:"Ensures the main landmark is at top level",help:"Main landmark must not be contained in another landmark"},"landmark-no-duplicate-banner":{description:"Ensures the document has at most one banner landmark",help:"Document must not have more than one banner landmark"},"landmark-no-duplicate-contentinfo":{description:"Ensures the document has at most one contentinfo landmark",help:"Document must not have more than one contentinfo landmark"},"landmark-one-main":{description:"Ensures the document has only one main landmark and each iframe in the page has at most one main landmark",help:"Document must have one main landmark"},"landmark-unique":{help:"Ensures landmarks are unique",description:"Landmarks must have a unique role or role/label/title (i.e. accessible name) combination"},"layout-table":{description:"Ensures presentational <table> elements do not use <th>, <caption> elements or the summary attribute",help:"Layout tables must not use data table elements"},"link-in-text-block":{description:"Links can be distinguished without relying on color",help:"Links must be distinguished from surrounding text in a way that does not rely on color"},"link-name":{description:"Ensures links have discernible text",help:"Links must have discernible text"},list:{description:"Ensures that lists are structured correctly",help:"<ul> and <ol> must only directly contain <li>, <script> or <template> elements"},listitem:{description:"Ensures <li> elements are used semantically",help:"<li> elements must be contained in a <ul> or <ol>"},marquee:{description:"Ensures <marquee> elements are not used",help:"<marquee> elements are deprecated and must not be used"},"meta-refresh":{description:'Ensures <meta http-equiv="refresh"> is not used',help:"Timed refresh must not exist"},"meta-viewport-large":{description:'Ensures <meta name="viewport"> can scale a significant amount',help:"Users should be able to zoom and scale the text up to 500%"},"meta-viewport":{description:'Ensures <meta name="viewport"> does not disable text scaling and zooming',help:"Zooming and scaling must not be disabled"},"object-alt":{description:"Ensures <object> elements have alternate text",help:"<object> elements must have alternate text"},"p-as-heading":{description:"Ensure p elements are not used to style headings",help:"Bold, italic text and font-size are not used to style p elements as a heading"},"page-has-heading-one":{description:"Ensure that the page, or at least one of its frames contains a level-one heading",help:"Page must contain a level-one heading"},radiogroup:{description:'Ensures related <input type="radio"> elements have a group and that the group designation is consistent',help:"Radio inputs with the same name attribute value must be part of a group"},region:{description:"Ensures all page content is contained by landmarks",help:"All page content must be contained by landmarks"},"role-img-alt":{description:"Ensures [role='img'] elements have alternate text",help:"[role='img'] elements have an alternative text"},"scope-attr-valid":{description:"Ensures the scope attribute is used correctly on tables",help:"scope attribute should be used correctly"},"scrollable-region-focusable":{description:"Elements that have scrollable content should be accessible by keyboard",help:"Ensure that scrollable region has keyboard access"},"server-side-image-map":{description:"Ensures that server-side image maps are not used",help:"Server-side image maps must not be used"},"skip-link":{description:"Ensure all skip links have a focusable target",help:"The skip-link target should exist and be focusable"},tabindex:{description:"Ensures tabindex attribute values are not greater than 0",help:"Elements should not have tabindex greater than zero"},"table-duplicate-name":{description:"Ensure that tables do not have the same summary and caption",help:"The <caption> element should not contain the same text as the summary attribute"},"table-fake-caption":{description:"Ensure that tables with a caption use the <caption> element.",help:"Data or header cells should not be used to give caption to a data table."},"td-has-header":{description:"Ensure that each non-empty data cell in a large table has one or more table headers",help:"All non-empty td element in table larger than 3 by 3 must have an associated table header"},"td-headers-attr":{description:"Ensure that each cell in a table using the headers refers to another cell in that table",help:"All cells in a table element that use the headers attribute must only refer to other cells of that same table"},"th-has-data-cells":{description:"Ensure that each table header in a data table refers to data cells",help:"All th elements and elements with role=columnheader/rowheader must have data cells they describe"},"valid-lang":{description:"Ensures lang attributes have valid values",help:"lang attribute must have a valid value"},"video-caption":{description:"Ensures <video> elements have captions",help:"<video> elements must have captions"},"video-description":{description:"Ensures <video> elements have audio descriptions",help:"<video> elements must have an audio description track"}},checks:{accesskeys:{impact:"serious",messages:{pass:function(e){return"Accesskey attribute value is unique"},fail:function(e){return"Document has multiple elements with the same accesskey"}}},"non-empty-alt":{impact:"critical",messages:{pass:function(e){return"Element has a non-empty alt attribute"},fail:function(e){return"Element has no alt attribute or the alt attribute is empty"}}},"non-empty-title":{impact:"serious",messages:{pass:function(e){return"Element has a title attribute"},fail:function(e){return"Element has no title attribute or the title attribute is empty"}}},"aria-label":{impact:"serious",messages:{pass:function(e){return"aria-label attribute exists and is not empty"},fail:function(e){return"aria-label attribute does not exist or is empty"}}},"aria-labelledby":{impact:"serious",messages:{pass:function(e){return"aria-labelledby attribute exists and references elements that are visible to screen readers"},fail:function(e){return"aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty"}}},"aria-allowed-attr":{impact:"critical",messages:{pass:function(e){return"ARIA attributes are used correctly for the defined role"},fail:function(e){var t="ARIA attribute"+(e.data&&1<e.data.length?"s are":" is")+" not allowed:",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},"aria-unsupported-attr":{impact:"critical",messages:{pass:function(e){return"ARIA attribute is supported"},fail:function(e){var t="ARIA attribute is not widely supported in screen readers and assistive technologies: ",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},"aria-allowed-role":{impact:"minor",messages:{pass:function(e){return"ARIA role is allowed for given element"},fail:function(e){return"ARIA role"+(e.data&&1<e.data.length?"s":"")+" "+e.data.join(", ")+" "+(e.data&&1<e.data.length?"are":" is")+" not allowed for given element"},incomplete:function(e){return"ARIA role"+(e.data&&1<e.data.length?"s":"")+" "+e.data.join(", ")+" must be removed when the element is made visible, as "+(e.data&&1<e.data.length?"they are":"it is")+" not allowed for the element"}}},"implicit-role-fallback":{impact:"moderate",messages:{pass:function(e){return"Element’s implicit ARIA role is an appropriate fallback"},fail:function(e){return"Element’s implicit ARIA role is not a good fallback for the (unsupported) role"}}},"aria-hidden-body":{impact:"critical",messages:{pass:function(e){return"No aria-hidden attribute is present on document body"},fail:function(e){return"aria-hidden=true should not be present on the document body"}}},"focusable-disabled":{impact:"serious",messages:{pass:function(e){return"No focusable elements contained within element"},fail:function(e){return"Focusable content should be disabled or be removed from the DOM"}}},"focusable-not-tabbable":{impact:"serious",messages:{pass:function(e){return"No focusable elements contained within element"},fail:function(e){return"Focusable content should have tabindex='-1' or be removed from the DOM"}}},"no-implicit-explicit-label":{impact:"moderate",messages:{pass:function(e){return"There is no mismatch between a <label> and accessible name"},incomplete:function(e){return"Check that the <label> does not need be part of the ARIA "+e.data+" field's name"}}},"aria-required-attr":{impact:"critical",messages:{pass:function(e){return"All required ARIA attributes are present"},fail:function(e){var t="Required ARIA attribute"+(e.data&&1<e.data.length?"s":"")+" not present:",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},"aria-required-children":{impact:"critical",messages:{pass:function(e){return"Required ARIA children are present"},fail:function(e){var t="Required ARIA "+(e.data&&1<e.data.length?"children":"child")+" role not present:",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t},incomplete:function(e){var t="Expecting ARIA "+(e.data&&1<e.data.length?"children":"child")+" role to be added:",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},"aria-required-parent":{impact:"critical",messages:{pass:function(e){return"Required ARIA parent role present"},fail:function(e){var t="Required ARIA parent"+(e.data&&1<e.data.length?"s":"")+" role not present:",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},invalidrole:{impact:"critical",messages:{pass:function(e){return"ARIA role is valid"},fail:function(e){return"Role must be one of the valid ARIA roles"}}},abstractrole:{impact:"serious",messages:{pass:function(e){return"Abstract roles are not used"},fail:function(e){return"Abstract roles cannot be directly used"}}},unsupportedrole:{impact:"critical",messages:{pass:function(e){return"ARIA role is supported"},fail:function(e){var t="The role used is not widely supported in screen readers and assistive technologies: ",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},"has-visible-text":{impact:"minor",messages:{pass:function(e){return"Element has text that is visible to screen readers"},fail:function(e){return"Element does not have text that is visible to screen readers"}}},"aria-valid-attr-value":{impact:"critical",messages:{pass:function(e){return"ARIA attribute values are valid"},fail:function(e){var t="Invalid ARIA attribute value"+(e.data&&1<e.data.length?"s":"")+":",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t},incomplete:function(e){var t="ARIA attribute"+(e.data&&1<e.data.length?"s":"")+" element ID does not exist on the page:",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},"aria-errormessage":{impact:"critical",messages:{pass:function(e){return"Uses a supported aria-errormessage technique"},fail:function(e){var t="aria-errormessage value"+(e.data&&1<e.data.length?"s":"")+" ",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" `"+n[r+=1];return t+="` must use a technique to announce the message (e.g., aria-live, aria-describedby, role=alert, etc.)"}}},"aria-valid-attr":{impact:"critical",messages:{pass:function(e){return"ARIA attribute name"+(e.data&&1<e.data.length?"s":"")+" are valid"},fail:function(e){var t="Invalid ARIA attribute name"+(e.data&&1<e.data.length?"s":"")+":",n=e.data;if(n)for(var r=-1,a=n.length-1;r<a;)t+=" "+n[r+=1];return t}}},caption:{impact:"critical",messages:{pass:function(e){return"The multimedia element has a captions track"},incomplete:function(e){return"Check that captions is available for the element"}}},"autocomplete-valid":{impact:"serious",messages:{pass:function(e){return"the autocomplete attribute is correctly formatted"},fail:function(e){return"the autocomplete attribute is incorrectly formatted"}}},"autocomplete-appropriate":{impact:"serious",messages:{pass:function(e){return"the autocomplete value is on an appropriate element"},fail:function(e){return"the autocomplete value is inappropriate for this type of input"}}},"avoid-inline-spacing":{impact:"serious",messages:{pass:function(e){return"No inline styles with '!important' that affect text spacing has been specified"},fail:function(e){return"Remove '!important' from inline style"+(e.data&&1<e.data.length?"s":"")+" "+e.data.join(", ")+", as overriding this is not supported by most browsers"}}},"is-on-screen":{impact:"serious",messages:{pass:function(e){return"Element is not visible"},fail:function(e){return"Element is visible"}}},"button-has-visible-text":{impact:"critical",messages:{pass:function(e){return"Element has inner text that is visible to screen readers"},fail:function(e){return"Element does not have inner text that is visible to screen readers"}}},"role-presentation":{impact:"minor",messages:{pass:function(e){return'Element\'s default semantics were overriden with role="presentation"'},fail:function(e){return'Element\'s default semantics were not overridden with role="presentation"'}}},"role-none":{impact:"minor",messages:{pass:function(e){return'Element\'s default semantics were overriden with role="none"'},fail:function(e){return'Element\'s default semantics were not overridden with role="none"'}}},"internal-link-present":{impact:"serious",messages:{pass:function(e){return"Valid skip link found"},fail:function(e){return"No valid skip link found"}}},"header-present":{impact:"serious",messages:{pass:function(e){return"Page has a header"},fail:function(e){return"Page does not have a header"}}},landmark:{impact:"serious",messages:{pass:function(e){return"Page has a landmark region"},fail:function(e){return"Page does not have a landmark region"}}},"group-labelledby":{impact:"critical",messages:{pass:function(e){return'Elements with the name "'+e.data.name+'" have both a shared label, and a unique label, referenced through aria-labelledby'},fail:function(e){var t="",n=e.data&&e.data.failureCode;return t+='Elements with the name "'+e.data.name+'" do not all have ',t+="no-shared-label"===n?"a shared label":"no-unique-label"===n?"a unique label":"both a shared label, and a unique label",t+=", referenced through aria-labelledby"}}},fieldset:{impact:"critical",messages:{pass:function(e){return"Element is contained in a fieldset"},fail:function(e){var t="",n=e.data&&e.data.failureCode;return t+="no-legend"===n?"Fieldset does not have a legend as its first child":"empty-legend"===n?"Legend does not have text that is visible to screen readers":"mixed-inputs"===n?"Fieldset contains unrelated inputs":"no-group-label"===n?"ARIA group does not have aria-label or aria-labelledby":"group-mixed-inputs"===n?"ARIA group contains unrelated inputs":"Element does not have a containing fieldset or ARIA group"}}},"color-contrast":{impact:"serious",messages:{pass:function(e){return"Element has sufficient color contrast of "+e.data.contrastRatio},fail:function(e){return"Element has insufficient color contrast of "+e.data.contrastRatio+" (foreground color: "+e.data.fgColor+", background color: "+e.data.bgColor+", font size: "+e.data.fontSize+", font weight: "+e.data.fontWeight+"). Expected contrast ratio of "+e.data.expectedContrastRatio},incomplete:{bgImage:"Element's background color could not be determined due to a background image",bgGradient:"Element's background color could not be determined due to a background gradient",imgNode:"Element's background color could not be determined because element contains an image node",bgOverlap:"Element's background color could not be determined because it is overlapped by another element",fgAlpha:"Element's foreground color could not be determined because of alpha transparency",elmPartiallyObscured:"Element's background color could not be determined because it's partially obscured by another element",elmPartiallyObscuring:"Element's background color could not be determined because it partially overlaps other elements",outsideViewport:"Element's background color could not be determined because it's outside the viewport",equalRatio:"Element has a 1:1 contrast ratio with the background",shortTextContent:"Element content is too short to determine if it is actual text content",default:"Unable to determine contrast ratio"}}},"css-orientation-lock":{impact:"serious",messages:{pass:function(e){return"Display is operable, and orientation lock does not exist"},fail:function(e){return"CSS Orientation lock is applied, and makes display inoperable"},incomplete:function(e){return"CSS Orientation lock cannot be determined"}}},"structured-dlitems":{impact:"serious",messages:{pass:function(e){return"When not empty, element has both <dt> and <dd> elements"},fail:function(e){return"When not empty, element does not have at least one <dt> element followed by at least one <dd> element"}}},"only-dlitems":{impact:"serious",messages:{pass:function(e){return"List element only has direct children that are allowed inside <dt> or <dd> elements"},fail:function(e){return"List element has direct children that are not allowed inside <dt> or <dd> elements"}}},dlitem:{impact:"serious",messages:{pass:function(e){return"Description list item has a <dl> parent element"},fail:function(e){return"Description list item does not have a <dl> parent element"}}},"doc-has-title":{impact:"serious",messages:{pass:function(e){return"Document has a non-empty <title> element"},fail:function(e){return"Document does not have a non-empty <title> element"}}},"duplicate-id-active":{impact:"serious",messages:{pass:function(e){return"Document has no active elements that share the same id attribute"},fail:function(e){return"Document has active elements with the same id attribute: "+e.data}}},"duplicate-id-aria":{impact:"critical",messages:{pass:function(e){return"Document has no elements referenced with ARIA or labels that share the same id attribute"},fail:function(e){return"Document has multiple elements referenced with ARIA with the same id attribute: "+e.data}}},"duplicate-id":{impact:"minor",messages:{pass:function(e){return"Document has no static elements that share the same id attribute"},fail:function(e){return"Document has multiple static elements with the same id attribute"}}},"has-widget-role":{impact:"minor",messages:{pass:function(e){return"Element has a widget role."},fail:function(e){return"Element does not have a widget role."}}},"valid-scrollable-semantics":{impact:"minor",messages:{pass:function(e){return"Element has valid semantics for an element in the focus order."},fail:function(e){return"Element has invalid semantics for an element in the focus order."}}},"multiple-label":{impact:"moderate",messages:{pass:function(e){return"Form field does not have multiple label elements"},fail:function(e){return"Multiple label elements is not widely supported in assistive technologies"}}},"frame-tested":{impact:"critical",messages:{pass:function(e){return"The iframe was tested with axe-core"},fail:function(e){return"The iframe could not be tested with axe-core"},incomplete:function(e){return"The iframe still has to be tested with axe-core"}}},"unique-frame-title":{impact:"serious",messages:{pass:function(e){return"Element's title attribute is unique"},fail:function(e){return"Element's title attribute is not unique"}}},"heading-order":{impact:"moderate",messages:{pass:function(e){return"Heading order valid"},fail:function(e){return"Heading order invalid"}}},"hidden-content":{impact:"minor",messages:{pass:function(e){return"All content on the page has been analyzed."},fail:function(e){return"There were problems analyzing the content on this page."},incomplete:function(e){return"There is hidden content on the page that was not analyzed. You will need to trigger the display of this content in order to analyze it."}}},"has-lang":{impact:"serious",messages:{pass:function(e){return"The <html> element has a lang attribute"},fail:function(e){return"The <html> element does not have a lang attribute"}}},"valid-lang":{impact:"serious",messages:{pass:function(e){return"Value of lang attribute is included in the list of valid languages"},fail:function(e){return"Value of lang attribute not included in the list of valid languages"}}},"xml-lang-mismatch":{impact:"moderate",messages:{pass:function(e){return"Lang and xml:lang attributes have the same base language"},fail:function(e){return"Lang and xml:lang attributes do not have the same base language"}}},"has-alt":{impact:"critical",messages:{pass:function(e){return"Element has an alt attribute"},fail:function(e){return"Element does not have an alt attribute"}}},"alt-space-value":{impact:"critical",messages:{pass:function(e){return"Element has a valid alt attribute value"},fail:function(e){return"Element has an alt attribute containing only a space character, which is not ignored by all screen readers"}}},"duplicate-img-label":{impact:"minor",messages:{pass:function(e){return"Element does not duplicate existing text in <img> alt text"},fail:function(e){return"Element contains <img> element with alt text that duplicates existing text"}}},"non-empty-if-present":{impact:"critical",messages:{pass:function(e){var t="Element ";return e.data?t+="has a non-empty value attribute":t+="does not have a value attribute",t},fail:function(e){return"Element has a value attribute and the value attribute is empty"}}},"non-empty-value":{impact:"critical",messages:{pass:function(e){return"Element has a non-empty value attribute"},fail:function(e){return"Element has no value attribute or the value attribute is empty"}}},"label-content-name-mismatch":{impact:"serious",messages:{pass:function(e){return"Element contains visible text as part of it's accessible name"},fail:function(e){return"Text inside the element is not included in the accessible name"}}},"title-only":{impact:"serious",messages:{pass:function(e){return"Form element does not solely use title attribute for its label"},fail:function(e){return"Only title used to generate label for form element"}}},"implicit-label":{impact:"critical",messages:{pass:function(e){return"Form element has an implicit (wrapped) <label>"},fail:function(e){return"Form element does not have an implicit (wrapped) <label>"}}},"explicit-label":{impact:"critical",messages:{pass:function(e){return"Form element has an explicit <label>"},fail:function(e){return"Form element does not have an explicit <label>"}}},"help-same-as-label":{impact:"minor",messages:{pass:function(e){return"Help text (title or aria-describedby) does not duplicate label text"},fail:function(e){return"Help text (title or aria-describedby) text is the same as the label text"}}},"hidden-explicit-label":{impact:"critical",messages:{pass:function(e){return"Form element has a visible explicit <label>"},fail:function(e){return"Form element has explicit <label> that is hidden"}}},"landmark-is-top-level":{impact:"moderate",messages:{pass:function(e){return"The "+e.data.role+" landmark is at the top level."},fail:function(e){return"The "+e.data.role+" landmark is contained in another landmark."}}},"page-no-duplicate-banner":{impact:"moderate",messages:{pass:function(e){return"Document does not have more than one banner landmark"},fail:function(e){return"Document has more than one banner landmark"}}},"page-no-duplicate-contentinfo":{impact:"moderate",messages:{pass:function(e){return"Document does not have more than one contentinfo landmark"},fail:function(e){return"Document has more than one contentinfo landmark"}}},"page-has-main":{impact:"moderate",messages:{pass:function(e){return"Document has at least one main landmark"},fail:function(e){return"Document does not have a main landmark"}}},"page-no-duplicate-main":{impact:"moderate",messages:{pass:function(e){return"Document does not have more than one main landmark"},fail:function(e){return"Document has more than one main landmark"}}},"landmark-is-unique":{impact:"moderate",messages:{pass:function(e){return"Landmarks must have a unique role or role/label/title (i.e. accessible name) combination"},fail:function(e){return"The landmark must have a unique aria-label, aria-labelledby, or title to make landmarks distinguishable"}}},"has-th":{impact:"serious",messages:{pass:function(e){return"Layout table does not use <th> elements"},fail:function(e){return"Layout table uses <th> elements"}}},"has-caption":{impact:"serious",messages:{pass:function(e){return"Layout table does not use <caption> element"},fail:function(e){return"Layout table uses <caption> element"}}},"has-summary":{impact:"serious",messages:{pass:function(e){return"Layout table does not use summary attribute"},fail:function(e){return"Layout table uses summary attribute"}}},"link-in-text-block":{impact:"serious",messages:{pass:function(e){return"Links can be distinguished from surrounding text in some way other than by color"},fail:function(e){return"Links need to be distinguished from surrounding text in some way other than by color"},incomplete:{bgContrast:"Element's contrast ratio could not be determined. Check for a distinct hover/focus style",bgImage:"Element's contrast ratio could not be determined due to a background image",bgGradient:"Element's contrast ratio could not be determined due to a background gradient",imgNode:"Element's contrast ratio could not be determined because element contains an image node",bgOverlap:"Element's contrast ratio could not be determined because of element overlap",default:"Unable to determine contrast ratio"}}},"focusable-no-name":{impact:"serious",messages:{pass:function(e){return"Element is not in tab order or has accessible text"},fail:function(e){return"Element is in tab order and does not have accessible text"}}},"only-listitems":{impact:"serious",messages:{pass:function(e){return"List element only has direct children that are allowed inside <li> elements"},fail:function(e){return"List element has direct children that are not allowed inside <li> elements"}}},listitem:{impact:"serious",messages:{pass:function(e){return'List item has a <ul>, <ol> or role="list" parent element'},fail:function(e){return'List item does not have a <ul>, <ol> or role="list" parent element'}}},"meta-refresh":{impact:"critical",messages:{pass:function(e){return"<meta> tag does not immediately refresh the page"},fail:function(e){return"<meta> tag forces timed refresh of page"}}},"meta-viewport-large":{impact:"minor",messages:{pass:function(e){return"<meta> tag does not prevent significant zooming on mobile devices"},fail:function(e){return"<meta> tag limits zooming on mobile devices"}}},"meta-viewport":{impact:"critical",messages:{pass:function(e){return"<meta> tag does not disable zooming on mobile devices"},fail:function(e){return e.data+" on <meta> tag disables zooming on mobile devices"}}},"p-as-heading":{impact:"serious",messages:{pass:function(e){return"<p> elements are not styled as headings"},fail:function(e){return"Heading elements should be used instead of styled p elements"}}},"page-has-heading-one":{impact:"moderate",messages:{pass:function(e){return"Page has at least one level-one heading"},fail:function(e){return"Page must have a level-one heading"}}},region:{impact:"moderate",messages:{pass:function(e){return"All page content is contained by landmarks"},fail:function(e){return"Some page content is not contained by landmarks"}}},"html5-scope":{impact:"moderate",messages:{pass:function(e){return"Scope attribute is only used on table header elements (<th>)"},fail:function(e){return"In HTML 5, scope attributes may only be used on table header elements (<th>)"}}},"scope-value":{impact:"critical",messages:{pass:function(e){return"Scope attribute is used correctly"},fail:function(e){return"The value of the scope attribute may only be 'row' or 'col'"}}},"focusable-content":{impact:"moderate",messages:{pass:function(e){return"Element contains focusable elements"},fail:function(e){return"Element should have focusable content"}}},"focusable-element":{impact:"moderate",messages:{pass:function(e){return"Element is focusable"},fail:function(e){return"Element should be focusable"}}},exists:{impact:"minor",messages:{pass:function(e){return"Element does not exist"},fail:function(e){return"Element exists"}}},"skip-link":{impact:"moderate",messages:{pass:function(e){return"Skip link target exists"},incomplete:function(e){return"Skip link target should become visible on activation"},fail:function(e){return"No skip link target"}}},tabindex:{impact:"serious",messages:{pass:function(e){return"Element does not have a tabindex greater than 0"},fail:function(e){return"Element has a tabindex greater than 0"}}},"same-caption-summary":{impact:"minor",messages:{pass:function(e){return"Content of summary attribute and <caption> are not duplicated"},fail:function(e){return"Content of summary attribute and <caption> element are identical"}}},"caption-faked":{impact:"serious",messages:{pass:function(e){return"The first row of a table is not used as a caption"},fail:function(e){return"The first row of the table should be a caption instead of a table cell"}}},"td-has-header":{impact:"critical",messages:{pass:function(e){return"All non-empty data cells have table headers"},fail:function(e){return"Some non-empty data cells do not have table headers"}}},"td-headers-attr":{impact:"serious",messages:{pass:function(e){return"The headers attribute is exclusively used to refer to other cells in the table"},fail:function(e){return"The headers attribute is not exclusively used to refer to other cells in the table"}}},"th-has-data-cells":{impact:"serious",messages:{pass:function(e){return"All table header cells refer to data cells"},fail:function(e){return"Not all table header cells refer to data cells"},incomplete:function(e){return"Table data cells are missing or empty"}}},description:{impact:"critical",messages:{pass:function(e){return"The multimedia element has an audio description track"},incomplete:function(e){return"Check that audio description is available for the element"}}}},failureSummaries:{any:{failureMessage:function(e){var t="Fix any of the following:",n=e;if(n)for(var r=-1,a=n.length-1;r<a;)t+="\n  "+n[r+=1].split("\n").join("\n  ");return t}},none:{failureMessage:function(e){var t="Fix all of the following:",n=e;if(n)for(var r=-1,a=n.length-1;r<a;)t+="\n  "+n[r+=1].split("\n").join("\n  ");return t}}},incompleteFallbackMessage:function(e){return"axe couldn't tell the reason. Time to break out the element inspector!"}},rules:[{id:"accesskeys",selector:"[accesskey]",excludeHidden:!1,tags:["best-practice","cat.keyboard"],all:[],any:[],none:["accesskeys"]},{id:"area-alt",selector:"map area[href]",excludeHidden:!1,tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["non-empty-alt","non-empty-title","aria-label","aria-labelledby"],none:[]},{id:"aria-allowed-attr",matches:function(e,t,n){var r=/^aria-/;if(e.hasAttributes())for(var a=axe.utils.getNodeAttributes(e),o=0,i=a.length;o<i;o++)if(r.test(a[o].name))return!0;return!1},tags:["cat.aria","wcag2a","wcag412"],all:[],any:["aria-allowed-attr"],none:["aria-unsupported-attr"]},{id:"aria-allowed-role",excludeHidden:!1,selector:"[role]",matches:function(e,t,n){return null!==axe.commons.aria.getRole(e,{noImplicit:!0,dpub:!0,fallback:!0})},tags:["cat.aria","best-practice"],all:[],any:[{options:{allowImplicit:!0,ignoredTags:[]},id:"aria-allowed-role"}],none:[]},{id:"aria-dpub-role-fallback",selector:"[role]",matches:function(e,t,n){var r=e.getAttribute("role");return["doc-backlink","doc-biblioentry","doc-biblioref","doc-cover","doc-endnote","doc-glossref","doc-noteref"].includes(r)},tags:["cat.aria","wcag2a","wcag131"],all:["implicit-role-fallback"],any:[],none:[]},{id:"aria-hidden-body",selector:"body",excludeHidden:!1,tags:["cat.aria","wcag2a","wcag412"],all:[],any:["aria-hidden-body"],none:[]},{id:"aria-hidden-focus",selector:'[aria-hidden="true"]',matches:function(e,t,n){var r=axe.commons.dom.getComposedParent;return function e(t){return!t||"true"!==t.getAttribute("aria-hidden")&&e(r(t))}(r(e))},excludeHidden:!1,tags:["cat.name-role-value","wcag2a","wcag412","wcag131"],all:["focusable-disabled","focusable-not-tabbable"],any:[],none:[]},{id:"aria-input-field-name",selector:'[role="combobox"], [role="listbox"], [role="searchbox"], [role="slider"], [role="spinbutton"], [role="textbox"]',matches:function(e,t,n){var r=axe.commons.aria,a=e.nodeName.toUpperCase(),o=r.getRole(e,{noImplicit:!0});return("AREA"!==a||!e.getAttribute("href"))&&(!["INPUT","SELECT","TEXTAREA"].includes(a)&&("IMG"!==a&&("img"!==o||"SVG"===a)&&("BUTTON"!==a&&"button"!==o&&("combobox"!==o||!axe.utils.querySelectorAll(t,'input:not([type="hidden"])').length))))},tags:["wcag2a","wcag412"],all:[],any:["aria-label","aria-labelledby","non-empty-title"],none:["no-implicit-explicit-label"]},{id:"aria-required-attr",selector:"[role]",tags:["cat.aria","wcag2a","wcag412"],all:[],any:["aria-required-attr"],none:[]},{id:"aria-required-children",selector:"[role]",tags:["cat.aria","wcag2a","wcag131"],all:[],any:[{options:{reviewEmpty:["doc-bibliography","doc-endnotes","grid","list","listbox","table","tablist","tree","treegrid","rowgroup"]},id:"aria-required-children"}],none:[]},{id:"aria-required-parent",selector:"[role]",tags:["cat.aria","wcag2a","wcag131"],all:[],any:["aria-required-parent"],none:[]},{id:"aria-roles",selector:"[role]",tags:["cat.aria","wcag2a","wcag412"],all:[],any:[],none:["invalidrole","abstractrole","unsupportedrole"]},{id:"aria-toggle-field-name",selector:'[role="checkbox"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="radio"], [role="switch"]',matches:function(e,t,n){var r=axe.commons.aria,a=e.nodeName.toUpperCase(),o=r.getRole(e,{noImplicit:!0});return("AREA"!==a||!e.getAttribute("href"))&&(!["INPUT","SELECT","TEXTAREA"].includes(a)&&("IMG"!==a&&("img"!==o||"SVG"===a)&&("BUTTON"!==a&&"button"!==o&&("combobox"!==o||!axe.utils.querySelectorAll(t,'input:not([type="hidden"])').length))))},tags:["wcag2a","wcag412"],all:[],any:["aria-label","aria-labelledby","non-empty-title","has-visible-text"],none:["no-implicit-explicit-label"]},{id:"aria-valid-attr-value",matches:function(e,t,n){var r=/^aria-/;if(e.hasAttributes())for(var a=axe.utils.getNodeAttributes(e),o=0,i=a.length;o<i;o++)if(r.test(a[o].name))return!0;return!1},tags:["cat.aria","wcag2a","wcag412"],all:[{options:[],id:"aria-valid-attr-value"},"aria-errormessage"],any:[],none:[]},{id:"aria-valid-attr",matches:function(e,t,n){var r=/^aria-/;if(e.hasAttributes())for(var a=axe.utils.getNodeAttributes(e),o=0,i=a.length;o<i;o++)if(r.test(a[o].name))return!0;return!1},tags:["cat.aria","wcag2a","wcag412"],all:[],any:[{options:[],id:"aria-valid-attr"}],none:[]},{id:"audio-caption",selector:"audio",enabled:!1,excludeHidden:!1,tags:["cat.time-and-media","wcag2a","wcag121","section508","section508.22.a"],all:[],any:[],none:["caption"]},{id:"autocomplete-valid",matches:function(e,t,n){var r=axe.commons,a=r.text,o=r.aria,i=r.dom,u=t.attr("autocomplete");if(!u||""===a.sanitize(u))return!1;var s=t.props.nodeName;if(!1===["textarea","input","select"].includes(s))return!1;if("input"===s&&["submit","reset","button","hidden"].includes(t.props.type))return!1;var l=t.attr("aria-disabled")||"false";if(t.hasAttr("disabled")||"true"===l.toLowerCase())return!1;var c=t.attr("role"),d=t.attr("tabindex");if("-1"===d&&c){var m=o.lookupTable.role[c];if(void 0===m||"widget"!==m.type)return!1}return!("-1"===d&&t.actualNode&&!i.isVisible(t.actualNode,!1)&&!i.isVisible(t.actualNode,!0))},tags:["cat.forms","wcag21aa","wcag135"],all:["autocomplete-valid","autocomplete-appropriate"],any:[],none:[]},{id:"avoid-inline-spacing",selector:"[style]",tags:["wcag21aa","wcag1412"],all:["avoid-inline-spacing"],any:[],none:[]},{id:"blink",selector:"blink",excludeHidden:!1,tags:["cat.time-and-media","wcag2a","wcag222","section508","section508.22.j"],all:[],any:[],none:["is-on-screen"]},{id:"button-name",selector:'button, [role="button"]',tags:["cat.name-role-value","wcag2a","wcag412","section508","section508.22.a"],all:[],any:["button-has-visible-text","aria-label","aria-labelledby","role-presentation","role-none","non-empty-title"],none:[]},{id:"bypass",selector:"html",pageLevel:!0,matches:function(e,t,n){return!!e.querySelector("a[href]")},tags:["cat.keyboard","wcag2a","wcag241","section508","section508.22.o"],all:[],any:["internal-link-present","header-present","landmark"],none:[]},{id:"checkboxgroup",selector:"input[type=checkbox][name]",tags:["cat.forms","best-practice"],all:[],any:["group-labelledby","fieldset"],none:[]},{id:"color-contrast",matches:function(e,t,n){var r=e.nodeName.toUpperCase(),a=e.type;if("true"===e.getAttribute("aria-disabled")||axe.commons.dom.findUpVirtual(t,'[aria-disabled="true"]'))return!1;if("INPUT"===r)return-1===["hidden","range","color","checkbox","radio","image"].indexOf(a)&&!e.disabled;if("SELECT"===r)return!!e.options.length&&!e.disabled;if("TEXTAREA"===r)return!e.disabled;if("OPTION"===r)return!1;if("BUTTON"===r&&e.disabled||axe.commons.dom.findUpVirtual(t,"button[disabled]"))return!1;if("FIELDSET"===r&&e.disabled||axe.commons.dom.findUpVirtual(t,"fieldset[disabled]"))return!1;var o=axe.commons.dom.findUpVirtual(t,"label");if("LABEL"===r||o){var i=e,u=t;o&&(i=o,u=axe.utils.getNodeFromTree(o));var s=axe.commons.dom.getRootNode(i);if((l=i.htmlFor&&s.getElementById(i.htmlFor))&&l.disabled)return!1;if((l=axe.utils.querySelectorAll(u,'input:not([type="hidden"]):not([type="image"]):not([type="button"]):not([type="submit"]):not([type="reset"]), select, textarea')).length&&l[0].actualNode.disabled)return!1}if(e.getAttribute("id")){var l,c=axe.utils.escapeSelector(e.getAttribute("id"));if((l=axe.commons.dom.getRootNode(e).querySelector("[aria-labelledby~="+c+"]"))&&l.disabled)return!1}if(""===axe.commons.text.visibleVirtual(t,!1,!0))return!1;var d,m,p=document.createRange(),f=t.children,h=f.length;for(m=0;m<h;m++)3===(d=f[m]).actualNode.nodeType&&""!==axe.commons.text.sanitize(d.actualNode.nodeValue)&&p.selectNodeContents(d.actualNode);var b=p.getClientRects();for(h=b.length,m=0;m<h;m++)if(axe.commons.dom.visuallyOverlaps(b[m],e))return!0;return!1},excludeHidden:!1,options:{noScroll:!1},tags:["cat.color","wcag2aa","wcag143"],all:[],any:["color-contrast"],none:[]},{id:"css-orientation-lock",selector:"html",tags:["cat.structure","wcag134","wcag21aa","experimental"],all:["css-orientation-lock"],any:[],none:[],preload:!0},{id:"definition-list",selector:"dl",matches:function(e,t,n){return!e.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:[],none:["structured-dlitems","only-dlitems"]},{id:"dlitem",selector:"dd, dt",matches:function(e,t,n){return!e.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:["dlitem"],none:[]},{id:"document-title",selector:"html",matches:function(e,t,n){return e.ownerDocument.defaultView.self===e.ownerDocument.defaultView.top},tags:["cat.text-alternatives","wcag2a","wcag242"],all:[],any:["doc-has-title"],none:[]},{id:"duplicate-id-active",selector:"[id]",matches:function(e,t,n){var r=axe.commons,a=r.dom,o=r.aria,i=e.getAttribute("id").trim(),u='*[id="'.concat(axe.utils.escapeSelector(i),'"]');return Array.from(a.getRootNode(e).querySelectorAll(u)).some(a.isFocusable)&&!o.isAccessibleRef(e)},excludeHidden:!1,tags:["cat.parsing","wcag2a","wcag411"],all:[],any:["duplicate-id-active"],none:[]},{id:"duplicate-id-aria",selector:"[id]",matches:function(e,t,n){return axe.commons.aria.isAccessibleRef(e)},excludeHidden:!1,tags:["cat.parsing","wcag2a","wcag411"],all:[],any:["duplicate-id-aria"],none:[]},{id:"duplicate-id",selector:"[id]",matches:function(e,t,n){var r=axe.commons,a=r.dom,o=r.aria,i=e.getAttribute("id").trim(),u='*[id="'.concat(axe.utils.escapeSelector(i),'"]');return Array.from(a.getRootNode(e).querySelectorAll(u)).every(function(e){return!a.isFocusable(e)})&&!o.isAccessibleRef(e)},excludeHidden:!1,tags:["cat.parsing","wcag2a","wcag411"],all:[],any:["duplicate-id"],none:[]},{id:"empty-heading",selector:'h1, h2, h3, h4, h5, h6, [role="heading"]',matches:function(e,t,n){var r;return e.hasAttribute("role")&&(r=e.getAttribute("role").split(/\s+/i).filter(axe.commons.aria.isValidRole)),r&&0<r.length?r.includes("heading"):"heading"===axe.commons.aria.implicitRole(e)},tags:["cat.name-role-value","best-practice"],all:[],any:["has-visible-text"],none:[]},{id:"focus-order-semantics",selector:"div, h1, h2, h3, h4, h5, h6, [role=heading], p, span",matches:function(e,t,n){return axe.commons.dom.insertedIntoFocusOrder(e)},tags:["cat.keyboard","best-practice","experimental"],all:[],any:[{options:[],id:"has-widget-role"},{options:[],id:"valid-scrollable-semantics"}],none:[]},{id:"form-field-multiple-labels",selector:"input, select, textarea",matches:function(e,t,n){if("input"!==e.nodeName.toLowerCase()||!1===e.hasAttribute("type"))return!0;var r=e.getAttribute("type").toLowerCase();return!1===["hidden","image","button","submit","reset"].includes(r)},tags:["cat.forms","wcag2a","wcag332"],all:[],any:[],none:["multiple-label"]},{id:"frame-tested",selector:"frame, iframe",tags:["cat.structure","review-item","best-practice"],all:[{options:{isViolation:!1},id:"frame-tested"}],any:[],none:[]},{id:"frame-title-unique",selector:"frame[title], iframe[title]",matches:function(e,t,n){var r=e.getAttribute("title");return!(!r||!axe.commons.text.sanitize(r).trim())},tags:["cat.text-alternatives","best-practice"],all:[],any:[],none:["unique-frame-title"]},{id:"frame-title",selector:"frame, iframe",tags:["cat.text-alternatives","wcag2a","wcag241","wcag412","section508","section508.22.i"],all:[],any:["aria-label","aria-labelledby","non-empty-title","role-presentation","role-none"],none:[]},{id:"heading-order",selector:"h1, h2, h3, h4, h5, h6, [role=heading]",matches:function(e,t,n){var r;return e.hasAttribute("role")&&(r=e.getAttribute("role").split(/\s+/i).filter(axe.commons.aria.isValidRole)),r&&0<r.length?r.includes("heading"):"heading"===axe.commons.aria.implicitRole(e)},tags:["cat.semantics","best-practice"],all:[],any:["heading-order"],none:[]},{id:"hidden-content",selector:"*",excludeHidden:!1,tags:["cat.structure","experimental","review-item","best-practice"],all:[],any:["hidden-content"],none:[]},{id:"html-has-lang",selector:"html",matches:function(e,t,n){return e.ownerDocument.defaultView.self===e.ownerDocument.defaultView.top},tags:["cat.language","wcag2a","wcag311"],all:[],any:["has-lang"],none:[]},{id:"html-lang-valid",selector:"html[lang], html[xml\\:lang]",tags:["cat.language","wcag2a","wcag311"],all:[],any:[],none:["valid-lang"]},{id:"html-xml-lang-mismatch",selector:"html[lang][xml\\:lang]",matches:function(e,t,n){var r=axe.utils.getBaseLang,a=r(e.getAttribute("lang")),o=r(e.getAttribute("xml:lang"));return axe.utils.validLangs().includes(a)&&axe.utils.validLangs().includes(o)},tags:["cat.language","wcag2a","wcag311"],all:["xml-lang-mismatch"],any:[],none:[]},{id:"image-alt",selector:"img",tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["has-alt","aria-label","aria-labelledby","non-empty-title","role-presentation","role-none"],none:["alt-space-value"]},{id:"image-redundant-alt",selector:"img",tags:["cat.text-alternatives","best-practice"],all:[],any:[],none:["duplicate-img-label"]},{id:"input-button-name",selector:'input[type="button"], input[type="submit"], input[type="reset"]',tags:["cat.name-role-value","wcag2a","wcag412","section508","section508.22.a"],all:[],any:["non-empty-if-present","non-empty-value","aria-label","aria-labelledby","role-presentation","role-none","non-empty-title"],none:[]},{id:"input-image-alt",selector:'input[type="image"]',tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["non-empty-alt","aria-label","aria-labelledby","non-empty-title"],none:[]},{id:"label-content-name-mismatch",matches:function(e,t,n){var r=axe.commons,a=r.aria,o=r.text,i=a.getRole(e);return!!i&&(!!a.lookupTable.rolesOfType.widget.includes(i)&&(!!a.getRolesWithNameFromContents().includes(i)&&(!(!o.sanitize(a.arialabelText(e))&&!o.sanitize(a.arialabelledbyText(e)))&&!!o.sanitize(o.visibleVirtual(t)))))},tags:["wcag21a","wcag253","experimental"],all:[],any:["label-content-name-mismatch"],none:[]},{id:"label-title-only",selector:"input, select, textarea",matches:function(e,t,n){if("input"!==e.nodeName.toLowerCase()||!1===e.hasAttribute("type"))return!0;var r=e.getAttribute("type").toLowerCase();return!1===["hidden","image","button","submit","reset"].includes(r)},tags:["cat.forms","best-practice"],all:[],any:[],none:["title-only"]},{id:"label",selector:"input, select, textarea",matches:function(e,t,n){if("input"!==e.nodeName.toLowerCase()||!1===e.hasAttribute("type"))return!0;var r=e.getAttribute("type").toLowerCase();return!1===["hidden","image","button","submit","reset"].includes(r)},tags:["cat.forms","wcag2a","wcag332","wcag131","section508","section508.22.n"],all:[],any:["aria-label","aria-labelledby","implicit-label","explicit-label","non-empty-title"],none:["help-same-as-label","hidden-explicit-label"]},{id:"landmark-banner-is-top-level",selector:"header:not([role]), [role=banner]",matches:function(e,t,n){return e.hasAttribute("role")||!axe.commons.dom.findUpVirtual(t,"article, aside, main, nav, section")},tags:["cat.semantics","best-practice"],all:[],any:["landmark-is-top-level"],none:[]},{id:"landmark-complementary-is-top-level",selector:"aside:not([role]), [role=complementary]",tags:["cat.semantics","best-practice"],all:[],any:["landmark-is-top-level"],none:[]},{id:"landmark-contentinfo-is-top-level",selector:"footer:not([role]), [role=contentinfo]",matches:function(e,t,n){return e.hasAttribute("role")||!axe.commons.dom.findUpVirtual(t,"article, aside, main, nav, section")},tags:["cat.semantics","best-practice"],all:[],any:["landmark-is-top-level"],none:[]},{id:"landmark-main-is-top-level",selector:"main:not([role]), [role=main]",tags:["cat.semantics","best-practice"],all:[],any:["landmark-is-top-level"],none:[]},{id:"landmark-no-duplicate-banner",selector:"html",tags:["cat.semantics","best-practice"],all:[],any:[{options:{selector:"header:not([role]), [role=banner]",nativeScopeFilter:"article, aside, main, nav, section"},id:"page-no-duplicate-banner"}],none:[]},{id:"landmark-no-duplicate-contentinfo",selector:"html",tags:["cat.semantics","best-practice"],all:[],any:[{options:{selector:"footer:not([role]), [role=contentinfo]",nativeScopeFilter:"article, aside, main, nav, section"},id:"page-no-duplicate-contentinfo"}],none:[]},{id:"landmark-one-main",selector:"html",tags:["cat.semantics","best-practice"],all:[{options:{selector:"main:not([role]), [role='main']"},id:"page-has-main"},{options:{selector:"main:not([role]), [role='main']"},id:"page-no-duplicate-main"}],any:[],none:[]},{id:"landmark-unique",selector:"[role=banner], [role=complementary], [role=contentinfo], [role=main], [role=navigation], [role=region], [role=search], [role=form], form, footer, header, aside, main, nav, section",tags:["cat.semantics","best-practice"],matches:function(e,t,n){var o=["article","aside","main","nav","section"].join(",");return function(e){var t=e.actualNode,n=axe.commons.aria.getRolesByType("landmark"),r=axe.commons.aria.getRole(t);if(!r)return!1;var a=t.nodeName.toUpperCase();return"HEADER"===a||"FOOTER"===a?function(e){return!axe.commons.dom.findUpVirtual(e,o)}(e):"SECTION"!==a&&"FORM"!==a?0<=n.indexOf(r)||"region"===r:!!axe.commons.text.accessibleTextVirtual(e)}(t)&&axe.commons.dom.isVisible(e,!0)},all:[],any:["landmark-is-unique"],none:[]},{id:"layout-table",selector:"table",matches:function(e,t,n){var r=(e.getAttribute("role")||"").toLowerCase();return!(("presentation"===r||"none"===r)&&!axe.commons.dom.isFocusable(e)||axe.commons.table.isDataTable(e))},tags:["cat.semantics","wcag2a","wcag131"],all:[],any:[],none:["has-th","has-caption","has-summary"]},{id:"link-in-text-block",selector:"a[href], [role=link]",matches:function(e,t,n){var r=axe.commons.text.sanitize(e.textContent),a=e.getAttribute("role");return(!a||"link"===a)&&(!!r&&(!!axe.commons.dom.isVisible(e,!1)&&axe.commons.dom.isInTextBlock(e)))},excludeHidden:!1,tags:["cat.color","experimental","wcag2a","wcag141"],all:["link-in-text-block"],any:[],none:[]},{id:"link-name",selector:"a[href], [role=link][href]",matches:function(e,t,n){return"button"!==e.getAttribute("role")},tags:["cat.name-role-value","wcag2a","wcag412","wcag244","section508","section508.22.a"],all:[],any:["has-visible-text","aria-label","aria-labelledby","role-presentation","role-none"],none:["focusable-no-name"]},{id:"list",selector:"ul, ol",matches:function(e,t,n){return!e.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:[],none:["only-listitems"]},{id:"listitem",selector:"li",matches:function(e,t,n){return!e.getAttribute("role")},tags:["cat.structure","wcag2a","wcag131"],all:[],any:["listitem"],none:[]},{id:"marquee",selector:"marquee",excludeHidden:!1,tags:["cat.parsing","wcag2a","wcag222"],all:[],any:[],none:["is-on-screen"]},{id:"meta-refresh",selector:'meta[http-equiv="refresh"]',excludeHidden:!1,tags:["cat.time","wcag2a","wcag2aaa","wcag221","wcag224","wcag325"],all:[],any:["meta-refresh"],none:[]},{id:"meta-viewport-large",selector:'meta[name="viewport"]',excludeHidden:!1,tags:["cat.sensory-and-visual-cues","best-practice"],all:[],any:[{options:{scaleMinimum:5,lowerBound:2},id:"meta-viewport-large"}],none:[]},{id:"meta-viewport",selector:'meta[name="viewport"]',excludeHidden:!1,tags:["cat.sensory-and-visual-cues","wcag2aa","wcag144"],all:[],any:[{options:{scaleMinimum:2},id:"meta-viewport"}],none:[]},{id:"object-alt",selector:"object",tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["has-visible-text","aria-label","aria-labelledby","non-empty-title","role-presentation","role-none"],none:[]},{id:"p-as-heading",selector:"p",matches:function(e,t,n){var r=Array.from(e.parentNode.childNodes),a=e.textContent.trim();return!(0===a.length||2<=(a.match(/[.!?:;](?![.!?:;])/g)||[]).length)&&0!==r.slice(r.indexOf(e)+1).filter(function(e){return"P"===e.nodeName.toUpperCase()&&""!==e.textContent.trim()}).length},tags:["cat.semantics","wcag2a","wcag131","experimental"],all:[{options:{margins:[{weight:150,italic:!0},{weight:150,size:1.15},{italic:!0,size:1.15},{size:1.4}]},id:"p-as-heading"}],any:[],none:[]},{id:"page-has-heading-one",selector:"html",tags:["cat.semantics","best-practice"],all:[{options:{selector:'h1:not([role]), [role="heading"][aria-level="1"]'},id:"page-has-heading-one"}],any:[],none:[]},{id:"radiogroup",selector:"input[type=radio][name]",tags:["cat.forms","best-practice"],all:[],any:["group-labelledby","fieldset"],none:[]},{id:"region",selector:"html",pageLevel:!0,tags:["cat.keyboard","best-practice"],all:[],any:["region"],none:[]},{id:"role-img-alt",selector:"[role='img']:not(svg):not(img):not(area):not(input):not(object)",tags:["cat.text-alternatives","wcag2a","wcag111","section508","section508.22.a"],all:[],any:["aria-label","aria-labelledby","non-empty-title"],none:[]},{id:"scope-attr-valid",selector:"td[scope], th[scope]",tags:["cat.tables","best-practice"],all:["html5-scope","scope-value"],any:[],none:[]},{id:"scrollable-region-focusable",matches:function(e,t,n){var r=axe.utils.querySelectorAll,a=axe.commons.dom.hasContentVirtual;return!1!=!!axe.utils.getScroll(e,13)&&!!r(t,"*").some(function(e){return a(e,!0,!0)})},tags:["wcag2a","wcag211"],all:[],any:["focusable-content","focusable-element"],none:[]},{id:"server-side-image-map",selector:"img[ismap]",tags:["cat.text-alternatives","wcag2a","wcag211","section508","section508.22.f"],all:[],any:[],none:["exists"]},{id:"skip-link",selector:'a[href^="#"], a[href^="/#"]',matches:function(e,t,n){return axe.commons.dom.isSkipLink(e)},tags:["cat.keyboard","best-practice"],all:[],any:["skip-link"],none:[]},{id:"tabindex",selector:"[tabindex]",tags:["cat.keyboard","best-practice"],all:[],any:["tabindex"],none:[]},{id:"table-duplicate-name",selector:"table",tags:["cat.tables","best-practice"],all:[],any:[],none:["same-caption-summary"]},{id:"table-fake-caption",selector:"table",matches:function(e,t,n){return axe.commons.table.isDataTable(e)},tags:["cat.tables","experimental","wcag2a","wcag131","section508","section508.22.g"],all:["caption-faked"],any:[],none:[]},{id:"td-has-header",selector:"table",matches:function(e,t,n){if(axe.commons.table.isDataTable(e)){var r=axe.commons.table.toArray(e);return 3<=r.length&&3<=r[0].length&&3<=r[1].length&&3<=r[2].length}return!1},tags:["cat.tables","experimental","wcag2a","wcag131","section508","section508.22.g"],all:["td-has-header"],any:[],none:[]},{id:"td-headers-attr",selector:"table",tags:["cat.tables","wcag2a","wcag131","section508","section508.22.g"],all:["td-headers-attr"],any:[],none:[]},{id:"th-has-data-cells",selector:"table",matches:function(e,t,n){return axe.commons.table.isDataTable(e)},tags:["cat.tables","wcag2a","wcag131","section508","section508.22.g"],all:["th-has-data-cells"],any:[],none:[]},{id:"valid-lang",selector:"[lang], [xml\\:lang]",matches:function(e,t,n){return"html"!==e.nodeName.toLowerCase()},tags:["cat.language","wcag2aa","wcag312"],all:[],any:[],none:["valid-lang"]},{id:"video-caption",selector:"video",excludeHidden:!1,tags:["cat.text-alternatives","wcag2a","wcag122","section508","section508.22.a"],all:[],any:[],none:["caption"]},{id:"video-description",selector:"video",excludeHidden:!1,tags:["cat.text-alternatives","wcag2aa","wcag125","section508","section508.22.b"],all:[],any:[],none:["description"]}],checks:[{id:"abstractrole",evaluate:function(e,t,n,r){return"abstract"===axe.commons.aria.getRoleType(e.getAttribute("role"))}},{id:"aria-allowed-attr",evaluate:function(e,t,n,r){t=t||{};var a,o,i,u=[],s=e.getAttribute("role"),l=axe.utils.getNodeAttributes(e);if(s=s||axe.commons.aria.implicitRole(e),i=axe.commons.aria.allowedAttr(s),Array.isArray(t[s])&&(i=axe.utils.uniqueArray(t[s].concat(i))),s&&i)for(var c=0,d=l.length;c<d;c++)o=(a=l[c]).name,axe.commons.aria.validateAttr(o)&&!i.includes(o)&&u.push(o+'="'+a.nodeValue+'"');return!u.length||(this.data(u),!1)}},{id:"aria-allowed-role",evaluate:function(e,t,n,r){var a=axe.commons.dom,o=t||{},i=o.allowImplicit,u=void 0===i||i,s=o.ignoredTags,l=void 0===s?[]:s,c=e.nodeName.toUpperCase();if(l.map(function(e){return e.toUpperCase()}).includes(c))return!0;var d=axe.commons.aria.getElementUnallowedRoles(e,u);if(d.length){if(this.data(d),!a.isVisible(e,!0))return;return!1}return!0},options:{allowImplicit:!0,ignoredTags:[]}},{id:"aria-hidden-body",evaluate:function(e,t,n,r){return"true"!==e.getAttribute("aria-hidden")}},{id:"aria-errormessage",evaluate:function(n,e,t,r){var a=axe.commons,o=a.aria,i=a.dom;e=Array.isArray(e)?e:[];var u=n.getAttribute("aria-errormessage"),s=n.hasAttribute("aria-errormessage"),l=i.getRootNode(n);return!(-1===e.indexOf(u)&&s&&!function(e){if(""===e.trim())return o.lookupTable.attributes["aria-errormessage"].allowEmpty;var t=e&&l.getElementById(e);return t?"alert"===t.getAttribute("role")||"assertive"===t.getAttribute("aria-live")||-1<axe.utils.tokenList(n.getAttribute("aria-describedby")||"").indexOf(e):void 0}(u))||(this.data(axe.utils.tokenList(u)),!1)}},{id:"has-widget-role",evaluate:function(e,t,n,r){var a=e.getAttribute("role");if(null===a)return!1;var o=axe.commons.aria.getRoleType(a);return"widget"===o||"composite"===o},options:[]},{id:"implicit-role-fallback",evaluate:function(e,t,n,r){var a=e.getAttribute("role");if(null===a||!axe.commons.aria.isValidRole(a))return!0;var o=axe.commons.aria.getRoleType(a);return axe.commons.aria.implicitRole(e)===o}},{id:"invalidrole",evaluate:function(e,t,n,r){return!axe.commons.aria.isValidRole(e.getAttribute("role"),{allowAbstract:!0})}},{id:"no-implicit-explicit-label",evaluate:function(e,t,n,r){var a=axe.commons,o=a.aria,i=a.text,u=o.getRole(e,{noImplicit:!0});this.data(u);var s=i.sanitize(i.labelText(n)).toLowerCase(),l=i.sanitize(i.accessibleText(e)).toLowerCase();return!(!l&&!s)&&(!((l||!s)&&l.includes(s))&&void 0)}},{id:"aria-required-attr",evaluate:function(e,t,n,r){t=t||{};var a=[],o=axe.commons.forms,i=o.isNativeTextbox,u=o.isNativeSelect,s=o.isAriaTextbox,l=o.isAriaListbox,c=o.isAriaCombobox,d=o.isAriaRange,m={"aria-valuenow":function(){return!(i(e)||u(e)||s(e)||l(e)||c(e)||d(e)&&e.hasAttribute("aria-valuenow"))}};if(e.hasAttributes()){var p=e.getAttribute("role"),f=axe.commons.aria.requiredAttr(p);if(Array.isArray(t[p])&&(f=axe.utils.uniqueArray(t[p],f)),p&&f)for(var h=0,b=f.length;h<b;h++){var g=f[h];e.getAttribute(g)||m[g]&&!m[g]()||a.push(g)}}return!a.length||(this.data(a),!1)}},{id:"aria-required-children",evaluate:function(e,t,m,n){var r=axe.commons.aria.requiredOwned,i=axe.commons.aria.implicitNodes,u=axe.utils.matchesSelector,p=axe.commons.dom.idrefs,a=t&&Array.isArray(t.reviewEmpty)?t.reviewEmpty:[];function f(e,t,n,r){if(null===e)return!1;var a=i(n),o=['[role="'+n+'"]'];return a&&(o=o.concat(a)),o=o.join(","),r&&u(e,o)||!!axe.utils.querySelectorAll(t,o)[0]}function h(e,t){var n,r;for(n=0,r=e.length;n<r;n++)if(null!==e[n]){var a=axe.utils.getNodeFromTree(e[n]);if(f(e[n],a,t,!0))return!0}return!1}var o=e.getAttribute("role"),s=r(o);if(!s)return!0;var l=!1,c=s.one;if(!c){l=!0;c=s.all}var d=function(e,t,n,r){var a,o=t.length,i=[],u=p(e,"aria-owns");for(a=0;a<o;a++){var s=t[a];if(f(e,m,s)||h(u,s)){if(!n)return null}else n&&i.push(s)}if("combobox"===r){var l=i.indexOf("textbox");0<=l&&"INPUT"===e.nodeName.toUpperCase()&&["text","search","email","url","tel"].includes(e.type)&&i.splice(l,1);var c=i.indexOf("listbox"),d=e.getAttribute("aria-expanded");0<=c&&(!d||"false"===d)&&i.splice(c,1)}return i.length?i:!n&&t.length?t:null}(e,c,l,o);return!d||(this.data(d),!(!a.includes(o)||0!==e.children.length||0!==p(e,"aria-owns").length)&&void 0)},options:{reviewEmpty:["doc-bibliography","doc-endnotes","grid","list","listbox","table","tablist","tree","treegrid","rowgroup"]}},{id:"aria-required-parent",evaluate:function(e,t,n,r){function u(e){return(axe.commons.aria.implicitNodes(e)||[]).concat('[role="'+e+'"]').join(",")}function a(e,t,n){var r,a,o=e.actualNode.getAttribute("role"),i=[];if(!(t=t||axe.commons.aria.requiredContext(o)))return null;for(r=0,a=t.length;r<a;r++){if(n&&axe.utils.matchesSelector(e.actualNode,u(t[r])))return null;if(axe.commons.dom.findUpVirtual(e,u(t[r])))return null;i.push(t[r])}return i}var o=a(n);if(!o)return!0;var i=function(e){for(var t=[],n=null;e;){if(e.getAttribute("id")){var r=axe.utils.escapeSelector(e.getAttribute("id"));(n=axe.commons.dom.getRootNode(e).querySelector("[aria-owns~=".concat(r,"]")))&&t.push(n)}e=e.parentElement}return t.length?t:null}(e);if(i)for(var s=0,l=i.length;s<l;s++)if(!(o=a(axe.utils.getNodeFromTree(i[s]),o,!0)))return!0;return this.data(o),!1}},{id:"aria-unsupported-attr",evaluate:function(o,e,t,n){var i=o.nodeName.toUpperCase(),u=axe.commons.aria.lookupTable,s=axe.commons.aria.getRole(o),r=Array.from(axe.utils.getNodeAttributes(o)).filter(function(e){var t=e.name,n=u.attributes[t];if(!axe.commons.aria.validateAttr(t))return!1;var r=n.unsupported;if("object"!==S(r))return!!r;var a=axe.commons.matches(o,r.exceptions);return Object.keys(u.evaluateRoleForElement).includes(i)?!u.evaluateRoleForElement[i]({node:o,role:s,out:a}):!a}).map(function(e){return e.name.toString()});return!!r.length&&(this.data(r),!0)}},{id:"unsupportedrole",evaluate:function(e,t,n,r){return axe.commons.aria.isUnsupportedRole(axe.commons.aria.getRole(e))}},{id:"aria-valid-attr-value",evaluate:function(e,t,n,r){t=Array.isArray(t)?t:[];for(var a=[],o=[],i=/^aria-/,u=axe.utils.getNodeAttributes(e),s=["aria-errormessage"],l={"aria-controls":function(){return"false"!==e.getAttribute("aria-expanded")&&"false"!==e.getAttribute("aria-selected")},"aria-owns":function(){return"false"!==e.getAttribute("aria-expanded")},"aria-describedby":function(){axe.commons.aria.validateAttrValue(e,"aria-describedby")||a.push('aria-describedby="'.concat(e.getAttribute("aria-describedby"),'"'))}},c=0,d=u.length;c<d;c++){var m=u[c],p=m.name;s.includes(p)||-1!==t.indexOf(p)||!i.test(p)||l[p]&&!l[p]()||axe.commons.aria.validateAttrValue(e,p)||o.push("".concat(p,'="').concat(m.nodeValue,'"'))}if(!a.length)return!o.length||(this.data(o),!1);this.data(a)},options:[]},{id:"aria-valid-attr",evaluate:function(e,t,n,r){t=Array.isArray(t)?t:[];for(var a,o=[],i=/^aria-/,u=axe.utils.getNodeAttributes(e),s=0,l=u.length;s<l;s++)a=u[s].name,-1===t.indexOf(a)&&i.test(a)&&!axe.commons.aria.validateAttr(a)&&o.push(a);return!o.length||(this.data(o),!1)},options:[]},{id:"valid-scrollable-semantics",evaluate:function(e,t,n,r){var a,o,i,u={ARTICLE:!0,ASIDE:!0,NAV:!0,SECTION:!0},s={application:!0,banner:!1,complementary:!0,contentinfo:!0,form:!0,main:!0,navigation:!0,region:!0,search:!1};return(o=(i=e).getAttribute("role"))&&s[o.toLowerCase()]||!1||(a=i.nodeName.toUpperCase(),u[a]||!1)},options:[]},{id:"color-contrast",evaluate:function(e,t,n,r){var a=axe.commons,o=a.dom,i=a.color,u=a.text;if(!o.isVisible(e,!1))return!0;var s,l=!!(t||{}).noScroll,c=[],d=i.getBackgroundColor(e,c,l),m=i.getForegroundColor(e,l),p=window.getComputedStyle(e),f=parseFloat(p.getPropertyValue("font-size")),h=p.getPropertyValue("font-weight"),b=-1!==["bold","bolder","600","700","800","900"].indexOf(h),g=i.hasValidContrastRatio(d,m,f,b),y=Math.floor(100*g.contrastRatio)/100;null===d&&(s=i.incompleteData.get("bgColor"));var v=1==y,D=1===u.visibleVirtual(n,!1,!0).length;v?s=i.incompleteData.set("bgColor","equalRatio"):D&&(s="shortTextContent");var w={fgColor:m?m.toHexString():void 0,bgColor:d?d.toHexString():void 0,contrastRatio:g?y:void 0,fontSize:"".concat((72*f/96).toFixed(1),"pt (").concat(f,"px)"),fontWeight:b?"bold":"normal",missingData:s,expectedContrastRatio:g.expectedContrastRatio+":1"};return this.data(w),null===m||null===d||v||D&&!g.isValid?(s=null,i.incompleteData.clear(),void this.relatedNodes(c)):(g.isValid||this.relatedNodes(c),g.isValid)}},{id:"link-in-text-block",evaluate:function(e,t,n,r){var a=axe.commons,o=a.color,i=a.dom;function u(e,t){var n=e.getRelativeLuminance(),r=t.getRelativeLuminance();return(Math.max(n,r)+.05)/(Math.min(n,r)+.05)}var s=["block","list-item","table","flex","grid","inline-block"];function l(e){var t=window.getComputedStyle(e).getPropertyValue("display");return-1!==s.indexOf(t)||"table-"===t.substr(0,6)}if(l(e))return!1;for(var c,d,m=i.getComposedParent(e);1===m.nodeType&&!l(m);)m=i.getComposedParent(m);if(this.relatedNodes([m]),o.elementIsDistinct(e,m))return!0;if(c=o.getForegroundColor(e),d=o.getForegroundColor(m),c&&d){var p,f=u(c,d);return 1===f||(3<=f?(axe.commons.color.incompleteData.set("fgColor","bgContrast"),this.data({missingData:axe.commons.color.incompleteData.get("fgColor")}),void axe.commons.color.incompleteData.clear()):(c=o.getBackgroundColor(e),d=o.getBackgroundColor(m),(!c||!d||3<=u(c,d))&&(p=c&&d?"bgContrast":axe.commons.color.incompleteData.get("bgColor"),axe.commons.color.incompleteData.set("fgColor",p),this.data({missingData:axe.commons.color.incompleteData.get("fgColor")}),void axe.commons.color.incompleteData.clear())))}}},{id:"autocomplete-appropriate",evaluate:function(e,t,n,r){if("input"!==n.props.nodeName)return!0;var a=["text","search","number"],o=["text","search","url"],i={bday:["text","search","date"],email:["text","search","email"],"cc-exp":["text","search","month"],"street-address":["text"],tel:["text","search","tel"],"cc-exp-month":a,"cc-exp-year":a,"transaction-amount":a,"bday-day":a,"bday-month":a,"bday-year":a,"new-password":["text","search","password"],"current-password":["text","search","password"],url:o,photo:o,impp:o};"object"===S(t)&&Object.keys(t).forEach(function(e){i[e]||(i[e]=[]),i[e]=i[e].concat(t[e])});var u=n.attr("autocomplete").split(/\s+/g).map(function(e){return e.toLowerCase()}),s=u[u.length-1];if(axe.commons.text.autocomplete.stateTerms.includes(s))return!0;var l=i[s],c=n.hasAttr("type")?axe.commons.text.sanitize(n.attr("type")).toLowerCase():"text";return c=axe.utils.validInputTypes().includes(c)?c:"text",void 0===l?"text"===c:l.includes(c)}},{id:"autocomplete-valid",evaluate:function(e,t,n,r){var a=n.attr("autocomplete")||"";return axe.commons.text.isValidAutocomplete(a,t)}},{id:"fieldset",evaluate:function(e,t,n,r){var o,i=this;function u(e,t){return axe.utils.toArray(e.querySelectorAll('select,textarea,button,input:not([name="'+t+'"]):not([type="hidden"])'))}var a={name:e.getAttribute("name"),type:e.getAttribute("type")},s=function(e){var t=axe.utils.escapeSelector(e.actualNode.name),n=axe.commons.dom.getRootNode(e.actualNode).querySelectorAll('input[type="'+axe.utils.escapeSelector(e.actualNode.type)+'"][name="'+t+'"]');if(n.length<2)return!0;var r=axe.commons.dom.findUpVirtual(e,"fieldset"),a=axe.commons.dom.findUpVirtual(e,'[role="group"]'+("radio"===e.actualNode.type?',[role="radiogroup"]':""));return a||r?r?function(e,t){var n=e.firstElementChild;if(!n||"LEGEND"!==n.nodeName.toUpperCase())return i.relatedNodes([e]),!(o="no-legend");if(!axe.commons.text.accessibleText(n))return i.relatedNodes([n]),!(o="empty-legend");var r=u(e,t);return!r.length||(i.relatedNodes(r),!(o="mixed-inputs"))}(r,t):function(e,t){var n=axe.commons.dom.idrefs(e,"aria-labelledby").some(function(e){return e&&axe.commons.text.accessibleText(e)}),r=e.getAttribute("aria-label");if(!(n||r&&axe.commons.text.sanitize(r)))return i.relatedNodes(e),!(o="no-group-label");var a=u(e,t);return!a.length||(i.relatedNodes(a),!(o="group-mixed-inputs"))}(a,t):(o="no-group",i.relatedNodes(function(e,t){return axe.utils.toArray(e).filter(function(e){return e!==t})}(n,e.actualNode)),!1)}(n);return s||(a.failureCode=o),this.data(a),s},after:function(e,t){var r={};return e.filter(function(e){if(e.result)return!0;var t=e.data;if(t){if(r[t.type]=r[t.type]||{},!r[t.type][t.name])return r[t.type][t.name]=[t],!0;var n=r[t.type][t.name].some(function(e){return e.failureCode===t.failureCode});return n||r[t.type][t.name].push(t),!n}return!1})}},{id:"group-labelledby",evaluate:function(n,e,t,r){var a=axe.commons,o=a.dom,i=a.text,u=axe.utils.escapeSelector(n.type),s=axe.utils.escapeSelector(n.name),l=o.getRootNode(n),c={name:n.name,type:n.type},d=Array.from(l.querySelectorAll('input[type="'.concat(u,'"][name="').concat(s,'"]')));if(d.length<=1)return this.data(c),!0;var m=o.idrefs(n,"aria-labelledby").filter(function(e){return!!e}),p=m.slice();d.forEach(function(e){if(e!==n){var t=o.idrefs(e,"aria-labelledby").filter(function(e){return e});m=m.filter(function(e){return t.includes(e)}),p=p.filter(function(e){return!t.includes(e)})}});var f={inLabelledByContext:!0};return p=p.filter(function(e){return i.accessibleText(e,f)}),m=m.filter(function(e){return i.accessibleText(e,f)}),0<p.length&&0<m.length?(this.data(c),!0):(0<p.length&&0===m.length?c.failureCode="no-shared-label":0===p.length&&0<m.length&&(c.failureCode="no-unique-label"),this.data(c),!1)},after:function(e,t){var n={};return e.filter(function(e){var t=e.data;return!(!t||(n[t.type]=n[t.type]||{},n[t.type][t.name]))&&(n[t.type][t.name]=!0)})}},{id:"accesskeys",evaluate:function(e,t,n,r){return axe.commons.dom.isVisible(e,!1)&&(this.data(e.getAttribute("accesskey")),this.relatedNodes([e])),!0},after:function(e,t){var n={};return e.filter(function(e){if(!e.data)return!1;var t=e.data.toUpperCase();return n[t]?(n[t].relatedNodes.push(e.relatedNodes[0]),!1):((n[t]=e).relatedNodes=[],!0)}).map(function(e){return e.result=!!e.relatedNodes.length,e})}},{id:"focusable-content",evaluate:function(e,t,n,r){var a=n.tabbableElements;return!!a&&0<a.filter(function(e){return e!==n}).length}},{id:"focusable-disabled",evaluate:function(e,t,n,r){var a=["BUTTON","FIELDSET","INPUT","SELECT","TEXTAREA"],o=n.tabbableElements;if(!o||!o.length)return!0;var i=o.reduce(function(e,t){var n=t.actualNode,r=n.nodeName.toUpperCase();return a.includes(r)&&e.push(n),e},[]);return this.relatedNodes(i),0===i.length}},{id:"focusable-element",evaluate:function(e,t,n,r){var a=n.isFocusable,o=parseInt(n.actualNode.getAttribute("tabindex"),10);return(o=isNaN(o)?null:o)?a&&0<=o:a}},{id:"focusable-no-name",evaluate:function(e,t,n,r){var a=e.getAttribute("tabindex");return!!(axe.commons.dom.isFocusable(e)&&-1<a)&&!axe.commons.text.accessibleTextVirtual(n)}},{id:"focusable-not-tabbable",evaluate:function(e,t,n,r){var a=["BUTTON","FIELDSET","INPUT","SELECT","TEXTAREA"],o=n.tabbableElements;if(!o||!o.length)return!0;var i=o.reduce(function(e,t){var n=t.actualNode,r=n.nodeName.toUpperCase();return a.includes(r)||e.push(n),e},[]);return this.relatedNodes(i),0===i.length}},{id:"landmark-is-top-level",evaluate:function(e,t,n,r){var a=axe.commons.aria.getRolesByType("landmark"),o=axe.commons.dom.getComposedParent(e);for(this.data({role:e.getAttribute("role")||axe.commons.aria.implicitRole(e)});o;){var i=o.getAttribute("role");if(i||"FORM"===o.nodeName.toUpperCase()||(i=axe.commons.aria.implicitRole(o)),i&&a.includes(i))return!1;o=axe.commons.dom.getComposedParent(o)}return!0}},{id:"page-has-heading-one",evaluate:function(e,t,n,r){if(!t||!t.selector||"string"!=typeof t.selector)throw new TypeError("visible-in-page requires options.selector to be a string");var a=axe.utils.querySelectorAll(n,t.selector);return this.relatedNodes(a.map(function(e){return e.actualNode})),0<a.length},after:function(e,t){return e.some(function(e){return!0===e.result})&&e.forEach(function(e){e.result=!0}),e},options:{selector:'h1:not([role]), [role="heading"][aria-level="1"]'}},{id:"page-has-main",evaluate:function(e,t,n,r){if(!t||!t.selector||"string"!=typeof t.selector)throw new TypeError("visible-in-page requires options.selector to be a string");var a=axe.utils.querySelectorAll(n,t.selector);return this.relatedNodes(a.map(function(e){return e.actualNode})),0<a.length},after:function(e,t){return e.some(function(e){return!0===e.result})&&e.forEach(function(e){e.result=!0}),e},options:{selector:"main:not([role]), [role='main']"}},{id:"page-no-duplicate-banner",evaluate:function(e,t,n,r){if(!t||!t.selector||"string"!=typeof t.selector)throw new TypeError("visible-in-page requires options.selector to be a string");var a=axe.utils.querySelectorAll(n,t.selector);return"string"==typeof t.nativeScopeFilter&&(a=a.filter(function(e){return e.actualNode.hasAttribute("role")||!axe.commons.dom.findUpVirtual(e,t.nativeScopeFilter)})),this.relatedNodes(a.map(function(e){return e.actualNode})),a.length<=1},options:{selector:"header:not([role]), [role=banner]",nativeScopeFilter:"article, aside, main, nav, section"}},{id:"page-no-duplicate-contentinfo",evaluate:function(e,t,n,r){if(!t||!t.selector||"string"!=typeof t.selector)throw new TypeError("visible-in-page requires options.selector to be a string");var a=axe.utils.querySelectorAll(n,t.selector);return"string"==typeof t.nativeScopeFilter&&(a=a.filter(function(e){return e.actualNode.hasAttribute("role")||!axe.commons.dom.findUpVirtual(e,t.nativeScopeFilter)})),this.relatedNodes(a.map(function(e){return e.actualNode})),a.length<=1},options:{selector:"footer:not([role]), [role=contentinfo]",nativeScopeFilter:"article, aside, main, nav, section"}},{id:"page-no-duplicate-main",evaluate:function(e,t,n,r){if(!t||!t.selector||"string"!=typeof t.selector)throw new TypeError("visible-in-page requires options.selector to be a string");var a=axe.utils.querySelectorAll(n,t.selector);return"string"==typeof t.nativeScopeFilter&&(a=a.filter(function(e){return e.actualNode.hasAttribute("role")||!axe.commons.dom.findUpVirtual(e,t.nativeScopeFilter)})),this.relatedNodes(a.map(function(e){return e.actualNode})),a.length<=1},options:{selector:"main:not([role]), [role='main']"}},{id:"tabindex",evaluate:function(e,t,n,r){return e.tabIndex<=0}},{id:"alt-space-value",evaluate:function(e,t,n,r){var a=/^\s+$/.test(e.getAttribute("alt"));return e.hasAttribute("alt")&&a}},{id:"duplicate-img-label",evaluate:function(e,t,n,r){var a=axe.commons,o=a.aria,i=a.text,u=a.dom;if(["none","presentation"].includes(o.getRole(e)))return!1;var s=u.findUpVirtual(n,'button, [role="button"], a[href], p, li, td, th');if(!s)return!1;var l=axe.utils.getNodeFromTree(s),c=i.visibleVirtual(l,!0).toLowerCase();return""!==c&&c===i.accessibleTextVirtual(n).toLowerCase()}},{id:"explicit-label",evaluate:function(e,t,n,r){if(e.getAttribute("id")){var a=axe.commons.dom.getRootNode(e),o=axe.utils.escapeSelector(e.getAttribute("id")),i=a.querySelector('label[for="'.concat(o,'"]'));if(i)return!axe.commons.dom.isVisible(i)||!!axe.commons.text.accessibleText(i)}return!1}},{id:"help-same-as-label",evaluate:function(e,t,n,r){var a=axe.commons.text.labelVirtual(n),o=e.getAttribute("title");if(!a)return!1;o||(o="",e.getAttribute("aria-describedby")&&(o=axe.commons.dom.idrefs(e,"aria-describedby").map(function(e){return e?axe.commons.text.accessibleText(e):""}).join("")));return axe.commons.text.sanitize(o)===axe.commons.text.sanitize(a)},enabled:!1},{id:"hidden-explicit-label",evaluate:function(e,t,n,r){if(e.getAttribute("id")){var a=axe.commons.dom.getRootNode(e),o=axe.utils.escapeSelector(e.getAttribute("id")),i=a.querySelector('label[for="'.concat(o,'"]'));if(i&&!axe.commons.dom.isVisible(i,!0))return""===axe.commons.text.accessibleTextVirtual(n).trim()}return!1}},{id:"implicit-label",evaluate:function(e,t,n,r){var a=axe.commons,o=a.dom,i=a.text,u=o.findUpVirtual(n,"label");return!!u&&!!i.accessibleText(u,{inControlContext:!0})}},{id:"label-content-name-mismatch",evaluate:function(e,t,n,r){var a=axe.commons.text,o=a.accessibleText(e).toLowerCase();if(!(a.isHumanInterpretable(o)<1)){var i=a.sanitize(a.visibleVirtual(n)).toLowerCase();return a.isHumanInterpretable(i)<1?!!u(i,o)||void 0:u(i,o)}function u(e,t){var n=s(t),r=s(e);return!(!n||!r)&&n.includes(r)}function s(e){var t=a.removeUnicode(e,{emoji:!0,nonBmp:!0,punctuations:!0});return a.sanitize(t)}}},{id:"multiple-label",evaluate:function(e,t,n,r){var a=axe.utils.escapeSelector(e.getAttribute("id")),o=e.parentNode,i=axe.commons.dom.getRootNode(e);i=i.documentElement||i;var u=Array.from(i.querySelectorAll('label[for="'.concat(a,'"]')));for(u.length&&(u=u.filter(function(e){return axe.commons.dom.isVisible(e)}));o;)"LABEL"===o.nodeName.toUpperCase()&&-1===u.indexOf(o)&&u.push(o),o=o.parentNode;if(this.relatedNodes(u),1<u.length){var s=u.filter(function(e){return axe.commons.dom.isVisible(e,!0)});return 1<s.length||!axe.commons.dom.idrefs(e,"aria-labelledby").includes(s[0])}return!1}},{id:"title-only",evaluate:function(e,t,n,r){return!(axe.commons.text.labelVirtual(n)||!e.getAttribute("title")&&!e.getAttribute("aria-describedby"))}},{id:"landmark-is-unique",evaluate:function(e,t,n,r){var a=axe.commons.aria.getRole(e),o=axe.commons.text.accessibleTextVirtual(n);return o=o?o.toLowerCase():null,this.data({role:a,accessibleText:o}),this.relatedNodes([e]),!0},after:function(e,t){var n=[];return e.filter(function(t){var e=n.find(function(e){return t.data.role===e.data.role&&t.data.accessibleText===e.data.accessibleText});return e?(e.result=!1,e.relatedNodes.push(t.relatedNodes[0]),!1):(n.push(t),t.relatedNodes=[],!0)})}},{id:"has-lang",evaluate:function(e,t,n,r){return!!(e.getAttribute("lang")||e.getAttribute("xml:lang")||"").trim()}},{id:"valid-lang",evaluate:function(a,e,t,n){var o,r;return o=(e||axe.utils.validLangs()).map(axe.utils.getBaseLang),!!(r=["lang","xml:lang"].reduce(function(e,t){var n=a.getAttribute(t);if("string"!=typeof n)return e;var r=axe.utils.getBaseLang(n);return""!==r&&-1===o.indexOf(r)&&e.push(t+'="'+a.getAttribute(t)+'"'),e},[])).length&&(this.data(r),!0)}},{id:"xml-lang-mismatch",evaluate:function(e,t,n,r){var a=axe.utils.getBaseLang;return a(e.getAttribute("lang"))===a(e.getAttribute("xml:lang"))}},{id:"dlitem",evaluate:function(e,t,n,r){var a=axe.commons.dom.getComposedParent(e),o=a.nodeName.toUpperCase(),i=axe.commons.aria.getRole(a,{noImplicit:!0});return"DIV"===o&&["presentation","none",null].includes(i)&&(o=(a=axe.commons.dom.getComposedParent(a)).nodeName.toUpperCase(),i=axe.commons.aria.getRole(a,{noImplicit:!0})),"DL"===o&&(!i||"list"===i)}},{id:"listitem",evaluate:function(e,t,n,r){var a=axe.commons.dom.getComposedParent(e);if(a){var o=a.nodeName.toUpperCase(),i=(a.getAttribute("role")||"").toLowerCase();return"list"===i||(!i||!axe.commons.aria.isValidRole(i))&&["UL","OL"].includes(o)}}},{id:"only-dlitems",evaluate:function(e,t,n,r){var a=axe.commons,o=a.dom,i=a.aria,u=["definition","term","list"],s=n.children.reduce(function(e,t){var n=t.actualNode;return"DIV"===n.nodeName.toUpperCase()&&null===i.getRole(n)?e.concat(t.children):e.concat(t)},[]).reduce(function(e,t){var n=t.actualNode,r=n.nodeName.toUpperCase();if(1===n.nodeType&&o.isVisible(n,!0,!1)){var a=i.getRole(n,{noImplicit:!0});("DT"!==r&&"DD"!==r||a)&&(u.includes(a)||e.badNodes.push(n))}else 3===n.nodeType&&""!==n.nodeValue.trim()&&(e.hasNonEmptyTextNode=!0);return e},{badNodes:[],hasNonEmptyTextNode:!1});return s.badNodes.length&&this.relatedNodes(s.badNodes),!!s.badNodes.length||s.hasNonEmptyTextNode}},{id:"only-listitems",evaluate:function(e,t,n,r){var o=axe.commons.dom,a=n.children.reduce(function(e,t){var n=t.actualNode,r=n.nodeName.toUpperCase();if(1===n.nodeType&&o.isVisible(n,!0,!1)){var a=function(e,t){return"listitem"===e||"LI"===t&&!e}((n.getAttribute("role")||"").toLowerCase(),r);e.hasListItem=function(e,t,n){return e||"LI"===t&&n||n}(e.hasListItem,r,a),a&&(e.isEmpty=!1),"LI"!==r||a||e.liItemsWithRole++,"LI"===r||a||e.badNodes.push(n)}return 3===n.nodeType&&""!==n.nodeValue.trim()&&(e.hasNonEmptyTextNode=!0),e},{badNodes:[],isEmpty:!0,hasNonEmptyTextNode:!1,hasListItem:!1,liItemsWithRole:0}),i=n.children.filter(function(e){return"LI"===e.actualNode.nodeName.toUpperCase()}),u=0<a.liItemsWithRole&&i.length===a.liItemsWithRole;return a.badNodes.length&&this.relatedNodes(a.badNodes),!(a.hasListItem||a.isEmpty&&!u)||!!a.badNodes.length||a.hasNonEmptyTextNode}},{id:"structured-dlitems",evaluate:function(e,t,n,r){var a=n.children;if(!a||!a.length)return!1;for(var o,i=!1,u=!1,s=0;s<a.length;s++){if("DT"===(o=a[s].actualNode.nodeName.toUpperCase())&&(i=!0),i&&"DD"===o)return!1;"DD"===o&&(u=!0)}return i||u}},{id:"caption",evaluate:function(e,t,n,r){return!axe.utils.querySelectorAll(n,"track").some(function(e){return"captions"===(e.actualNode.getAttribute("kind")||"").toLowerCase()})&&void 0}},{id:"description",evaluate:function(e,t,n,r){return!axe.utils.querySelectorAll(n,"track").some(function(e){return"descriptions"===(e.actualNode.getAttribute("kind")||"").toLowerCase()})&&void 0}},{id:"frame-tested",evaluate:function(e,t,n,r){var a=this.async(),o=Object.assign({isViolation:!1,timeout:500},t),i=o.isViolation,u=o.timeout,s=setTimeout(function(){s=setTimeout(function(){s=null,a(!i&&void 0)},0)},u);axe.utils.respondable(e.contentWindow,"axe.ping",null,void 0,function(){null!==s&&(clearTimeout(s),a(!0))})},options:{isViolation:!1}},{id:"css-orientation-lock",evaluate:function(e,t,n,r){var a=(r||{}).cssom,o=void 0===a?void 0:a;if(o&&o.length){var i=o.reduce(function(e,t){var n=t.sheet,r=t.root,a=t.shadowId,o=a||"topDocument";if(e[o]||(e[o]={root:r,rules:[]}),!n||!n.cssRules)return e;var i=Array.from(n.cssRules);return e[o].rules=e[o].rules.concat(i),e},{}),s=!1,l=[];return Object.keys(i).forEach(function(e){var t=i[e],u=t.root,n=t.rules.filter(function(e){return 4===e.type});if(n&&n.length){var r=n.filter(function(e){var t=e.cssText;return/orientation:\s*landscape/i.test(t)||/orientation:\s*portrait/i.test(t)});r&&r.length&&r.forEach(function(e){e.cssRules.length&&Array.from(e.cssRules).forEach(function(e){if(e.selectorText&&!(e.style.length<=0)){var t=e.style.transform||e.style.webkitTransform||e.style.msTransform||!1;if(t){var n=t.match(/rotate\(([^)]+)deg\)/),r=parseInt(n&&n[1]||0),a=r%90==0&&r%180!=0;if(a&&"HTML"!==e.selectorText.toUpperCase()){var o=e.selectorText,i=Array.from(u.querySelectorAll(o));i&&i.length&&(l=l.concat(i))}s=a}}})})}}),s?(l.length&&this.relatedNodes(l),!1):!0}}},{id:"meta-viewport-large",evaluate:function(e,t,n,r){t=t||{};for(var a,o=(e.getAttribute("content")||"").split(/[;,]/),i={},u=t.scaleMinimum||2,s=t.lowerBound||!1,l=0,c=o.length;l<c;l++){var d=(a=o[l].split("=")).shift().toLowerCase();d&&a.length&&(i[d.trim()]=a.shift().trim().toLowerCase())}return!!(s&&i["maximum-scale"]&&parseFloat(i["maximum-scale"])<s)||(s||"no"!==i["user-scalable"]?!(i["maximum-scale"]&&parseFloat(i["maximum-scale"])<u)||(this.data("maximum-scale"),!1):(this.data("user-scalable=no"),!1))},options:{scaleMinimum:5,lowerBound:2}},{id:"meta-viewport",evaluate:function(e,t,n,r){t=t||{};for(var a,o=(e.getAttribute("content")||"").split(/[;,]/),i={},u=t.scaleMinimum||2,s=t.lowerBound||!1,l=0,c=o.length;l<c;l++){var d=(a=o[l].split("=")).shift().toLowerCase();d&&a.length&&(i[d.trim()]=a.shift().trim().toLowerCase())}return!!(s&&i["maximum-scale"]&&parseFloat(i["maximum-scale"])<s)||(s||"no"!==i["user-scalable"]?!(i["maximum-scale"]&&parseFloat(i["maximum-scale"])<u)||(this.data("maximum-scale"),!1):(this.data("user-scalable=no"),!1))},options:{scaleMinimum:2}},{id:"header-present",evaluate:function(e,t,n,r){return!!axe.utils.querySelectorAll(n,'h1, h2, h3, h4, h5, h6, [role="heading"]')[0]}},{id:"heading-order",evaluate:function(e,t,n,r){var a=e.getAttribute("aria-level");if(null!==a)return this.data(parseInt(a,10)),!0;var o=e.nodeName.toUpperCase().match(/H(\d)/);return o&&this.data(parseInt(o[1],10)),!0},after:function(e,t){if(e.length<2)return e;for(var n=e[0].data,r=1;r<e.length;r++)e[r].result&&e[r].data>n+1&&(e[r].result=!1),n=e[r].data;return e}},{id:"internal-link-present",evaluate:function(e,t,n,r){return axe.utils.querySelectorAll(n,"a[href]").some(function(e){return/^#[^/!]/.test(e.actualNode.getAttribute("href"))})}},{id:"landmark",evaluate:function(e,t,n,r){return 0<axe.utils.querySelectorAll(n,'main, [role="main"]').length}},{id:"meta-refresh",evaluate:function(e,t,n,r){var a=e.getAttribute("content")||"",o=a.split(/[;,]/);return""===a||"0"===o[0]}},{id:"p-as-heading",evaluate:function(e,t,n,r){var a=Array.from(e.parentNode.children),o=a.indexOf(e),i=(t=t||{}).margins||[],u=a.slice(o+1).find(function(e){return"P"===e.nodeName.toUpperCase()}),s=a.slice(0,o).reverse().find(function(e){return"P"===e.nodeName.toUpperCase()});function l(e){var t=window.getComputedStyle(function(e){for(var t=e,n=e.textContent.trim(),r=n;r===n&&void 0!==t;){var a=-1;if(0===(e=t).children.length)return e;for(;a++,""===(r=e.children[a].textContent.trim())&&a+1<e.children.length;);t=e.children[a]}return e}(e));return{fontWeight:function(e){switch(e){case"lighter":return 100;case"normal":return 400;case"bold":return 700;case"bolder":return 900}return e=parseInt(e),isNaN(e)?400:e}(t.getPropertyValue("font-weight")),fontSize:parseInt(t.getPropertyValue("font-size")),isItalic:"italic"===t.getPropertyValue("font-style")}}function c(n,r,e){return e.reduce(function(e,t){return e||(!t.size||n.fontSize/t.size>r.fontSize)&&(!t.weight||n.fontWeight-t.weight>r.fontWeight)&&(!t.italic||n.isItalic&&!r.isItalic)},!1)}var d=l(e),m=u?l(u):null,p=s?l(s):null;if(!m||!c(d,m,i))return!0;var f=axe.commons.dom.findUpVirtual(n,"blockquote");return!!(f&&"BLOCKQUOTE"===f.nodeName.toUpperCase()||p&&!c(d,p,i))&&void 0},options:{margins:[{weight:150,italic:!0},{weight:150,size:1.15},{italic:!0,size:1.15},{size:1.4}]}},{id:"region",evaluate:function(e,t,n,r){var a=axe.commons,o=a.dom,i=a.aria,u=i.getRolesByType("landmark"),s=u.reduce(function(e,t){return e.concat(i.implicitNodes(t))},[]).filter(function(e){return null!==e});var l=function e(t){var n=t.actualNode;return function(a){var o=a.actualNode,e=axe.commons.aria.getRole(o,{noImplicit:!0}),t=(o.getAttribute("aria-live")||"").toLowerCase().trim();return e?"dialog"===e||u.includes(e):!!["assertive","polite"].includes(t)||s.some(function(e){var t=axe.utils.matchesSelector(o,e);if("FORM"!==o.nodeName.toUpperCase())return t;var n=o.getAttribute("title"),r=n&&""!==n.trim()?axe.commons.text.sanitize(n):null;return t&&(!!i.labelVirtual(a)||!!r)})}(t)||o.isSkipLink(t.actualNode)&&o.getElementByReference(t.actualNode,"href")||!o.isVisible(n,!0)?[]:o.hasContent(n,!0)?[n]:t.children.filter(function(e){return 1===e.actualNode.nodeType}).map(e).reduce(function(e,t){return e.concat(t)},[])}(n);return this.relatedNodes(l),0===l.length},after:function(e,t){return[e[0]]}},{id:"skip-link",evaluate:function(e,t,n,r){var a=axe.commons.dom.getElementByReference(e,"href");return!!a&&(axe.commons.dom.isVisible(a,!0)||void 0)}},{id:"unique-frame-title",evaluate:function(e,t,n,r){var a=axe.commons.text.sanitize(e.title).trim().toLowerCase();return this.data(a),!0},after:function(e,t){var n={};return e.forEach(function(e){n[e.data]=void 0!==n[e.data]?++n[e.data]:0}),e.forEach(function(e){e.result=!!n[e.data]}),e}},{id:"duplicate-id-active",evaluate:function(t,e,n,r){var a=t.getAttribute("id").trim();if(!a)return!0;var o=axe.commons.dom.getRootNode(t),i=Array.from(o.querySelectorAll('[id="'.concat(axe.utils.escapeSelector(a),'"]'))).filter(function(e){return e!==t});return i.length&&this.relatedNodes(i),this.data(a),0===i.length},after:function(e,t){var n=[];return e.filter(function(e){return-1===n.indexOf(e.data)&&(n.push(e.data),!0)})}},{id:"duplicate-id-aria",evaluate:function(t,e,n,r){var a=t.getAttribute("id").trim();if(!a)return!0;var o=axe.commons.dom.getRootNode(t),i=Array.from(o.querySelectorAll('[id="'.concat(axe.utils.escapeSelector(a),'"]'))).filter(function(e){return e!==t});return i.length&&this.relatedNodes(i),this.data(a),0===i.length},after:function(e,t){var n=[];return e.filter(function(e){return-1===n.indexOf(e.data)&&(n.push(e.data),!0)})}},{id:"duplicate-id",evaluate:function(t,e,n,r){var a=t.getAttribute("id").trim();if(!a)return!0;var o=axe.commons.dom.getRootNode(t),i=Array.from(o.querySelectorAll('[id="'.concat(axe.utils.escapeSelector(a),'"]'))).filter(function(e){return e!==t});return i.length&&this.relatedNodes(i),this.data(a),0===i.length},after:function(e,t){var n=[];return e.filter(function(e){return-1===n.indexOf(e.data)&&(n.push(e.data),!0)})}},{id:"aria-label",evaluate:function(e,t,n,r){var a=axe.commons,o=a.text,i=a.aria;return!!o.sanitize(i.arialabelText(e))}},{id:"aria-labelledby",evaluate:function(e,t,n,r){var a=axe.commons,o=a.text,i=a.aria;return!!o.sanitize(i.arialabelledbyText(e))}},{id:"avoid-inline-spacing",evaluate:function(t,e,n,r){var a=["line-height","letter-spacing","word-spacing"].filter(function(e){if("important"===t.style.getPropertyPriority(e))return e});return!(0<a.length)||(this.data(a),!1)}},{id:"button-has-visible-text",evaluate:function(e,t,n,r){var a,o=e.nodeName.toUpperCase(),i=e.getAttribute("role");return("BUTTON"===o||"button"===i&&"INPUT"!==o)&&(a=axe.commons.text.accessibleTextVirtual(n),this.data(a),!!a)}},{id:"doc-has-title",evaluate:function(e,t,n,r){var a=document.title;return!(!a||!axe.commons.text.sanitize(a).trim())}},{id:"exists",evaluate:function(e,t,n,r){return!0}},{id:"has-alt",evaluate:function(e,t,n,r){var a=e.nodeName.toLowerCase();return e.hasAttribute("alt")&&("img"===a||"input"===a||"area"===a)}},{id:"has-visible-text",evaluate:function(e,t,n,r){return 0<axe.commons.text.accessibleTextVirtual(n).length}},{id:"is-on-screen",evaluate:function(e,t,n,r){return axe.commons.dom.isVisible(e,!1)&&!axe.commons.dom.isOffscreen(e)}},{id:"non-empty-alt",evaluate:function(e,t,n,r){var a=e.getAttribute("alt");return!(!a||!axe.commons.text.sanitize(a).trim())}},{id:"non-empty-if-present",evaluate:function(e,t,n,r){var a=e.nodeName.toUpperCase(),o=(e.getAttribute("type")||"").toLowerCase(),i=e.getAttribute("value");return this.data(i),!("INPUT"!==a||!["submit","reset"].includes(o))&&null===i}},{id:"non-empty-title",evaluate:function(e,t,n,r){var a=axe.commons.text;return!!a.sanitize(a.titleText(e))}},{id:"non-empty-value",evaluate:function(e,t,n,r){var a=e.getAttribute("value");return!(!a||!axe.commons.text.sanitize(a).trim())}},{id:"role-none",evaluate:function(e,t,n,r){return"none"===e.getAttribute("role")}},{id:"role-presentation",evaluate:function(e,t,n,r){return"presentation"===e.getAttribute("role")}},{id:"caption-faked",evaluate:function(e,t,n,r){var a=axe.commons.table.toGrid(e),o=a[0];return a.length<=1||o.length<=1||e.rows.length<=1||o.reduce(function(e,t,n){return e||t!==o[n+1]&&void 0!==o[n+1]},!1)}},{id:"has-caption",evaluate:function(e,t,n,r){return!!e.caption}},{id:"has-summary",evaluate:function(e,t,n,r){return!!e.summary}},{id:"has-th",evaluate:function(e,t,n,r){for(var a,o,i=[],u=0,s=e.rows.length;u<s;u++)for(var l=0,c=(a=e.rows[u]).cells.length;l<c;l++)"TH"!==(o=a.cells[l]).nodeName.toUpperCase()&&-1===["rowheader","columnheader"].indexOf(o.getAttribute("role"))||i.push(o);return!!i.length&&(this.relatedNodes(i),!0)}},{id:"html5-scope",evaluate:function(e,t,n,r){return!axe.commons.dom.isHTML5(document)||"TH"===e.nodeName.toUpperCase()}},{id:"same-caption-summary",evaluate:function(e,t,n,r){return!(!e.summary||!e.caption)&&e.summary.toLowerCase()===axe.commons.text.accessibleText(e.caption).toLowerCase()}},{id:"scope-value",evaluate:function(e,t,n,r){var a=e.getAttribute("scope").toLowerCase();return-1!==["row","col","rowgroup","colgroup"].indexOf(a)}},{id:"td-has-header",evaluate:function(e,t,n,r){var a=axe.commons.table,o=[];return a.getAllCells(e).forEach(function(e){axe.commons.dom.hasContent(e)&&a.isDataCell(e)&&!axe.commons.aria.label(e)&&(a.getHeaders(e).some(function(e){return null!==e&&!!axe.commons.dom.hasContent(e)})||o.push(e))}),!o.length||(this.relatedNodes(o),!1)}},{id:"td-headers-attr",evaluate:function(e,t,n,r){for(var a=[],o=0,i=e.rows.length;o<i;o++)for(var u=e.rows[o],s=0,l=u.cells.length;s<l;s++)a.push(u.cells[s]);var c=a.reduce(function(e,t){return t.getAttribute("id")&&e.push(t.getAttribute("id")),e},[]),d=a.reduce(function(e,t){var n,r,a=(t.getAttribute("headers")||"").split(/\s/).reduce(function(e,t){return(t=t.trim())&&e.push(t),e},[]);return 0!==a.length&&(t.getAttribute("id")&&(n=-1!==a.indexOf(t.getAttribute("id").trim())),r=a.reduce(function(e,t){return e||-1===c.indexOf(t)},!1),(n||r)&&e.push(t)),e},[]);return!(0<d.length)||(this.relatedNodes(d),!1)}},{id:"th-has-data-cells",evaluate:function(e,t,n,r){var a=axe.commons.table,o=a.getAllCells(e),i=this,u=[];o.forEach(function(e){var t=e.getAttribute("headers");t&&(u=u.concat(t.split(/\s+/)));var n=e.getAttribute("aria-labelledby");n&&(u=u.concat(n.split(/\s+/)))});var s=o.filter(function(e){return""!==axe.commons.text.sanitize(e.textContent)&&("TH"===e.nodeName.toUpperCase()||-1!==["rowheader","columnheader"].indexOf(e.getAttribute("role")))}),l=a.toGrid(e),c=!0;return s.forEach(function(e){if(!e.getAttribute("id")||!u.includes(e.getAttribute("id"))){var t=a.getCellPosition(e,l),n=!1;a.isColumnHeader(e)&&(n=a.traverse("down",t,l).find(function(e){return!a.isColumnHeader(e)})),!n&&a.isRowHeader(e)&&(n=a.traverse("right",t,l).find(function(e){return!a.isRowHeader(e)})),n||i.relatedNodes(e),c=c&&n}}),!!c||void 0}},{id:"hidden-content",evaluate:function(e,t,n,r){if(!["SCRIPT","HEAD","TITLE","NOSCRIPT","STYLE","TEMPLATE"].includes(e.nodeName.toUpperCase())&&axe.commons.dom.hasContentVirtual(n)){var a=window.getComputedStyle(e);if("none"===a.getPropertyValue("display"))return;if("hidden"===a.getPropertyValue("visibility")){var o=axe.commons.dom.getComposedParent(e),i=o&&window.getComputedStyle(o);if(!i||"hidden"!==i.getPropertyValue("visibility"))return}}return!0}}],commons:function(){function e(e){return null===e}function t(e){return null!==e}var commons={},l=commons.aria={},n=l.lookupTable={};n.attributes={"aria-activedescendant":{type:"idref",allowEmpty:!0,unsupported:!1},"aria-atomic":{type:"boolean",values:["true","false"],unsupported:!1},"aria-autocomplete":{type:"nmtoken",values:["inline","list","both","none"],unsupported:!1},"aria-busy":{type:"boolean",values:["true","false"],unsupported:!1},"aria-checked":{type:"nmtoken",values:["true","false","mixed","undefined"],unsupported:!1},"aria-colcount":{type:"int",unsupported:!1},"aria-colindex":{type:"int",unsupported:!1},"aria-colspan":{type:"int",unsupported:!1},"aria-controls":{type:"idrefs",allowEmpty:!0,unsupported:!1},"aria-current":{type:"nmtoken",allowEmpty:!0,values:["page","step","location","date","time","true","false"],unsupported:!1},"aria-describedby":{type:"idrefs",allowEmpty:!0,unsupported:!1},"aria-describedat":{unsupported:!0,unstandardized:!0},"aria-details":{unsupported:!0},"aria-disabled":{type:"boolean",values:["true","false"],unsupported:!1},"aria-dropeffect":{type:"nmtokens",values:["copy","move","reference","execute","popup","none"],unsupported:!1},"aria-errormessage":{type:"idref",allowEmpty:!0,unsupported:!1},"aria-expanded":{type:"nmtoken",values:["true","false","undefined"],unsupported:!1},"aria-flowto":{type:"idrefs",allowEmpty:!0,unsupported:!1},"aria-grabbed":{type:"nmtoken",values:["true","false","undefined"],unsupported:!1},"aria-haspopup":{type:"nmtoken",allowEmpty:!0,values:["true","false","menu","listbox","tree","grid","dialog"],unsupported:!1},"aria-hidden":{type:"boolean",values:["true","false"],unsupported:!1},"aria-invalid":{type:"nmtoken",allowEmpty:!0,values:["true","false","spelling","grammar"],unsupported:!1},"aria-keyshortcuts":{type:"string",allowEmpty:!0,unsupported:!1},"aria-label":{type:"string",allowEmpty:!0,unsupported:!1},"aria-labelledby":{type:"idrefs",allowEmpty:!0,unsupported:!1},"aria-level":{type:"int",unsupported:!1},"aria-live":{type:"nmtoken",values:["off","polite","assertive"],unsupported:!1},"aria-modal":{type:"boolean",values:["true","false"],unsupported:!1},"aria-multiline":{type:"boolean",values:["true","false"],unsupported:!1},"aria-multiselectable":{type:"boolean",values:["true","false"],unsupported:!1},"aria-orientation":{type:"nmtoken",values:["horizontal","vertical"],unsupported:!1},"aria-owns":{type:"idrefs",allowEmpty:!0,unsupported:!1},"aria-placeholder":{type:"string",allowEmpty:!0,unsupported:!1},"aria-posinset":{type:"int",unsupported:!1},"aria-pressed":{type:"nmtoken",values:["true","false","mixed","undefined"],unsupported:!1},"aria-readonly":{type:"boolean",values:["true","false"],unsupported:!1},"aria-relevant":{type:"nmtokens",values:["additions","removals","text","all"],unsupported:!1},"aria-required":{type:"boolean",values:["true","false"],unsupported:!1},"aria-roledescription":{type:"string",allowEmpty:!0,unsupported:{exceptions:["button",{nodeName:"input",properties:{type:["button","checkbox","image","radio","reset","submit"]}},"img","select","summary"]}},"aria-rowcount":{type:"int",unsupported:!1},"aria-rowindex":{type:"int",unsupported:!1},"aria-rowspan":{type:"int",unsupported:!1},"aria-selected":{type:"nmtoken",values:["true","false","undefined"],unsupported:!1},"aria-setsize":{type:"int",unsupported:!1},"aria-sort":{type:"nmtoken",values:["ascending","descending","other","none"],unsupported:!1},"aria-valuemax":{type:"decimal",unsupported:!1},"aria-valuemin":{type:"decimal",unsupported:!1},"aria-valuenow":{type:"decimal",unsupported:!1},"aria-valuetext":{type:"string",unsupported:!1}},n.globalAttributes=["aria-atomic","aria-busy","aria-controls","aria-current","aria-describedby","aria-disabled","aria-dropeffect","aria-flowto","aria-grabbed","aria-haspopup","aria-hidden","aria-invalid","aria-keyshortcuts","aria-label","aria-labelledby","aria-live","aria-owns","aria-relevant","aria-roledescription"],n.role={alert:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},alertdialog:{type:"widget",attributes:{allowed:["aria-expanded","aria-modal","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["dialog","section"]},application:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["article","audio","embed","iframe","object","section","svg","video"]},article:{type:"structure",attributes:{allowed:["aria-expanded","aria-posinset","aria-setsize","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["article"],unsupported:!1},banner:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["header"],unsupported:!1,allowedElements:["section"]},button:{type:"widget",attributes:{allowed:["aria-expanded","aria-pressed","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["button",'input[type="button"]','input[type="image"]','input[type="reset"]','input[type="submit"]',"summary"],unsupported:!1,allowedElements:[{nodeName:"a",attributes:{href:t}}]},cell:{type:"structure",attributes:{allowed:["aria-colindex","aria-colspan","aria-rowindex","aria-rowspan","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["td","th"],unsupported:!1},checkbox:{type:"widget",attributes:{allowed:["aria-checked","aria-required","aria-readonly","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,implicit:['input[type="checkbox"]'],unsupported:!1,allowedElements:["button"]},columnheader:{type:"structure",attributes:{allowed:["aria-colindex","aria-colspan","aria-expanded","aria-rowindex","aria-rowspan","aria-required","aria-readonly","aria-selected","aria-sort","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["th"],unsupported:!1},combobox:{type:"composite",attributes:{allowed:["aria-autocomplete","aria-required","aria-activedescendant","aria-orientation","aria-errormessage"],required:["aria-expanded"]},owned:{all:["listbox","textbox"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:[{nodeName:"input",properties:{type:"text"}}]},command:{nameFrom:["author"],type:"abstract",unsupported:!1},complementary:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["aside"],unsupported:!1,allowedElements:["section"]},composite:{nameFrom:["author"],type:"abstract",unsupported:!1},contentinfo:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["footer"],unsupported:!1,allowedElements:["section"]},definition:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["dd","dfn"],unsupported:!1},dialog:{type:"widget",attributes:{allowed:["aria-expanded","aria-modal","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["dialog"],unsupported:!1,allowedElements:["section"]},directory:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,unsupported:!1,allowedElements:["ol","ul"]},document:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["body"],unsupported:!1,allowedElements:["article","embed","iframe","object","section","svg"]},"doc-abstract":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-acknowledgments":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-afterword":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-appendix":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-backlink":{type:"link",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,unsupported:!1,allowedElements:[{nodeName:"a",attributes:{href:t}}]},"doc-biblioentry":{type:"listitem",attributes:{allowed:["aria-expanded","aria-level","aria-posinset","aria-setsize","aria-errormessage"]},owned:null,nameFrom:["author"],context:["doc-bibliography"],unsupported:!1,allowedElements:["li"]},"doc-bibliography":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:{one:["doc-biblioentry"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-biblioref":{type:"link",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,unsupported:!1,allowedElements:[{nodeName:"a",attributes:{href:t}}]},"doc-chapter":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-colophon":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-conclusion":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-cover":{type:"img",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1},"doc-credit":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-credits":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-dedication":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-endnote":{type:"listitem",attributes:{allowed:["aria-expanded","aria-level","aria-posinset","aria-setsize","aria-errormessage"]},owned:null,namefrom:["author"],context:["doc-endnotes"],unsupported:!1,allowedElements:["li"]},"doc-endnotes":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:{one:["doc-endnote"]},namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-epigraph":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1},"doc-epilogue":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-errata":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-example":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["aside","section"]},"doc-footnote":{type:"section",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["aside","footer","header"]},"doc-foreword":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-glossary":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:["term","definition"],namefrom:["author"],context:null,unsupported:!1,allowedElements:["dl"]},"doc-glossref":{type:"link",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author","contents"],context:null,unsupported:!1,allowedElements:[{nodeName:"a",attributes:{href:t}}]},"doc-index":{type:"navigation",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["nav","section"]},"doc-introduction":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-noteref":{type:"link",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author","contents"],context:null,unsupported:!1,allowedElements:[{nodeName:"a",attributes:{href:t}}]},"doc-notice":{type:"note",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-pagebreak":{type:"separator",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["hr"]},"doc-pagelist":{type:"navigation",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["nav","section"]},"doc-part":{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-preface":{type:"landmark",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-prologue":{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-pullquote":{type:"none",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["aside","section"]},"doc-qna":{type:"section",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},"doc-subtitle":{type:"sectionhead",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:{nodeName:["h1","h2","h3","h4","h5","h6"]}},"doc-tip":{type:"note",attributes:{allowed:["aria-expanded"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["aside"]},"doc-toc":{type:"navigation",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,namefrom:["author"],context:null,unsupported:!1,allowedElements:["nav","section"]},feed:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:{one:["article"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:["article","aside","section"]},figure:{type:"structure",unsupported:!1},form:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["form"],unsupported:!1},grid:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-colcount","aria-level","aria-multiselectable","aria-readonly","aria-rowcount","aria-errormessage"]},owned:{one:["rowgroup","row"]},nameFrom:["author"],context:null,implicit:["table"],unsupported:!1},gridcell:{type:"widget",attributes:{allowed:["aria-colindex","aria-colspan","aria-expanded","aria-rowindex","aria-rowspan","aria-selected","aria-readonly","aria-required","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["td","th"],unsupported:!1},group:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["details","optgroup"],unsupported:!1,allowedElements:["dl","figcaption","fieldset","figure","footer","header","ol","ul"]},heading:{type:"structure",attributes:{required:["aria-level"],allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["h1","h2","h3","h4","h5","h6"],unsupported:!1},img:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["img"],unsupported:!1,allowedElements:["embed","iframe","object","svg"]},input:{nameFrom:["author"],type:"abstract",unsupported:!1},landmark:{nameFrom:["author"],type:"abstract",unsupported:!1},link:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["a[href]"],unsupported:!1,allowedElements:["button",{nodeName:"input",properties:{type:["image","button"]}}]},list:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:{all:["listitem"]},nameFrom:["author"],context:null,implicit:["ol","ul","dl"],unsupported:!1},listbox:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-multiselectable","aria-required","aria-expanded","aria-orientation","aria-errormessage"]},owned:{all:["option"]},nameFrom:["author"],context:null,implicit:["select"],unsupported:!1,allowedElements:["ol","ul"]},listitem:{type:"structure",attributes:{allowed:["aria-level","aria-posinset","aria-setsize","aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["list"],implicit:["li","dt"],unsupported:!1},log:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},main:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["main"],unsupported:!1,allowedElements:["article","section"]},marquee:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},math:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["math"],unsupported:!1},menu:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-orientation","aria-errormessage"]},owned:{one:["menuitem","menuitemradio","menuitemcheckbox"]},nameFrom:["author"],context:null,implicit:['menu[type="context"]'],unsupported:!1,allowedElements:["ol","ul"]},menubar:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-orientation","aria-errormessage"]},owned:{one:["menuitem","menuitemradio","menuitemcheckbox"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:["ol","ul"]},menuitem:{type:"widget",attributes:{allowed:["aria-posinset","aria-setsize","aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["menu","menubar"],implicit:['menuitem[type="command"]'],unsupported:!1,allowedElements:["button","li",{nodeName:"iput",properties:{type:["image","button"]}},{nodeName:"a",attributes:{href:t}}]},menuitemcheckbox:{type:"widget",attributes:{allowed:["aria-checked","aria-posinset","aria-setsize","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["menu","menubar"],implicit:['menuitem[type="checkbox"]'],unsupported:!1,allowedElements:[{nodeName:["button","li"]},{nodeName:"input",properties:{type:["checkbox","image","button"]}},{nodeName:"a",attributes:{href:t}}]},menuitemradio:{type:"widget",attributes:{allowed:["aria-checked","aria-selected","aria-posinset","aria-setsize","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["menu","menubar"],implicit:['menuitem[type="radio"]'],unsupported:!1,allowedElements:[{nodeName:["button","li"]},{nodeName:"input",properties:{type:["image","button","radio"]}},{nodeName:"a",attributes:{href:t}}]},navigation:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["nav"],unsupported:!1,allowedElements:["section"]},none:{type:"structure",attributes:null,owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:[{nodeName:["article","aside","dl","embed","figcaption","fieldset","figure","footer","form","h1","h2","h3","h4","h5","h6","header","iframe","li","ol","section","ul"]},{nodeName:"img",attributes:{alt:t}}]},note:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["aside"]},option:{type:"widget",attributes:{allowed:["aria-selected","aria-posinset","aria-setsize","aria-checked","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["listbox"],implicit:["option"],unsupported:!1,allowedElements:[{nodeName:["button","li"]},{nodeName:"input",properties:{type:["checkbox","button"]}},{nodeName:"a",attributes:{href:t}}]},presentation:{type:"structure",attributes:null,owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:[{nodeName:["article","aside","dl","embed","figcaption","fieldset","figure","footer","form","h1","h2","h3","h4","h5","h6","header","iframe","li","ol","section","ul"]},{nodeName:"img",attributes:{alt:t}}]},progressbar:{type:"widget",attributes:{allowed:["aria-valuetext","aria-valuenow","aria-valuemax","aria-valuemin","aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["progress"],unsupported:!1},radio:{type:"widget",attributes:{allowed:["aria-selected","aria-posinset","aria-setsize","aria-required","aria-errormessage","aria-checked"]},owned:null,nameFrom:["author","contents"],context:null,implicit:['input[type="radio"]'],unsupported:!1,allowedElements:[{nodeName:["button","li"]},{nodeName:"input",properties:{type:["image","button"]}}]},radiogroup:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-required","aria-expanded","aria-readonly","aria-errormessage"]},owned:{all:["radio"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:{nodeName:["ol","ul"]}},range:{nameFrom:["author"],type:"abstract",unsupported:!1},region:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["section[aria-label]","section[aria-labelledby]","section[title]"],unsupported:!1,allowedElements:{nodeName:["article","aside"]}},roletype:{type:"abstract",unsupported:!1},row:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-colindex","aria-expanded","aria-level","aria-selected","aria-rowindex","aria-errormessage"]},owned:{one:["cell","columnheader","rowheader","gridcell"]},nameFrom:["author","contents"],context:["rowgroup","grid","treegrid","table"],implicit:["tr"],unsupported:!1},rowgroup:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-errormessage"]},owned:{all:["row"]},nameFrom:["author","contents"],context:["grid","table","treegrid"],implicit:["tbody","thead","tfoot"],unsupported:!1},rowheader:{type:"structure",attributes:{allowed:["aria-colindex","aria-colspan","aria-expanded","aria-rowindex","aria-rowspan","aria-required","aria-readonly","aria-selected","aria-sort","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["row"],implicit:["th"],unsupported:!1},scrollbar:{type:"widget",attributes:{required:["aria-controls","aria-valuenow"],allowed:["aria-valuetext","aria-orientation","aria-errormessage","aria-valuemax","aria-valuemin"]},owned:null,nameFrom:["author"],context:null,unsupported:!1},search:{type:"landmark",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:{nodeName:["aside","form","section"]}},searchbox:{type:"widget",attributes:{allowed:["aria-activedescendant","aria-autocomplete","aria-multiline","aria-readonly","aria-required","aria-placeholder","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="search"]'],unsupported:!1,allowedElements:{nodeName:"input",properties:{type:"text"}}},section:{nameFrom:["author","contents"],type:"abstract",unsupported:!1},sectionhead:{nameFrom:["author","contents"],type:"abstract",unsupported:!1},select:{nameFrom:["author"],type:"abstract",unsupported:!1},separator:{type:"structure",attributes:{allowed:["aria-expanded","aria-orientation","aria-valuenow","aria-valuemax","aria-valuemin","aria-valuetext","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["hr"],unsupported:!1,allowedElements:["li"]},slider:{type:"widget",attributes:{allowed:["aria-valuetext","aria-orientation","aria-readonly","aria-errormessage","aria-valuemax","aria-valuemin"],required:["aria-valuenow"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="range"]'],unsupported:!1},spinbutton:{type:"widget",attributes:{allowed:["aria-valuetext","aria-required","aria-readonly","aria-errormessage","aria-valuemax","aria-valuemin"],required:["aria-valuenow"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="number"]'],unsupported:!1,allowedElements:{nodeName:"input",properties:{type:"text"}}},status:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:["output"],unsupported:!1,allowedElements:["section"]},structure:{type:"abstract",unsupported:!1},switch:{type:"widget",attributes:{allowed:["aria-errormessage"],required:["aria-checked"]},owned:null,nameFrom:["author","contents"],context:null,unsupported:!1,allowedElements:["button",{nodeName:"input",properties:{type:["checkbox","image","button"]}},{nodeName:"a",attributes:{href:t}}]},tab:{type:"widget",attributes:{allowed:["aria-selected","aria-expanded","aria-setsize","aria-posinset","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["tablist"],unsupported:!1,allowedElements:[{nodeName:["button","h1","h2","h3","h4","h5","h6","li"]},{nodeName:"input",properties:{type:"button"}},{nodeName:"a",attributes:{href:t}}]},table:{type:"structure",attributes:{allowed:["aria-colcount","aria-rowcount","aria-errormessage"]},owned:{one:["rowgroup","row"]},nameFrom:["author"],context:null,implicit:["table"],unsupported:!1},tablist:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-level","aria-multiselectable","aria-orientation","aria-errormessage"]},owned:{all:["tab"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:["ol","ul"]},tabpanel:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1,allowedElements:["section"]},term:{type:"structure",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,implicit:["dt"],unsupported:!1},textbox:{type:"widget",attributes:{allowed:["aria-activedescendant","aria-autocomplete","aria-multiline","aria-readonly","aria-required","aria-placeholder","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:['input[type="text"]','input[type="email"]','input[type="password"]','input[type="tel"]','input[type="url"]',"input:not([type])","textarea"],unsupported:!1},timer:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,unsupported:!1},toolbar:{type:"structure",attributes:{allowed:["aria-activedescendant","aria-expanded","aria-orientation","aria-errormessage"]},owned:null,nameFrom:["author"],context:null,implicit:['menu[type="toolbar"]'],unsupported:!1,allowedElements:["ol","ul"]},tooltip:{type:"widget",attributes:{allowed:["aria-expanded","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:null,unsupported:!1},tree:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-multiselectable","aria-required","aria-expanded","aria-orientation","aria-errormessage"]},owned:{all:["treeitem"]},nameFrom:["author"],context:null,unsupported:!1,allowedElements:["ol","ul"]},treegrid:{type:"composite",attributes:{allowed:["aria-activedescendant","aria-colcount","aria-expanded","aria-level","aria-multiselectable","aria-readonly","aria-required","aria-rowcount","aria-orientation","aria-errormessage"]},owned:{one:["rowgroup","row"]},nameFrom:["author"],context:null,unsupported:!1},treeitem:{type:"widget",attributes:{allowed:["aria-checked","aria-selected","aria-expanded","aria-level","aria-posinset","aria-setsize","aria-errormessage"]},owned:null,nameFrom:["author","contents"],context:["group","tree"],unsupported:!1,allowedElements:["li",{nodeName:"a",attributes:{href:t}}]},widget:{type:"abstract",unsupported:!1},window:{nameFrom:["author"],type:"abstract",unsupported:!1}},n.elementsAllowedNoRole=[{nodeName:["base","body","caption","col","colgroup","datalist","dd","details","dt","head","html","keygen","label","legend","main","map","math","meta","meter","noscript","optgroup","param","picture","progress","script","source","style","template","textarea","title","track"]},{nodeName:"area",attributes:{href:t}},{nodeName:"input",properties:{type:["color","data","datatime","file","hidden","month","number","password","range","reset","submit","time","week"]}},{nodeName:"input",attributes:{list:e},properties:{type:["email","search","tel","url"]}},{nodeName:"link",attributes:{href:t}},{nodeName:"menu",attributes:{type:"context"}},{nodeName:"menuitem",attributes:{type:["command","checkbox","radio"]}},{nodeName:"select",condition:function(e){return 1<Number(e.getAttribute("size"))},properties:{multiple:!0}},{nodeName:["clippath","cursor","defs","desc","feblend","fecolormatrix","fecomponenttransfer","fecomposite","feconvolvematrix","fediffuselighting","fedisplacementmap","fedistantlight","fedropshadow","feflood","fefunca","fefuncb","fefuncg","fefuncr","fegaussianblur","feimage","femerge","femergenode","femorphology","feoffset","fepointlight","fespecularlighting","fespotlight","fetile","feturbulence","filter","hatch","hatchpath","lineargradient","marker","mask","meshgradient","meshpatch","meshrow","metadata","mpath","pattern","radialgradient","solidcolor","stop","switch","view"]}],n.elementsAllowedAnyRole=[{nodeName:"a",attributes:{href:e}},{nodeName:["abbr","address","canvas","div","p","pre","blockquote","ins","del","output","span","table","tbody","thead","tfoot","td","em","strong","small","s","cite","q","dfn","abbr","time","code","var","samp","kbd","sub","sup","i","b","u","mark","ruby","rt","rp","bdi","bdo","br","wbr","th","tr"]}],n.evaluateRoleForElement={A:function(e){var t=e.node,n=e.out;return"http://www.w3.org/2000/svg"===t.namespaceURI||(!t.href.length||n)},AREA:function(e){return!e.node.href},BUTTON:function(e){var t=e.node,n=e.role,r=e.out;return"menu"===t.getAttribute("type")?"menuitem"===n:r},IMG:function(e){var t=e.node,n=e.out;return t.alt?!n:n},INPUT:function(e){var t=e.node,n=e.role,r=e.out;switch(t.type){case"button":case"image":return r;case"checkbox":return!("button"!==n||!t.hasAttribute("aria-pressed"))||r;case"radio":return"menuitemradio"===n;case"text":return"combobox"===n||"searchbox"===n||"spinbutton"===n;default:return!1}},LI:function(e){var t=e.node,n=e.out;return!axe.utils.matchesSelector(t,"ol li, ul li")||n},MENU:function(e){return"context"!==e.node.getAttribute("type")},OPTION:function(e){var t=e.node;return!axe.utils.matchesSelector(t,"select > option, datalist > option, optgroup > option")},SELECT:function(e){var t=e.node,n=e.role;return!t.multiple&&t.size<=1&&"menu"===n},SVG:function(e){var t=e.node,n=e.out;return!(!t.parentNode||"http://www.w3.org/2000/svg"!==t.parentNode.namespaceURI)||n}},n.rolesOfType={widget:["button","checkbox","dialog","gridcell","heading","link","log","marquee","menuitem","menuitemcheckbox","menuitemradio","option","progressbar","radio","scrollbar","slider","spinbutton","status","switch","tab","tabpanel","textbox","timer","tooltip","tree","treeitem"]};var s={};commons.color=s;var h=commons.dom={},r={};function i(e,t){return i.fromDefinition(e,t)}commons.forms=r,commons.matches=i;var o=commons.table={},g=commons.text={EdgeFormDefaults:{}};commons.utils=axe.utils;l.arialabelText=function(e){return 1!==(e=e.actualNode||e).nodeType?"":e.getAttribute("aria-label")||""},l.arialabelledbyText=function(r,e){var a=1<arguments.length&&void 0!==e?e:{};return 1!==(r=r.actualNode||r).nodeType||a.inLabelledByContext||a.inControlContext?"":h.idrefs(r,"aria-labelledby").filter(function(e){return e}).reduce(function(e,t){var n=g.accessibleText(t,R({inLabelledByContext:!0,startNode:a.startNode||r},a));return e?"".concat(e," ").concat(n):n},"")},l.requiredAttr=function(e){var t=l.lookupTable.role[e];return t&&t.attributes&&t.attributes.required||[]},l.allowedAttr=function(e){var t=l.lookupTable.role[e],n=t&&t.attributes&&t.attributes.allowed||[],r=t&&t.attributes&&t.attributes.required||[];return n.concat(l.lookupTable.globalAttributes).concat(r)},l.validateAttr=function(e){return!!l.lookupTable.attributes[e]},l.getElementUnallowedRoles=function(t,e){var n=!(1<arguments.length&&void 0!==e)||e,r=t.nodeName.toUpperCase();if(!axe.utils.isHtmlElement(t))return[];var a=function(e){var t=[];if(!e)return t;if(e.hasAttribute("role")){var n=axe.utils.tokenList(e.getAttribute("role").toLowerCase());t=t.concat(n)}if(e.hasAttributeNS("http://www.idpf.org/2007/ops","type")){var r=axe.utils.tokenList(e.getAttributeNS("http://www.idpf.org/2007/ops","type").toLowerCase()).map(function(e){return"doc-".concat(e)});t=t.concat(r)}return t=t.filter(function(e){return axe.commons.aria.isValidRole(e)})}(t),o=axe.commons.aria.implicitRole(t);return a.filter(function(e){return(!n||e!==o)&&(!(n||"row"===e&&"TR"===r&&axe.utils.matchesSelector(t,'table[role="grid"] > tr'))||!l.isAriaRoleAllowedOnElement(t,e))})},l.getOwnedVirtual=function(e){var t=e.actualNode,n=e.children;if(!t||!n)throw new Error("getOwnedVirtual requires a virtual node");return h.idrefs(t,"aria-owns").reduce(function(e,t){if(t){var n=axe.utils.getNodeFromTree(t);e.push(n)}return e},n)},l.getRole=function(e,t){var n=1<arguments.length&&void 0!==t?t:{},r=n.noImplicit,a=n.fallback,o=n.abstracts,i=n.dpub;if(1!==(e=e.actualNode||e).nodeType)return null;var u=(e.getAttribute("role")||"").trim().toLowerCase(),s=(a?axe.utils.tokenList(u):[u]).filter(function(e){return!(!i&&"doc-"===e.substr(0,4))&&l.isValidRole(e,{allowAbstract:o})})[0];return s||r?s||null:l.implicitRole(e)};var a,u=/^idrefs?$/;function c(e){return e.getPropertyValue("font-family").split(/[,;]/g).map(function(e){return e.trim().toLowerCase()})}function d(e,t){var n=t.nodeName.toUpperCase(),r={TD:["TR","THEAD","TBODY","TFOOT"],TH:["TR","THEAD","TBODY","TFOOT"],INPUT:["LABEL"]},a=e.map(function(e){return e.nodeName.toUpperCase()}),o=e;for(var i in r)if(a.includes(i))for(var u=0;u<r[i].length;u++){var s=axe.commons.dom.findUp(t,r[i][u]);if(s&&-1===e.indexOf(s))axe.commons.dom.visuallyOverlaps(t.getBoundingClientRect(),s)&&o.splice(a.indexOf(i)+1,0,s);n===r[i][u]&&-1===a.indexOf(n)&&o.splice(a.indexOf(i)+1,0,t)}return o}function m(e,t){var n=e.getClientRects()[0],r=h.shadowElementsFromPoint(n.left,n.top);if(r)for(var a=0;a<r.length;a++)if(r[a]!==e&&r[a]===t)return!0;return!1}l.isAccessibleRef=function(e){e=e.actualNode||e;var t=h.getRootNode(e);t=t.documentElement||t;var n=e.id;axe._cache.get("idRefs")||(axe._cache.set("idRefs",{}),function e(n,t){n.hasAttribute&&("LABEL"===n.nodeName.toUpperCase()&&n.hasAttribute("for")&&(axe._cache.get("idRefs")[n.getAttribute("for")]=!0),t.filter(function(e){return n.hasAttribute(e)}).forEach(function(e){var t=n.getAttribute(e);axe.utils.tokenList(t).forEach(function(e){axe._cache.get("idRefs")[e]=!0})}));for(var r=0;r<n.children.length;r++)e(n.children[r],t)}(t,Object.keys(l.lookupTable.attributes).filter(function(e){var t=l.lookupTable.attributes[e].type;return u.test(t)})));return!0===axe._cache.get("idRefs")[n]},l.isAriaRoleAllowedOnElement=function(e,t){var n=e.nodeName.toUpperCase(),r=axe.commons.aria.lookupTable;if(i(e,r.elementsAllowedNoRole))return!1;if(i(e,r.elementsAllowedAnyRole))return!0;var a=r.role[t];if(!a||!a.allowedElements)return!1;var o=i(e,a.allowedElements);return Object.keys(r.evaluateRoleForElement).includes(n)?r.evaluateRoleForElement[n]({node:e,role:t,out:o}):o},l.isUnsupportedRole=function(e){var t=l.lookupTable.role[e];return!!t&&t.unsupported},l.labelVirtual=function(e){var t,n=e.actualNode;return n.getAttribute("aria-labelledby")&&(t=h.idrefs(n,"aria-labelledby").map(function(e){var t=axe.utils.getNodeFromTree(e);return t?g.visibleVirtual(t,!0):""}).join(" ").trim())?t:(t=(t=n.getAttribute("aria-label"))&&g.sanitize(t).trim())?t:null},l.label=function(e){return e=axe.utils.getNodeFromTree(e),l.labelVirtual(e)},l.namedFromContents=function(e,t){var n=(1<arguments.length&&void 0!==t?t:{}).strict;if(1!==(e=e.actualNode||e).nodeType)return!1;var r=l.getRole(e),a=l.lookupTable.role[r];return!!(a&&a.nameFrom.includes("contents")||"TABLE"===e.nodeName.toUpperCase())||!n&&(!a||["presentation","none"].includes(r))},l.isValidRole=function(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:{},n=t.allowAbstract,r=t.flagUnsupported,a=void 0!==r&&r,o=l.lookupTable.role[e],i=!!o&&o.unsupported;return!(!o||a&&i)&&(!!n||"abstract"!==o.type)},l.getRolesWithNameFromContents=function(){return Object.keys(l.lookupTable.role).filter(function(e){return l.lookupTable.role[e].nameFrom&&-1!==l.lookupTable.role[e].nameFrom.indexOf("contents")})},l.getRolesByType=function(t){return Object.keys(l.lookupTable.role).filter(function(e){return l.lookupTable.role[e].type===t})},l.getRoleType=function(e){var t=l.lookupTable.role[e];return t&&t.type||null},l.requiredOwned=function(e){"use strict";var t=null,n=l.lookupTable.role[e];return n&&(t=axe.utils.clone(n.owned)),t},l.requiredContext=function(e){"use strict";var t=null,n=l.lookupTable.role[e];return n&&(t=axe.utils.clone(n.context)),t},l.implicitNodes=function(e){"use strict";var t=null,n=l.lookupTable.role[e];return n&&n.implicit&&(t=axe.utils.clone(n.implicit)),t},l.implicitRole=function(n){"use strict";var e=Object.keys(l.lookupTable.role).map(function(e){var t=l.lookupTable.role[e];return{name:e,implicit:t&&t.implicit}}).reduce(function(e,t){return t.implicit&&t.implicit.some(function(e){return axe.utils.matchesSelector(n,e)})&&e.push(t.name),e},[]);if(!e.length)return null;for(var r,t=axe.utils.getNodeAttributes(n),a=[],o=0,i=t.length;o<i;o++){var u=t[o];u.name.match(/^aria-/)&&a.push(u.name)}return(r=a,e.map(function(e){return{score:function(e){return l.allowedAttr(e).reduce(function(e,t){return e+(-1<r.indexOf(t)?1:0)},0)}(e),name:e}}).sort(function(e,t){return t.score-e.score}).map(function(e){return e.name})).shift()},l.validateAttrValue=function(e,t){"use strict";var n,r,a=e.getAttribute(t),o=l.lookupTable.attributes[t],i=h.getRootNode(e);if(!o)return!0;if(o.allowEmpty&&(!a||""===a.trim()))return!0;switch(o.type){case"boolean":case"nmtoken":return"string"==typeof a&&o.values.includes(a.toLowerCase());case"nmtokens":return(r=axe.utils.tokenList(a)).reduce(function(e,t){return e&&o.values.includes(t)},0!==r.length);case"idref":return!(!a||!i.getElementById(a));case"idrefs":return(r=axe.utils.tokenList(a)).some(function(e){return i.getElementById(e)});case"string":return""!==a.trim();case"decimal":return!(!(n=a.match(/^[-+]?([0-9]*)\.?([0-9]*)$/))||!n[1]&&!n[2]);case"int":return/^[-+]?[0-9]+$/.test(a)}},s.centerPointOfRect=function(e){if(!(e.left>window.innerWidth)&&!(e.top>window.innerHeight))return{x:Math.min(Math.ceil(e.left+e.width/2),window.innerWidth-1),y:Math.min(Math.ceil(e.top+e.height/2),window.innerHeight-1)}},s.Color=function(e,t,n,r){this.red=e,this.green=t,this.blue=n,this.alpha=r,this.toHexString=function(){var e=Math.round(this.red).toString(16),t=Math.round(this.green).toString(16),n=Math.round(this.blue).toString(16);return"#"+(15.5<this.red?e:"0"+e)+(15.5<this.green?t:"0"+t)+(15.5<this.blue?n:"0"+n)};var a=/^rgb\((\d+), (\d+), (\d+)\)$/,o=/^rgba\((\d+), (\d+), (\d+), (\d*(\.\d+)?)\)/;this.parseRgbString=function(e){if("transparent"===e)return this.red=0,this.green=0,this.blue=0,void(this.alpha=0);var t=e.match(a);return t?(this.red=parseInt(t[1],10),this.green=parseInt(t[2],10),this.blue=parseInt(t[3],10),void(this.alpha=1)):(t=e.match(o))?(this.red=parseInt(t[1],10),this.green=parseInt(t[2],10),this.blue=parseInt(t[3],10),void(this.alpha=Math.round(100*parseFloat(t[4]))/100)):void 0},this.getRelativeLuminance=function(){var e=this.red/255,t=this.green/255,n=this.blue/255;return.2126*(e<=.03928?e/12.92:Math.pow((.055+e)/1.055,2.4))+.7152*(t<=.03928?t/12.92:Math.pow((.055+t)/1.055,2.4))+.0722*(n<=.03928?n/12.92:Math.pow((.055+n)/1.055,2.4))}},s.flattenColors=function(e,t){var n=e.alpha,r=(1-n)*t.red+n*e.red,a=(1-n)*t.green+n*e.green,o=(1-n)*t.blue+n*e.blue,i=e.alpha+t.alpha*(1-e.alpha);return new s.Color(r,a,o,i)},s.getContrast=function(e,t){if(!t||!e)return null;t.alpha<1&&(t=s.flattenColors(t,e));var n=e.getRelativeLuminance(),r=t.getRelativeLuminance();return(Math.max(r,n)+.05)/(Math.min(r,n)+.05)},s.hasValidContrastRatio=function(e,t,n,r){var a=s.getContrast(e,t),o=r&&Math.ceil(72*n)/96<14||!r&&Math.ceil(72*n)/96<18?4.5:3;return{isValid:o<a,contrastRatio:a,expectedContrastRatio:o}},s.elementHasImage=function(e,t){var n=e.nodeName.toUpperCase();if(["IMG","CANVAS","OBJECT","IFRAME","VIDEO","SVG"].includes(n))return axe.commons.color.incompleteData.set("bgColor","imgNode"),!0;var r=(t=t||window.getComputedStyle(e)).getPropertyValue("background-image"),a="none"!==r;if(a){var o=/gradient/.test(r);axe.commons.color.incompleteData.set("bgColor",o?"bgGradient":"bgImage")}return a},s.elementIsDistinct=function(e,t){var r=window.getComputedStyle(e);if("none"!==r.getPropertyValue("background-image"))return!0;if(["border-bottom","border-top","outline"].reduce(function(e,t){var n=new s.Color;return n.parseRgbString(r.getPropertyValue(t+"-color")),e||"none"!==r.getPropertyValue(t+"-style")&&0<parseFloat(r.getPropertyValue(t+"-width"))&&0!==n.alpha},!1))return!0;var n=window.getComputedStyle(t);if(c(r)[0]!==c(n)[0])return!0;var a=["text-decoration-line","text-decoration-style","font-weight","font-style","font-size"].reduce(function(e,t){return e||r.getPropertyValue(t)!==n.getPropertyValue(t)},!1),o=r.getPropertyValue("text-decoration");return o.split(" ").length<3&&(a=a||o!==n.getPropertyValue("text-decoration")),a},s.getBackgroundColor=function(r,e,t){var a=1<arguments.length&&void 0!==e?e:[];if(!0!==(2<arguments.length&&void 0!==t&&t)){var n=r.getBoundingClientRect().height-2>=2*window.innerHeight;r.scrollIntoView(n)}var o=[],i=s.getBackgroundStack(r);return(i||[]).some(function(e){var t=window.getComputedStyle(e),n=s.getOwnBackgroundColor(t);return function(e,t,n){var r=e!==t&&!h.visuallyContains(e,t)&&0!==n.alpha;r&&axe.commons.color.incompleteData.set("bgColor","elmPartiallyObscured");return r}(r,e,n)||s.elementHasImage(e,t)?(o=null,a.push(e),!0):0!==n.alpha&&(a.push(e),o.push(n),1===n.alpha)}),null===o||null===i?null:(o.push(new s.Color(255,255,255,1)),o.reduce(s.flattenColors))},s.getBackgroundStack=function(e){var t=s.filteredRectStack(e);if(null===t)return null;t=d(t,e);var n=(t=function(e){var t=e.indexOf(document.body),n=e;(1<t||-1===t)&&!s.elementHasImage(document.documentElement)&&0===s.getOwnBackgroundColor(window.getComputedStyle(document.documentElement)).alpha&&(1<t&&n.splice(t,1),n.splice(e.indexOf(document.documentElement),1),n.push(document.body));return n}(t=h.reduceToElementsBelowFloating(t,e))).indexOf(e);return function(e,t,n){if(0<e)for(var r=e-1;0<=r;r--){var a=t[r];if(m(n,a))return!0;t.splice(r,1)}return!1}(n,t,e)?(axe.commons.color.incompleteData.set("bgColor","bgOverlap"),null):-1!==n?t:null},s.filteredRectStack=function(a){var o=s.getRectStack(a);if(o&&1===o.length)return o[0];if(o&&1<o.length){var i,u=o.shift();return d(u,a),o.forEach(function(e,t){if(0!==t){var n=o[t-1],r=o[t];i=n.every(function(e,t){return e===r[t]})||u.includes(a)}}),i?o[0]:(axe.commons.color.incompleteData.set("bgColor","elmPartiallyObscuring"),null)}return axe.commons.color.incompleteData.set("bgColor","outsideViewport"),null},s.getRectStack=function(e){var t=axe.commons.color.centerPointOfRect(e.getBoundingClientRect());if(!t)return null;var n=h.shadowElementsFromPoint(t.x,t.y),r=Array.from(e.getClientRects());if(!r||r.length<=1)return[n];var a=r.filter(function(e){return e.width&&0<e.width}).map(function(e){var t=axe.commons.color.centerPointOfRect(e);if(t)return h.shadowElementsFromPoint(t.x,t.y)});return a.some(function(e){return void 0===e})?null:(a.splice(0,0,n),a)},h.isOpaque=function(e){var t=window.getComputedStyle(e);return s.elementHasImage(e,t)||1===s.getOwnBackgroundColor(t).alpha},s.getForegroundColor=function(e,t){var n=window.getComputedStyle(e),r=new s.Color;r.parseRgbString(n.getPropertyValue("color"));var a=n.getPropertyValue("opacity");if(r.alpha=r.alpha*a,1===r.alpha)return r;var o=s.getBackgroundColor(e,[],t);if(null!==o)return s.flattenColors(r,o);var i=axe.commons.color.incompleteData.get("bgColor");return axe.commons.color.incompleteData.set("fgColor",i),null},s.getOwnBackgroundColor=function(e){var t=new s.Color;if(t.parseRgbString(e.getPropertyValue("background-color")),0!==t.alpha){var n=e.getPropertyValue("opacity");t.alpha=t.alpha*n}return t},s.incompleteData=(a={},{set:function(e,t){if("string"!=typeof e)throw new Error("Incomplete data: key must be a string");return t&&(a[e]=t),a[e]},get:function(e){return a[e]},clear:function(){a={}}}),h.reduceToElementsBelowFloating=function(e,t){var n,r,a,o=["fixed","sticky"],i=[],u=!1;for(n=0;n<e.length;++n)(r=e[n])===t&&(u=!0),a=window.getComputedStyle(r),u||-1===o.indexOf(a.position)?i.push(r):i=[];return i},h.findElmsInContext=function(e){var t,n=e.context,r=e.value,a=e.attr,o=e.elm,i=void 0===o?"":o,u=axe.utils.escapeSelector(r);return t=9===n.nodeType||11===n.nodeType?n:h.getRootNode(n),Array.from(t.querySelectorAll(i+"["+a+"="+u+"]"))},h.findUp=function(e,t){return h.findUpVirtual(axe.utils.getNodeFromTree(e),t)},h.findUpVirtual=function(e,t){var n;if(n=e.actualNode,!e.shadowId&&"function"==typeof e.actualNode.closest){var r=e.actualNode.closest(t);return r||null}for(;(n=n.assignedSlot?n.assignedSlot:n.parentNode)&&11===n.nodeType&&(n=n.host),n&&!axe.utils.matchesSelector(n,t)&&n!==document.documentElement;);return n&&axe.utils.matchesSelector(n,t)?n:null},h.getComposedParent=function e(t){if(t.assignedSlot)return e(t.assignedSlot);if(t.parentNode){var n=t.parentNode;if(1===n.nodeType)return n;if(n.host)return n.host}return null},h.getElementByReference=function(e,t){var n=e.getAttribute(t);if(!n)return null;"#"===n.charAt(0)?n=decodeURIComponent(n.substring(1)):"/#"===n.substr(0,2)&&(n=decodeURIComponent(n.substring(2)));var r=document.getElementById(n);return r||((r=document.getElementsByName(n)).length?r[0]:null)},h.getElementCoordinates=function(e){"use strict";var t=h.getScrollOffset(document),n=t.left,r=t.top,a=e.getBoundingClientRect();return{top:a.top+r,right:a.right+n,bottom:a.bottom+r,left:a.left+n,width:a.right-a.left,height:a.bottom-a.top}},h.getRootNode=axe.utils.getRootNode,h.getScrollOffset=function(e){"use strict";if(!e.nodeType&&e.document&&(e=e.document),9!==e.nodeType)return{left:e.scrollLeft,top:e.scrollTop};var t=e.documentElement,n=e.body;return{left:t&&t.scrollLeft||n&&n.scrollLeft||0,top:t&&t.scrollTop||n&&n.scrollTop||0}},h.getTabbableElements=function(e){return axe.utils.querySelectorAll(e,"*").filter(function(e){var t=e.isFocusable,n=e.actualNode.getAttribute("tabindex");return(n=n&&!isNaN(parseInt(n,10))?parseInt(n):null)?t&&0<=n:t})},h.getViewportSize=function(e){"use strict";var t,n=e.document,r=n.documentElement;return e.innerWidth?{width:e.innerWidth,height:e.innerHeight}:r?{width:r.clientWidth,height:r.clientHeight}:{width:(t=n.body).clientWidth,height:t.clientHeight}};var p=["HEAD","TITLE","TEMPLATE","SCRIPT","STYLE","IFRAME","OBJECT","VIDEO","AUDIO","NOSCRIPT"];function f(e){return e.disabled||h.isHiddenWithCSS(e)&&"AREA"!==e.nodeName.toUpperCase()}h.hasContentVirtual=function(e,t,n){return function(e){if(!p.includes(e.actualNode.nodeName.toUpperCase()))return e.children.some(function(e){var t=e.actualNode;return 3===t.nodeType&&t.nodeValue.trim()})}(e)||h.isVisualContent(e.actualNode)||!!n||!!l.labelVirtual(e)||!t&&e.children.some(function(e){return 1===e.actualNode.nodeType&&h.hasContentVirtual(e)})},h.hasContent=function(e,t,n){return e=axe.utils.getNodeFromTree(e),h.hasContentVirtual(e,t,n)},h.idrefs=function(e,t){"use strict";var n,r,a=h.getRootNode(e),o=[],i=e.getAttribute(t);if(i)for(n=0,r=(i=axe.utils.tokenList(i)).length;n<r;n++)o.push(a.getElementById(i[n]));return o},h.isFocusable=function(e){"use strict";if(f(e))return!1;if(h.isNativelyFocusable(e))return!0;var t=e.getAttribute("tabindex");return!(!t||isNaN(parseInt(t,10)))},h.isNativelyFocusable=function(e){"use strict";if(!e||f(e))return!1;switch(e.nodeName.toUpperCase()){case"A":case"AREA":if(e.href)return!0;break;case"INPUT":return"hidden"!==e.type;case"TEXTAREA":case"SELECT":case"DETAILS":case"BUTTON":return!0}return!1},h.insertedIntoFocusOrder=function(e){return-1<e.tabIndex&&h.isFocusable(e)&&!h.isNativelyFocusable(e)},h.isHiddenWithCSS=function(e,t){if(9===e.nodeType)return!1;if(11===e.nodeType&&(e=e.host),["STYLE","SCRIPT"].includes(e.nodeName.toUpperCase()))return!1;var n=window.getComputedStyle(e,null);if(!n)throw new Error("Style does not exist for the given element.");if("none"===n.getPropertyValue("display"))return!0;var r=["hidden","collapse"],a=n.getPropertyValue("visibility");if(r.includes(a)&&!t)return!0;if(r.includes(a)&&t&&r.includes(t))return!0;var o=h.getComposedParent(e);return!(!o||r.includes(a))&&h.isHiddenWithCSS(o,a)},h.isHTML5=function(e){var t=e.doctype;return null!==t&&("html"===t.name&&!t.publicId&&!t.systemId)};var b=["block","list-item","table","flex","grid","inline-block"];function y(e){var t=window.getComputedStyle(e).getPropertyValue("display");return b.includes(t)||"table-"===t.substr(0,6)}h.isInTextBlock=function(n){if(y(n))return!1;var e=function(e){for(var t=h.getComposedParent(e);t&&!y(t);)t=h.getComposedParent(t);return axe.utils.getNodeFromTree(t)}(n),r="",a="",o=0;return function t(e,n){!1!==n(e.actualNode)&&e.children.forEach(function(e){return t(e,n)})}(e,function(e){if(2===o)return!1;if(3===e.nodeType&&(r+=e.nodeValue),1===e.nodeType){var t=(e.nodeName||"").toUpperCase();if(["BR","HR"].includes(t))0===o?a=r="":o=2;else{if("none"===e.style.display||"hidden"===e.style.overflow||!["",null,"none"].includes(e.style.float)||!["",null,"relative"].includes(e.style.position))return!1;if("A"===t&&e.href||"link"===(e.getAttribute("role")||"").toLowerCase())return e===n&&(o=1),a+=e.textContent,!1}}}),r=axe.commons.text.sanitize(r),a=axe.commons.text.sanitize(a),r.length>a.length},h.isNode=function(e){"use strict";return e instanceof Node},h.isOffscreen=function(e){var t,n=document.documentElement,r=window.getComputedStyle(e),a=window.getComputedStyle(document.body||n).getPropertyValue("direction"),o=h.getElementCoordinates(e);if(o.bottom<0&&(function(e,t){for(e=h.getComposedParent(e);e&&"html"!==e.nodeName.toLowerCase();){if(e.scrollTop&&0<=(t+=e.scrollTop))return!1;e=h.getComposedParent(e)}return!0}(e,o.bottom)||"absolute"===r.position))return!0;if(0===o.left&&0===o.right)return!1;if("ltr"===a){if(o.right<=0)return!0}else if(t=Math.max(n.scrollWidth,h.getViewportSize(window).width),o.left>=t)return!0;return!1};var v=/^\/?#[^/!]/;h.isSkipLink=function(e){return!!v.test(e.getAttribute("href"))&&(void 0!==axe._cache.get("firstPageLink")?t=axe._cache.get("firstPageLink"):(t=axe.utils.querySelectorAll(axe._tree,'a:not([href^="#"]):not([href^="/#"]):not([href^="javascript"])')[0],axe._cache.set("firstPageLink",t||null)),!t||e.compareDocumentPosition(t.actualNode)===e.DOCUMENT_POSITION_FOLLOWING);var t},h.isVisible=function(e,t,n){"use strict";var r=axe.utils.getNodeFromTree(e),a="_isVisible"+(t?"ScreenReader":"");if(9===e.nodeType)return!0;if(11===e.nodeType&&(e=e.host),r&&void 0!==r[a])return r[a];var o=window.getComputedStyle(e,null);if(null===o)return!1;var i=e.nodeName.toUpperCase();if("none"===o.getPropertyValue("display")||["STYLE","SCRIPT","NOSCRIPT","TEMPLATE"].includes(i)||!t&&function(e){"use strict";var t=e.match(/rect\s*\(([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px,?\s*([0-9]+)px\s*\)/);return!(!t||5!==t.length)&&(t[3]-t[1]<=0&&t[2]-t[4]<=0)}(o.getPropertyValue("clip"))||!n&&("hidden"===o.getPropertyValue("visibility")||!t&&h.isOffscreen(e))||t&&"true"===e.getAttribute("aria-hidden"))return!1;var u=e.assignedSlot?e.assignedSlot:e.parentNode,s=!1;return u&&(s=h.isVisible(u,t,!0)),r&&(r[a]=s),s};var D=["checkbox","img","radio","range","slider","spinbutton","textbox"];h.isVisualContent=function(e){var t=e.getAttribute("role");if(t)return-1!==D.indexOf(t);switch(e.nodeName.toUpperCase()){case"IMG":case"IFRAME":case"OBJECT":case"VIDEO":case"AUDIO":case"CANVAS":case"SVG":case"MATH":case"BUTTON":case"SELECT":case"TEXTAREA":case"KEYGEN":case"PROGRESS":case"METER":return!0;case"INPUT":return"hidden"!==e.type;default:return!1}},h.shadowElementsFromPoint=function(r,a){var t=2<arguments.length&&void 0!==arguments[2]?arguments[2]:document,o=3<arguments.length&&void 0!==arguments[3]?arguments[3]:0;if(999<o)throw new Error("Infinite loop detected");return Array.from(t.elementsFromPoint(r,a)).filter(function(e){return h.getRootNode(e)===t}).reduce(function(e,t){if(axe.utils.isShadowRoot(t)){var n=h.shadowElementsFromPoint(r,a,t.shadowRoot,o+1);(e=e.concat(n)).length&&axe.commons.dom.visuallyContains(e[0],t)&&e.push(t)}else e.push(t);return e},[])},h.visuallyContains=function(e,t){var n=e.getBoundingClientRect(),r=n.top+.01,a=n.bottom-.01,o=n.left+.01,i=n.right-.01,u=t.getBoundingClientRect(),s=u.top,l=u.left,c=s-t.scrollTop,d=s-t.scrollTop+t.scrollHeight,m=l-t.scrollLeft,p=l-t.scrollLeft+t.scrollWidth,f=window.getComputedStyle(t);return"inline"===f.getPropertyValue("display")||!(o<m&&o<u.left||r<c&&r<u.top||p<i&&i>u.right||d<a&&a>u.bottom)&&(!(i>u.right||a>u.bottom)||("scroll"===f.overflow||"auto"===f.overflow||"hidden"===f.overflow||t instanceof HTMLBodyElement||t instanceof HTMLHtmlElement))},h.visuallyOverlaps=function(e,t){var n=t.getBoundingClientRect(),r=n.top,a=n.left,o=r-t.scrollTop,i=r-t.scrollTop+t.scrollHeight,u=a-t.scrollLeft,s=a-t.scrollLeft+t.scrollWidth;if(e.left>s&&e.left>n.right||e.top>i&&e.top>n.bottom||e.right<u&&e.right<n.left||e.bottom<o&&e.bottom<n.top)return!1;var l=window.getComputedStyle(t);return!(e.left>n.right||e.top>n.bottom)||("scroll"===l.overflow||"auto"===l.overflow||t instanceof HTMLBodyElement||t instanceof HTMLHtmlElement)},r.isAriaCombobox=function(e){return"combobox"===axe.commons.aria.getRole(e,{noImplicit:!0})},r.isAriaListbox=function(e){return"listbox"===axe.commons.aria.getRole(e,{noImplicit:!0})};var w=["progressbar","scrollbar","slider","spinbutton"];r.isAriaRange=function(e){var t=axe.commons.aria.getRole(e,{noImplicit:!0});return w.includes(t)},r.isAriaTextbox=function(e){return"textbox"===axe.commons.aria.getRole(e,{noImplicit:!0})},r.isNativeSelect=function(e){return"SELECT"===e.nodeName.toUpperCase()};var k=["button","checkbox","color","file","hidden","image","password","radio","reset","submit"];r.isNativeTextbox=function(e){var t=e.nodeName.toUpperCase();return"TEXTAREA"===t||"INPUT"===t&&!k.includes(e.type)},i.attributes=function(t,e){return t=t.actualNode||t,i.fromFunction(function(e){return t.getAttribute(e)},e)},i.condition=function(e,t){return!!t(e)};var x,E=["nodeName","attributes","properties","condition"];function C(e){var t=e.actualNode;return 3!==t.nodeType?"":t.textContent}i.fromDefinition=function(r,a){return r=r.actualNode||r,Array.isArray(a)?a.some(function(e){return i(r,e)}):"string"==typeof a?axe.utils.matchesSelector(r,a):Object.keys(a).every(function(e){if(!E.includes(e))throw new Error('Unknown matcher type "'.concat(e,'"'));var t=i[e],n=a[e];return t(r,n)})},i.fromFunction=function(t,n){if("object"!==S(n)||Array.isArray(n)||n instanceof RegExp)throw new Error("Expect matcher to be an object");return Object.keys(n).every(function(e){return i.fromPrimative(t(e),n[e])})},i.fromPrimative=function(e,t){var n=S(t);return Array.isArray(t)&&void 0!==e?t.includes(e):"function"===n?!!t(e):t instanceof RegExp?t.test(e):t===e},i.nodeName=function(e,t,n){var r=(2<arguments.length&&void 0!==n?n:{}).isXHTML;if(e=e.actualNode||e,void 0===r){if("string"==typeof t)return axe.utils.matchesSelector(e,t);void 0===x&&(x=axe.utils.isXHTML(e.ownerDocument)),r=x}var a=r?e.nodeName:e.nodeName.toLowerCase();return i.fromPrimative(a,t)},i.properties=function(t,e){return t=t.actualNode||t,i.fromFunction(function(e){return t[e]},e)},o.getAllCells=function(e){var t,n,r,a,o=[];for(t=0,r=e.rows.length;t<r;t++)for(n=0,a=e.rows[t].cells.length;n<a;n++)o.push(e.rows[t].cells[n]);return o},o.getCellPosition=function(e,t){var n,r;for(t=t||o.toGrid(h.findUp(e,"table")),n=0;n<t.length;n++)if(t[n]&&-1!==(r=t[n].indexOf(e)))return{x:r,y:n}},o.getHeaders=function(e){if(e.hasAttribute("headers"))return commons.dom.idrefs(e,"headers");var t=commons.table.toGrid(commons.dom.findUp(e,"table")),n=commons.table.getCellPosition(e,t),r=o.traverse("left",n,t).filter(function(e){return o.isRowHeader(e)}),a=o.traverse("up",n,t).filter(function(e){return o.isColumnHeader(e)});return[].concat(r,a).reverse()},o.getScope=function(e){var t=e.getAttribute("scope"),n=e.getAttribute("role");if(e instanceof Element==!1||-1===["TD","TH"].indexOf(e.nodeName.toUpperCase()))throw new TypeError("Expected TD or TH element");if("columnheader"===n)return"col";if("rowheader"===n)return"row";if("col"===t||"row"===t)return t;if("TH"!==e.nodeName.toUpperCase())return!1;var r=o.toGrid(h.findUp(e,"table")),a=o.getCellPosition(e);return r[a.y].reduce(function(e,t){return e&&"TH"===t.nodeName.toUpperCase()},!0)?"col":r.map(function(e){return e[a.x]}).reduce(function(e,t){return e&&t&&"TH"===t.nodeName.toUpperCase()},!0)?"row":"auto"},o.isColumnHeader=function(e){return-1!==["col","auto"].indexOf(o.getScope(e))},o.isDataCell=function(e){if(!e.children.length&&!e.textContent.trim())return!1;var t=e.getAttribute("role");return axe.commons.aria.isValidRole(t)?["cell","gridcell"].includes(t):"TD"===e.nodeName.toUpperCase()},o.isDataTable=function(e){var t=(e.getAttribute("role")||"").toLowerCase();if(("presentation"===t||"none"===t)&&!h.isFocusable(e))return!1;if("true"===e.getAttribute("contenteditable")||h.findUp(e,'[contenteditable="true"]'))return!0;if("grid"===t||"treegrid"===t||"table"===t)return!0;if("landmark"===commons.aria.getRoleType(t))return!0;if("0"===e.getAttribute("datatable"))return!1;if(e.getAttribute("summary"))return!0;if(e.tHead||e.tFoot||e.caption)return!0;for(var n=0,r=e.children.length;n<r;n++)if("COLGROUP"===e.children[n].nodeName.toUpperCase())return!0;for(var a,o,i=0,u=e.rows.length,s=!1,l=0;l<u;l++)for(var c=0,d=(a=e.rows[l]).cells.length;c<d;c++){if("TH"===(o=a.cells[c]).nodeName.toUpperCase())return!0;if(s||o.offsetWidth===o.clientWidth&&o.offsetHeight===o.clientHeight||(s=!0),o.getAttribute("scope")||o.getAttribute("headers")||o.getAttribute("abbr"))return!0;if(["columnheader","rowheader"].includes((o.getAttribute("role")||"").toLowerCase()))return!0;if(1===o.children.length&&"ABBR"===o.children[0].nodeName.toUpperCase())return!0;i++}if(e.getElementsByTagName("table").length)return!1;if(u<2)return!1;var m,p,f=e.rows[Math.ceil(u/2)];if(1===f.cells.length&&1===f.cells[0].colSpan)return!1;if(5<=f.cells.length)return!0;if(s)return!0;for(l=0;l<u;l++){if(a=e.rows[l],m&&m!==window.getComputedStyle(a).getPropertyValue("background-color"))return!0;if(m=window.getComputedStyle(a).getPropertyValue("background-color"),p&&p!==window.getComputedStyle(a).getPropertyValue("background-image"))return!0;p=window.getComputedStyle(a).getPropertyValue("background-image")}return 20<=u||!(h.getElementCoordinates(e).width>.95*h.getViewportSize(window).width)&&(!(i<10)&&!e.querySelector("object, embed, iframe, applet"))},o.isHeader=function(e){if(o.isColumnHeader(e)||o.isRowHeader(e))return!0;if(e.getAttribute("id")){var t=axe.utils.escapeSelector(e.getAttribute("id"));return!!document.querySelector('[headers~="'.concat(t,'"]'))}return!1},o.isRowHeader=function(e){return["row","auto"].includes(o.getScope(e))},o.toGrid=function(e){for(var t=[],n=e.rows,r=0,a=n.length;r<a;r++){var o=n[r].cells;t[r]=t[r]||[];for(var i=0,u=0,s=o.length;u<s;u++)for(var l=0;l<o[u].colSpan;l++){for(var c=0;c<o[u].rowSpan;c++){for(t[r+c]=t[r+c]||[];t[r+c][i];)i++;t[r+c][i]=o[u]}i++}}return t},o.toArray=o.toGrid,o.traverse=function(e,t,n,r){if(Array.isArray(t)&&(r=n,n=t,t={x:0,y:0}),"string"==typeof e)switch(e){case"left":e={x:-1,y:0};break;case"up":e={x:0,y:-1};break;case"right":e={x:1,y:0};break;case"down":e={x:0,y:1}}return function e(t,n,r,a){var o,i=r[n.y]?r[n.y][n.x]:void 0;return i?"function"==typeof a&&!0===(o=a(i,n,r))?[i]:((o=e(t,{x:n.x+t.x,y:n.y+t.y},r,a)).unshift(i),o):[]}(e,{x:t.x+e.x,y:t.y+e.y},n,r)},g.accessibleText=function(e,t){var n=axe.utils.getNodeFromTree(e);return g.accessibleTextVirtual(n,t)},g.accessibleTextVirtual=function(n,e){var r=1<arguments.length&&void 0!==e?e:{},t=n.actualNode;if(r=function(e,t){var n=e.actualNode;t.startNode||(t=R({startNode:e},t));1===n.nodeType&&t.inLabelledByContext&&void 0===t.includeHidden&&(t=R({includeHidden:!h.isVisible(n,!0)},t));return t}(n,r),function(e,t){var n=e.actualNode;if(1!==n.nodeType||t.includeHidden)return!1;return!h.isVisible(n,!0)}(n,r))return"";var a=[l.arialabelledbyText,l.arialabelText,g.nativeTextAlternative,g.formControlValue,g.subtreeText,C,g.titleText].reduce(function(e,t){return r.startNode===n&&(e=g.sanitize(e)),""!==e?e:t(n,r)},"");return r.debug&&axe.log(a||"{empty-value}",t,r),a},g.accessibleTextVirtual.alreadyProcessed=function(e,t){return t.processed=t.processed||[],!!t.processed.includes(e)||(t.processed.push(e),!1)};var A=["textbox","progressbar","scrollbar","slider","spinbutton","combobox","listbox"];g.formControlValueMethods={nativeTextboxValue:function(e){if(e=e.actualNode||e,axe.commons.forms.isNativeTextbox(e))return e.value||"";return""},nativeSelectValue:function(e){return e=e.actualNode||e,axe.commons.forms.isNativeSelect(e)&&Array.from(e.options).filter(function(e){return e.selected}).map(function(e){return e.text}).join(" ")||""},ariaTextboxValue:function(e){var t=e.actualNode;if(!axe.commons.forms.isAriaTextbox(t))return"";return h.isHiddenWithCSS(t)?t.textContent:g.visibleVirtual(e,!0)},ariaListboxValue:function(e,t){var n=e.actualNode;if(!axe.commons.forms.isAriaListbox(n))return"";var r=l.getOwnedVirtual(e).filter(function(e){return"option"===l.getRole(e)&&"true"===e.actualNode.getAttribute("aria-selected")});return 0!==r.length?axe.commons.text.accessibleTextVirtual(r[0],t):""},ariaComboboxValue:function(e,t){var n,r=e.actualNode;return axe.commons.forms.isAriaCombobox(r)&&(n=l.getOwnedVirtual(e).filter(function(e){return"listbox"===l.getRole(e)})[0])?g.formControlValueMethods.ariaListboxValue(n,t):""},ariaRangeValue:function(e){if(e=e.actualNode||e,!axe.commons.forms.isAriaRange(e)||!e.hasAttribute("aria-valuenow"))return"";var t=+e.getAttribute("aria-valuenow");return isNaN(t)?"0":String(t)}},g.formControlValue=function(n,e){var r=1<arguments.length&&void 0!==e?e:{},t=n.actualNode,a=g.unsupported.accessibleNameFromFieldValue||[],o=l.getRole(t);if(r.startNode===n||!A.includes(o)||a.includes(o))return"";var i=Object.keys(g.formControlValueMethods).map(function(e){return g.formControlValueMethods[e]}).reduce(function(e,t){return e||t(n,r)},"");return r.debug&&axe.log(i||"{empty-value}",t,r),i},g.isHumanInterpretable=function(e){if(!e.length)return 0;if(["x","i"].includes(e))return 0;var t=g.removeUnicode(e,{emoji:!0,nonBmp:!0,punctuations:!0});return g.sanitize(t)?1:0};g.autocomplete={stateTerms:["on","off"],standaloneTerms:["name","honorific-prefix","given-name","additional-name","family-name","honorific-suffix","nickname","username","new-password","current-password","organization-title","organization","street-address","address-line1","address-line2","address-line3","address-level4","address-level3","address-level2","address-level1","country","country-name","postal-code","cc-name","cc-given-name","cc-additional-name","cc-family-name","cc-number","cc-exp","cc-exp-month","cc-exp-year","cc-csc","cc-type","transaction-currency","transaction-amount","language","bday","bday-day","bday-month","bday-year","sex","url","photo"],qualifiers:["home","work","mobile","fax","pager"],qualifiedTerms:["tel","tel-country-code","tel-national","tel-area-code","tel-local","tel-local-prefix","tel-local-suffix","tel-extension","email","impp"],locations:["billing","shipping"]},g.isValidAutocomplete=function(e,t){var n=1<arguments.length&&void 0!==t?t:{},r=n.looseTyped,a=void 0!==r&&r,o=n.stateTerms,i=void 0===o?[]:o,u=n.locations,s=void 0===u?[]:u,l=n.qualifiers,c=void 0===l?[]:l,d=n.standaloneTerms,m=void 0===d?[]:d,p=n.qualifiedTerms,f=void 0===p?[]:p;if(e=e.toLowerCase().trim(),(i=i.concat(g.autocomplete.stateTerms)).includes(e)||""===e)return!0;c=c.concat(g.autocomplete.qualifiers),s=s.concat(g.autocomplete.locations),m=m.concat(g.autocomplete.standaloneTerms),f=f.concat(g.autocomplete.qualifiedTerms);var h=e.split(/\s+/g);if(!a&&(8<h[0].length&&"section-"===h[0].substr(0,8)&&h.shift(),s.includes(h[0])&&h.shift(),c.includes(h[0])&&(h.shift(),m=[]),1!==h.length))return!1;var b=h[h.length-1];return m.includes(b)||f.includes(b)},g.labelText=function(e,t){var n=1<arguments.length&&void 0!==t?t:{},r=g.accessibleTextVirtual.alreadyProcessed;if(n.inControlContext||n.inLabelledByContext||r(e,n))return"";n.startNode||(n.startNode=e);var a,o=R({inControlContext:!0},n),i=function(e){var t=e.actualNode;return t.id?h.findElmsInContext({elm:"label",attr:"for",value:t.id,context:t}):[]}(e),u=h.findUpVirtual(e,"label");return u?(a=[].concat(he(i),[u])).sort(axe.utils.nodeSorter):a=i,a.map(function(e){return g.accessibleText(e,o)}).filter(function(e){return""!==e}).join(" ")},g.labelVirtual=function(e){var t,n;if(n=l.labelVirtual(e))return n;if(e.actualNode.id){var r=axe.utils.escapeSelector(e.actualNode.getAttribute("id"));if(n=(t=axe.commons.dom.getRootNode(e.actualNode).querySelector('label[for="'+r+'"]'))&&g.visible(t,!0))return n}return(n=(t=h.findUpVirtual(e,"label"))&&g.visible(t,!0))||null},g.label=function(e){return e=axe.utils.getNodeFromTree(e),g.labelVirtual(e)},g.nativeElementType=[{matches:[{nodeName:"textarea"},{nodeName:"input",properties:{type:["text","password","search","tel","email","url"]}}],namingMethods:"labelText"},{matches:{nodeName:"input",properties:{type:["button","submit","reset"]}},namingMethods:["valueText","titleText","buttonDefaultText"]},{matches:{nodeName:"input",properties:{type:"image"}},namingMethods:["altText","valueText","labelText","titleText","buttonDefaultText"]},{matches:"button",namingMethods:"subtreeText"},{matches:"fieldset",namingMethods:"fieldsetLegendText"},{matches:"OUTPUT",namingMethods:"subtreeText"},{matches:[{nodeName:"select"},{nodeName:"input",properties:{type:/^(?!text|password|search|tel|email|url|button|submit|reset)/}}],namingMethods:"labelText"},{matches:"summary",namingMethods:"subtreeText"},{matches:"figure",namingMethods:["figureText","titleText"]},{matches:"img",namingMethods:"altText"},{matches:"table",namingMethods:["tableCaptionText","tableSummaryText"]},{matches:["hr","br"],namingMethods:["titleText","singleSpace"]}],g.nativeTextAlternative=function(n,e){var r=1<arguments.length&&void 0!==e?e:{},t=n.actualNode;if(1!==t.nodeType||["presentation","none"].includes(l.getRole(t)))return"";var a=function(n){var e=g.nativeElementType,t=g.nativeTextMethods,r=e.find(function(e){var t=e.matches;return axe.commons.matches(n,t)});return(r?[].concat(r.namingMethods):[]).map(function(e){return t[e]})}(n).reduce(function(e,t){return e||t(n,r)},"");return r.debug&&axe.log(a||"{empty-value}",t,r),a};var F={submit:"Submit",image:"Submit",reset:"Reset",button:""};function j(e,t){return t.actualNode.getAttribute(e)||""}function z(e,t,n){var r=t.actualNode,a=[e=e.toLowerCase(),r.nodeName.toLowerCase()].join(","),o=r.querySelector(a);return o&&o.nodeName.toLowerCase()===e?g.accessibleText(o,n):""}g.nativeTextMethods={valueText:function(e){return e.actualNode.value||""},buttonDefaultText:function(e){var t=e.actualNode;return F[t.type]||""},tableCaptionText:z.bind(null,"caption"),figureText:z.bind(null,"figcaption"),fieldsetLegendText:z.bind(null,"legend"),altText:j.bind(null,"alt"),tableSummaryText:j.bind(null,"summary"),titleText:function(e,t){return g.titleText(e,t)},subtreeText:function(e,t){return g.subtreeText(e,t)},labelText:function(e,t){return g.labelText(e,t)},singleSpace:function(){return" "}},g.sanitize=function(e){"use strict";return e.replace(/\r\n/g,"\n").replace(/\u00A0/g," ").replace(/[\s]{2,}/g," ").trim()},g.subtreeText=function(e,t){var n=1<arguments.length&&void 0!==t?t:{},r=g.accessibleTextVirtual.alreadyProcessed;n.startNode=n.startNode||e;var a=n.strict;return r(e,n)||!l.namedFromContents(e,{strict:a})?"":l.getOwnedVirtual(e).reduce(function(e,t){return function(e,t,n){var r=t.actualNode.nodeName.toUpperCase(),a=g.accessibleTextVirtual(t,n);if(!a)return e;q.includes(r)||(" "!==a[0]&&(a+=" "),e&&" "!==e[e.length-1]&&(a=" "+a));return e+a}(e,t,n)},"")};var q=["A","EM","STRONG","SMALL","MARK","ABBR","DFN","I","B","S","U","CODE","VAR","SAMP","KBD","SUP","SUB","Q","CITE","SPAN","BDO","BDI","WBR","INS","DEL","MAP","AREA","NOSCRIPT","RUBY","BUTTON","LABEL","OUTPUT","DATALIST","KEYGEN","PROGRESS","COMMAND","CANVAS","TIME","METER","#TEXT"];var N=["button","iframe","a[href]",{nodeName:"input",properties:{type:"button"}}];function T(){return new RegExp("[ᴀ-ᵿᶀ-ᶿ᷀-᷿₠-⃏⃐-⃿℀-⅏⅐-↏←-⇿∀-⋿⌀-⏿␀-␿⑀-⑟①-⓿─-╿▀-▟■-◿☀-⛿✀-➿]")}return g.titleText=function(e){return 1===(e=e.actualNode||e).nodeType&&e.hasAttribute("title")?!axe.commons.matches(e,N)&&["none","presentation"].includes(l.getRole(e))?"":e.getAttribute("title"):""},g.hasUnicode=function(e,t){var n=t.emoji,r=t.nonBmp,a=t.punctuations;return n?axe.imports.emojiRegexText().test(e):r?T().test(e):!!a&&/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]/g.test(e)},g.removeUnicode=function(e,t){var n=t.emoji,r=t.nonBmp,a=t.punctuations;return n&&(e=e.replace(axe.imports.emojiRegexText(),"")),r&&(e=e.replace(T(),"")),a&&(e=e.replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]/g,"")),e},g.unsupported={accessibleNameFromFieldValue:["combobox","listbox","progressbar"]},g.visibleVirtual=function(n,r,a){var e=n.children.map(function(e){if(3===e.actualNode.nodeType){var t=e.actualNode.nodeValue;if(t&&h.isVisible(n.actualNode,r))return t}else if(!a)return g.visibleVirtual(e,r)}).join("");return g.sanitize(e)},g.visible=function(e,t,n){return e=axe.utils.getNodeFromTree(e),g.visibleVirtual(e,t,n)},commons}()})}("object"==typeof window?window:this);
\ No newline at end of file
diff --git a/third_party/blink/common/loader/url_loader_factory_bundle.cc b/third_party/blink/common/loader/url_loader_factory_bundle.cc
index 1476bf6..237565d4 100644
--- a/third_party/blink/common/loader/url_loader_factory_bundle.cc
+++ b/third_party/blink/common/loader/url_loader_factory_bundle.cc
@@ -110,7 +110,7 @@
 }
 
 void URLLoaderFactoryBundle::Clone(
-    network::mojom::URLLoaderFactoryRequest request) {
+    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver) {
   NOTREACHED();
 }
 
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn
index 7b773af..b04dc16 100644
--- a/third_party/blink/public/BUILD.gn
+++ b/third_party/blink/public/BUILD.gn
@@ -291,7 +291,6 @@
     "platform/web_resource_timing_info.h",
     "platform/web_rtc_answer_options.h",
     "platform/web_rtc_api_name.h",
-    "platform/web_rtc_certificate_generator.h",
     "platform/web_rtc_data_channel_init.h",
     "platform/web_rtc_dtmf_sender_handler.h",
     "platform/web_rtc_dtmf_sender_handler_client.h",
@@ -373,7 +372,10 @@
     "web/modules/mediastream/web_media_stream_utils.h",
     "web/modules/mediastream/webmediaplayer_ms.h",
     "web/modules/peerconnection/media_stream_remote_video_source.h",
+    "web/modules/peerconnection/media_stream_video_webrtc_sink.h",
     "web/modules/peerconnection/peer_connection_dependency_factory.h",
+    "web/modules/peerconnection/webrtc_media_stream_track_adapter.h",
+    "web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h",
     "web/modules/service_worker/web_service_worker_context_client.h",
     "web/modules/service_worker/web_service_worker_context_proxy.h",
     "web/modules/webrtc/webrtc_audio_device_impl.h",
diff --git a/third_party/blink/public/common/loader/url_loader_factory_bundle.h b/third_party/blink/public/common/loader/url_loader_factory_bundle.h
index f7d3633..fe81a9a 100644
--- a/third_party/blink/public/common/loader/url_loader_factory_bundle.h
+++ b/third_party/blink/public/common/loader/url_loader_factory_bundle.h
@@ -11,6 +11,7 @@
 #include <utility>
 
 #include "base/macros.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/mojom/url_loader_factory.mojom.h"
@@ -109,7 +110,8 @@
                             network::mojom::URLLoaderClientPtr client,
                             const net::MutableNetworkTrafficAnnotationTag&
                                 traffic_annotation) override;
-  void Clone(network::mojom::URLLoaderFactoryRequest request) override;
+  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
+      override;
   std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override;
   bool BypassRedirectChecks() const override;
 
diff --git a/third_party/blink/public/common/notifications/notification_constants.h b/third_party/blink/public/common/notifications/notification_constants.h
index c88e3b7..edda92a5 100644
--- a/third_party/blink/public/common/notifications/notification_constants.h
+++ b/third_party/blink/public/common/notifications/notification_constants.h
@@ -14,6 +14,32 @@
 constexpr base::TimeDelta kMaxNotificationShowTriggerDelay =
     base::TimeDelta::FromDays(367);
 
+// TODO(johnme): The maximum number of actions is platform-specific and should
+// be indicated by the embedder.
+
+// Maximum number of actions on a Platform Notification.
+constexpr size_t kNotificationMaxActions = 2;
+
+// TODO(mvanouwerkerk): Update the notification resource loader to get the
+// appropriate image sizes from the embedder.
+
+// The maximum reasonable image size, scaled from dip units to pixels using the
+// largest supported scaling factor. TODO(johnme): Check sizes are correct.
+constexpr int kNotificationMaxImageWidthPx = 1800;  // 450 dip * 4
+constexpr int kNotificationMaxImageHeightPx = 900;  // 225 dip * 4
+
+// The maximum reasonable notification icon size, scaled from dip units to
+// pixels using the largest supported scaling factor.
+constexpr int kNotificationMaxIconSizePx = 320;  // 80 dip * 4
+
+// The maximum reasonable badge size, scaled from dip units to pixels using the
+// largest supported scaling factor.
+constexpr int kNotificationMaxBadgeSizePx = 96;  // 24 dip * 4
+
+// The maximum reasonable action icon size, scaled from dip units to
+// pixels using the largest supported scaling factor.
+constexpr int kNotificationMaxActionIconSizePx = 128;  // 32 dip * 4
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_PUBLIC_COMMON_NOTIFICATIONS_NOTIFICATION_CONSTANTS_H_
diff --git a/third_party/blink/public/mojom/blob/blob_url_store.mojom b/third_party/blink/public/mojom/blob/blob_url_store.mojom
index fcdb204..ca0fa77 100644
--- a/third_party/blink/public/mojom/blob/blob_url_store.mojom
+++ b/third_party/blink/public/mojom/blob/blob_url_store.mojom
@@ -31,8 +31,9 @@
   // As long as the resulting URLLoaderFactory is alive the resolved blob will
   // also be kept alive, so it is possible to start loading the blob long after
   // both the blob URL and all other references to the blob have been dropped.
-  ResolveAsURLLoaderFactory(url.mojom.Url url,
-                            network.mojom.URLLoaderFactory& factory);
+  ResolveAsURLLoaderFactory(
+      url.mojom.Url url,
+      pending_receiver<network.mojom.URLLoaderFactory> factory);
 
   // Resolves a public Blob URL into a BlobURLToken. The BlobURLToken can be
   // used by the browser process to securely look up the blob a URL used to
diff --git a/third_party/blink/public/mojom/installedapp/OWNERS b/third_party/blink/public/mojom/installedapp/OWNERS
index 6137d699..124a0b41 100644
--- a/third_party/blink/public/mojom/installedapp/OWNERS
+++ b/third_party/blink/public/mojom/installedapp/OWNERS
@@ -1,4 +1,5 @@
-mgiuca@chromium.org
+peter@chromium.org
+rayankans@chromium.org
 
 per-file *.mojom=set noparent
 per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/third_party/blink/public/platform/modules/notifications/OWNERS b/third_party/blink/public/platform/modules/notifications/OWNERS
deleted file mode 100644
index 2fd0e4b..0000000
--- a/third_party/blink/public/platform/modules/notifications/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-peter@chromium.org
-
-# TEAM: platform-capabilities@chromium.org
-# COMPONENT: UI>Notifications
diff --git a/third_party/blink/public/platform/modules/notifications/web_notification_constants.h b/third_party/blink/public/platform/modules/notifications/web_notification_constants.h
deleted file mode 100644
index 7c7c137..0000000
--- a/third_party/blink/public/platform/modules/notifications/web_notification_constants.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_NOTIFICATIONS_WEB_NOTIFICATION_CONSTANTS_H_
-#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_NOTIFICATIONS_WEB_NOTIFICATION_CONSTANTS_H_
-
-namespace blink {
-
-// TODO(johnme): The maximum number of actions is platform-specific and should
-// be indicated by the embedder.
-
-// Maximum number of actions on a Platform Notification.
-static constexpr size_t kWebNotificationMaxActions = 2;
-
-// TODO(mvanouwerkerk): Update the notification resource loader to get the
-// appropriate image sizes from the embedder.
-
-// The maximum reasonable image size, scaled from dip units to pixels using the
-// largest supported scaling factor. TODO(johnme): Check sizes are correct.
-static constexpr int kWebNotificationMaxImageWidthPx = 1800;  // 450 dip * 4
-static constexpr int kWebNotificationMaxImageHeightPx = 900;  // 225 dip * 4
-
-// The maximum reasonable notification icon size, scaled from dip units to
-// pixels using the largest supported scaling factor.
-static constexpr int kWebNotificationMaxIconSizePx = 320;  // 80 dip * 4
-
-// The maximum reasonable badge size, scaled from dip units to pixels using the
-// largest supported scaling factor.
-static constexpr int kWebNotificationMaxBadgeSizePx = 96;  // 24 dip * 4
-
-// The maximum reasonable action icon size, scaled from dip units to
-// pixels using the largest supported scaling factor.
-static constexpr int kWebNotificationMaxActionIconSizePx = 128;  // 32 dip * 4
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_NOTIFICATIONS_WEB_NOTIFICATION_CONSTANTS_H_
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h
index 52a4be1..2430904 100644
--- a/third_party/blink/public/platform/platform.h
+++ b/third_party/blink/public/platform/platform.h
@@ -125,7 +125,6 @@
 class WebMediaCapabilitiesClient;
 class WebPrescientNetworking;
 class WebPublicSuffixList;
-class WebRTCCertificateGenerator;
 class WebRTCPeerConnectionHandler;
 class WebRTCPeerConnectionHandlerClient;
 class WebSandboxSupport;
@@ -575,11 +574,6 @@
   CreateRTCPeerConnectionHandler(WebRTCPeerConnectionHandlerClient*,
                                  scoped_refptr<base::SingleThreadTaskRunner>);
 
-  // May return null if WebRTC functionality is not available or out of
-  // resources.
-  virtual std::unique_ptr<WebRTCCertificateGenerator>
-  CreateRTCCertificateGenerator();
-
   // Returns the SingleThreadTaskRunner suitable for running WebRTC networking.
   // An rtc::Thread will have already been created.
   // May return null if WebRTC functionality is not implemented.
diff --git a/third_party/blink/public/platform/web_rtc_certificate_generator.h b/third_party/blink/public/platform/web_rtc_certificate_generator.h
deleted file mode 100644
index 198f4b1c..0000000
--- a/third_party/blink/public/platform/web_rtc_certificate_generator.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2015 Google 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:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_RTC_CERTIFICATE_GENERATOR_H_
-#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_RTC_CERTIFICATE_GENERATOR_H_
-
-#include <memory>
-
-#include "third_party/blink/public/platform/web_rtc_key_params.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/webrtc/api/peer_connection_interface.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace blink {
-
-using WebRTCCertificateCallback =
-    base::OnceCallback<void(rtc::scoped_refptr<rtc::RTCCertificate>)>;
-
-// Interface defining a class that can generate WebRTCCertificates
-// asynchronously.
-class WebRTCCertificateGenerator {
- public:
-  virtual ~WebRTCCertificateGenerator() = default;
-
-  // Start generating a certificate asynchronously. |observer| is invoked on the
-  // same thread that called generateCertificate when the operation is
-  // completed.
-  virtual void GenerateCertificate(
-      const WebRTCKeyParams&,
-      WebRTCCertificateCallback completion_callback,
-      scoped_refptr<base::SingleThreadTaskRunner>) = 0;
-  virtual void GenerateCertificateWithExpiration(
-      const WebRTCKeyParams&,
-      uint64_t expires_ms,
-      WebRTCCertificateCallback completion_callback,
-      scoped_refptr<base::SingleThreadTaskRunner>) = 0;
-
-  // Determines if the parameters are supported by |GenerateCertificate|.
-  // For example, if the number of bits of some parameter is too small or too
-  // large we may want to reject it for security or performance reasons.
-  virtual bool IsSupportedKeyParams(const WebRTCKeyParams&) = 0;
-
-  // Creates a certificate from the PEM strings. See also
-  // |rtc::RTCCertificate::ToPEM|.
-  virtual rtc::scoped_refptr<rtc::RTCCertificate> FromPEM(
-      blink::WebString pem_private_key,
-      blink::WebString pem_certificate) = 0;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_RTC_CERTIFICATE_GENERATOR_H_
diff --git a/third_party/blink/public/platform/web_url_response.h b/third_party/blink/public/platform/web_url_response.h
index 27e04af..0c0e3683 100644
--- a/third_party/blink/public/platform/web_url_response.h
+++ b/third_party/blink/public/platform/web_url_response.h
@@ -235,6 +235,7 @@
 
   // Flag whether this request was loaded via the SPDY protocol or not.
   // SPDY is an experimental web protocol, see http://dev.chromium.org/spdy
+  BLINK_PLATFORM_EXPORT bool WasFetchedViaSPDY() const;
   BLINK_PLATFORM_EXPORT void SetWasFetchedViaSPDY(bool);
 
   // Flag whether this request was loaded via a ServiceWorker. See
@@ -280,9 +281,15 @@
   BLINK_PLATFORM_EXPORT void SetRemotePort(uint16_t);
 
   // ALPN negotiated protocol of the socket which fetched this resource.
+  BLINK_PLATFORM_EXPORT bool WasAlpnNegotiated() const;
+  BLINK_PLATFORM_EXPORT void SetWasAlpnNegotiated(bool);
   BLINK_PLATFORM_EXPORT WebString AlpnNegotiatedProtocol() const;
   BLINK_PLATFORM_EXPORT void SetAlpnNegotiatedProtocol(const WebString&);
 
+  // Whether the response could use alternate protocol.
+  BLINK_PLATFORM_EXPORT bool WasAlternateProtocolAvailable() const;
+  BLINK_PLATFORM_EXPORT void SetWasAlternateProtocolAvailable(bool);
+
   // Information about the type of connection used to fetch this resource.
   BLINK_PLATFORM_EXPORT net::HttpResponseInfo::ConnectionInfo ConnectionInfo()
       const;
diff --git a/third_party/blink/public/web/modules/peerconnection/DEPS b/third_party/blink/public/web/modules/peerconnection/DEPS
index 1db93ebc..8e186078 100644
--- a/third_party/blink/public/web/modules/peerconnection/DEPS
+++ b/third_party/blink/public/web/modules/peerconnection/DEPS
@@ -1,9 +1,11 @@
 include_rules = [
+    "+base/memory/weak_ptr.h",
     # TODO(crbug.com/787254): Remove the use of base::MessageLoopCurrent.
     "+base/message_loop/message_loop_current.h",
 
     # TODO(crbug.com/787254): Replace base::SequenceChecker by base::ThreadChecker.
     "+base/sequence_checker.h",
     "+base/single_thread_task_runner.h",
+    "+base/synchronization/waitable_event.h",
     "+base/threading/thread.h",
 ]
diff --git a/third_party/blink/public/web/modules/peerconnection/media_stream_remote_video_source.h b/third_party/blink/public/web/modules/peerconnection/media_stream_remote_video_source.h
index b9085cf..a0ee73b 100644
--- a/third_party/blink/public/web/modules/peerconnection/media_stream_remote_video_source.h
+++ b/third_party/blink/public/web/modules/peerconnection/media_stream_remote_video_source.h
@@ -23,7 +23,7 @@
 // source is a local source and a video track where the source is a remote video
 // track.
 //
-// TODO(crbug.com/704136): Move the classes below out of the Blink exposed
+// TODO(crbug.com/787254): Move the classes below out of the Blink exposed
 // API when all users of it have been Onion souped.
 class BLINK_MODULES_EXPORT MediaStreamRemoteVideoSource
     : public MediaStreamVideoSource {
diff --git a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h b/third_party/blink/public/web/modules/peerconnection/media_stream_video_webrtc_sink.h
similarity index 71%
rename from content/renderer/media/webrtc/media_stream_video_webrtc_sink.h
rename to third_party/blink/public/web/modules/peerconnection/media_stream_video_webrtc_sink.h
index a0f560ad..019e8fd 100644
--- a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.h
+++ b/third_party/blink/public/web/modules/peerconnection/media_stream_video_webrtc_sink.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 CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_TRACK_ADAPTER_H_
-#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_TRACK_ADAPTER_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_PEERCONNECTION_MEDIA_STREAM_VIDEO_WEBRTC_SINK_H_
+#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_PEERCONNECTION_MEDIA_STREAM_VIDEO_WEBRTC_SINK_H_
 
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/threading/thread_checker.h"
-#include "content/common/content_export.h"
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
 #include "third_party/blink/public/web/modules/mediastream/media_stream_video_sink.h"
 #include "third_party/webrtc/api/media_stream_interface.h"
@@ -21,12 +21,9 @@
 class MediaStreamVideoTrack;
 class PeerConnectionDependencyFactory;
 class WebRtcVideoTrackSource;
-}
-
-namespace content {
 
 // MediaStreamVideoWebRtcSink is an adapter between a
-// blink::MediaStreamVideoTrack object and a webrtc VideoTrack that is
+// MediaStreamVideoTrack object and a webrtc VideoTrack that is
 // currently sent on a PeerConnection.
 // The responsibility of the class is to create and own a representation of a
 // webrtc VideoTrack that can be added and removed from a RTCPeerConnection. An
@@ -34,12 +31,15 @@
 // to an RTCPeerConnection object.
 // Instances of this class is owned by the WebRtcMediaStreamAdapter object that
 // created it.
-class CONTENT_EXPORT MediaStreamVideoWebRtcSink
-    : public blink::MediaStreamVideoSink {
+//
+// TODO(crbug.com/787254): Move the classes below out of the Blink exposed
+// API when all users of it have been Onion souped.
+class BLINK_MODULES_EXPORT MediaStreamVideoWebRtcSink
+    : public MediaStreamVideoSink {
  public:
   MediaStreamVideoWebRtcSink(
-      const blink::WebMediaStreamTrack& track,
-      blink::PeerConnectionDependencyFactory* factory,
+      const WebMediaStreamTrack& track,
+      PeerConnectionDependencyFactory* factory,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
   ~MediaStreamVideoWebRtcSink() override;
 
@@ -53,7 +53,7 @@
   // Implementation of MediaStreamSink.
   void OnEnabledChanged(bool enabled) override;
   void OnContentHintChanged(
-      blink::WebMediaStreamTrack::ContentHintType content_hint) override;
+      WebMediaStreamTrack::ContentHintType content_hint) override;
 
  private:
   // Helper to request a refresh frame from the source. Called via the callback
@@ -61,12 +61,12 @@
   void RequestRefreshFrame();
 
   // Used to DCHECK that we are called on the correct thread.
-  base::ThreadChecker thread_checker_;
+  THREAD_CHECKER(thread_checker_);
 
   // |video_source_| and |video_source_proxy_| are held as
   // references to outlive |video_track_| since the interfaces between them
   // don't use reference counting.
-  scoped_refptr<blink::WebRtcVideoTrackSource> video_source_;
+  scoped_refptr<WebRtcVideoTrackSource> video_source_;
   scoped_refptr<webrtc::VideoTrackSourceInterface> video_source_proxy_;
   scoped_refptr<webrtc::VideoTrackInterface> video_track_;
 
@@ -76,11 +76,14 @@
   // Provides WebRtcVideoSourceAdapter a weak reference to
   // MediaStreamVideoWebRtcSink in order to allow it to request refresh frames.
   // See comments in media_stream_video_webrtc_sink.cc.
+  //
+  // TODO(crbug.com/787254): Make this object Oilpan-able, and get
+  // rid of this weak prt factory use.
   base::WeakPtrFactory<MediaStreamVideoWebRtcSink> weak_factory_{this};
 
   DISALLOW_COPY_AND_ASSIGN(MediaStreamVideoWebRtcSink);
 };
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_VIDEO_TRACK_ADAPTER_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_PEERCONNECTION_MEDIA_STREAM_VIDEO_WEBRTC_SINK_H_
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h b/third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter.h
similarity index 87%
rename from content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h
rename to third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter.h
index badb679..21cc8af7e 100644
--- a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h
+++ b/third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter.h
@@ -2,28 +2,24 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_H_
-#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_H_
+#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_PEERCONNECTION_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_H_
+#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_PEERCONNECTION_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_H_
 
 #include <memory>
 
 #include "base/memory/ref_counted.h"
 #include "base/synchronization/waitable_event.h"
-#include "content/common/content_export.h"
-#include "content/renderer/media/webrtc/media_stream_video_webrtc_sink.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h"
 #include "third_party/blink/public/platform/modules/peerconnection/webrtc_audio_sink.h"
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_media_stream.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
 #include "third_party/blink/public/web/modules/mediastream/remote_media_stream_track_adapter.h"
+#include "third_party/blink/public/web/modules/peerconnection/media_stream_video_webrtc_sink.h"
 #include "third_party/webrtc/api/media_stream_interface.h"
 
 namespace blink {
+
 class PeerConnectionDependencyFactory;
-}
-
-namespace content {
-
 struct WebRtcMediaStreamTrackAdapterTraits;
 
 // This is a mapping between a webrtc and blink media stream track. It takes
@@ -32,7 +28,10 @@
 // There are different sinks/adapters used whether the track is local or remote
 // and whether it is an audio or video track; this adapter hides that fact and
 // lets you use a single class for any type of track.
-class CONTENT_EXPORT WebRtcMediaStreamTrackAdapter
+//
+// TODO(crbug.com/787254): Move the classes below out of the Blink exposed
+// API when all users of it have been Onion souped.
+class BLINK_MODULES_EXPORT WebRtcMediaStreamTrackAdapter
     : public base::RefCountedThreadSafe<WebRtcMediaStreamTrackAdapter,
                                         WebRtcMediaStreamTrackAdapterTraits> {
  public:
@@ -70,7 +69,7 @@
   blink::WebRtcAudioSink* GetLocalTrackAudioSinkForTesting() {
     return local_track_audio_sink_.get();
   }
-  MediaStreamVideoWebRtcSink* GetLocalTrackVideoSinkForTesting() {
+  blink::MediaStreamVideoWebRtcSink* GetLocalTrackVideoSinkForTesting() {
     return local_track_video_sink_.get();
   }
   blink::RemoteAudioTrackAdapter* GetRemoteAudioTrackAdapterForTesting() {
@@ -130,7 +129,7 @@
   // If the track is local, a sink is added to the local webrtc track that is
   // owned by us.
   std::unique_ptr<blink::WebRtcAudioSink> local_track_audio_sink_;
-  std::unique_ptr<MediaStreamVideoWebRtcSink> local_track_video_sink_;
+  std::unique_ptr<blink::MediaStreamVideoWebRtcSink> local_track_video_sink_;
   // If the track is remote, an adapter is used that listens to notifications on
   // the remote webrtc track and notifies Blink.
   scoped_refptr<blink::RemoteAudioTrackAdapter> remote_audio_track_adapter_;
@@ -139,7 +138,7 @@
   DISALLOW_COPY_AND_ASSIGN(WebRtcMediaStreamTrackAdapter);
 };
 
-struct CONTENT_EXPORT WebRtcMediaStreamTrackAdapterTraits {
+struct BLINK_MODULES_EXPORT WebRtcMediaStreamTrackAdapterTraits {
  private:
   friend class base::RefCountedThreadSafe<WebRtcMediaStreamTrackAdapter,
                                           WebRtcMediaStreamTrackAdapterTraits>;
@@ -149,6 +148,6 @@
   static void Destruct(const WebRtcMediaStreamTrackAdapter* adapter);
 };
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_PEERCONNECTION_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_H_
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h b/third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h
similarity index 80%
rename from content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h
rename to third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h
index 2c25e103..edcb224b 100644
--- a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h
+++ b/third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h
@@ -2,37 +2,37 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_MAP_H_
-#define CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_MAP_H_
-
-#include <map>
-#include <string>
+#ifndef THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_PEERCONNECTION_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_MAP_H_
+#define THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_PEERCONNECTION_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_MAP_H_
 
 #include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
-#include "content/common/content_export.h"
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h"
 #include "third_party/blink/public/platform/modules/peerconnection/two_keys_adapter_map.h"
+#include "third_party/blink/public/platform/web_common.h"
 #include "third_party/blink/public/platform/web_media_stream_track.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter.h"
 #include "third_party/webrtc/api/media_stream_interface.h"
 
+namespace base {
+class SingleThreadTaskRunner;
+}
+
 namespace blink {
 class PeerConnectionDependencyFactory;
-}
-
-namespace content {
 
 // A map and owner of |WebRtcMediaStreamTrackAdapter|s. It takes care of
 // creating, initializing and disposing track adapters independently of media
 // streams. Adapters are accessed via |AdapterRef|s, when all references to an
 // adapter are destroyed it is disposed and removed from the map.
-class CONTENT_EXPORT WebRtcMediaStreamTrackAdapterMap
+//
+// TODO(crbug.com/787254): Move the class below out of the Blink exposed
+// API when all users of it have been Onion souped.
+class BLINK_MODULES_EXPORT WebRtcMediaStreamTrackAdapterMap
     : public base::RefCountedThreadSafe<WebRtcMediaStreamTrackAdapterMap> {
  public:
   // Acts as an accessor to adapter members without leaking a reference to the
   // adapter. When the last |AdapterRef| is destroyed, the corresponding adapter
   // is |Dispose|d and removed from the map.
-  class CONTENT_EXPORT AdapterRef {
+  class BLINK_MODULES_EXPORT AdapterRef {
    public:
     // Must be invoked on the main thread. If this was the last reference to the
     // adapter it will be disposed and removed from the map.
@@ -50,7 +50,7 @@
 
     // Warning: Holding an external reference to the adapter will prevent
     // |~AdapterRef| from disposing the adapter.
-    WebRtcMediaStreamTrackAdapter* GetAdapterForTesting() const {
+    blink::WebRtcMediaStreamTrackAdapter* GetAdapterForTesting() const {
       return adapter_.get();
     }
 
@@ -62,14 +62,14 @@
     // Assumes map's |lock_| is held.
     AdapterRef(scoped_refptr<WebRtcMediaStreamTrackAdapterMap> map,
                Type type,
-               scoped_refptr<WebRtcMediaStreamTrackAdapter> adapter);
+               scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> adapter);
 
     scoped_refptr<WebRtcMediaStreamTrackAdapterMap> map_;
     Type type_;
     // A reference to the entry's adapter, ensures that |HasOneRef()| is false
     // as long as the |AdapterRef| is kept alive (the map entry has one
     // reference to it too).
-    scoped_refptr<WebRtcMediaStreamTrackAdapter> adapter_;
+    scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> adapter_;
   };
 
   // Must be invoked on the main thread.
@@ -128,14 +128,14 @@
   // |webrtc::MediaStreamTrackInterface|s.
   // The adapter keeps the |webrtc::MediaStreamTrackInterface| alive with ref
   // counting making it safe to use a raw pointer for key.
-  using LocalTrackAdapterMap =
-      blink::TwoKeysAdapterMap<int,  // blink::WebMediaStreamTrack::UniqueId()
-                               webrtc::MediaStreamTrackInterface*,
-                               scoped_refptr<WebRtcMediaStreamTrackAdapter>>;
-  using RemoteTrackAdapterMap =
-      blink::TwoKeysAdapterMap<webrtc::MediaStreamTrackInterface*,
-                               int,  // blink::WebMediaStreamTrack::UniqueId()
-                               scoped_refptr<WebRtcMediaStreamTrackAdapter>>;
+  using LocalTrackAdapterMap = blink::TwoKeysAdapterMap<
+      int,  // blink::WebMediaStreamTrack::UniqueId()
+      webrtc::MediaStreamTrackInterface*,
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>>;
+  using RemoteTrackAdapterMap = blink::TwoKeysAdapterMap<
+      webrtc::MediaStreamTrackInterface*,
+      int,  // blink::WebMediaStreamTrack::UniqueId()
+      scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>>;
 
   // Invoke on the main thread.
   virtual ~WebRtcMediaStreamTrackAdapterMap();
@@ -150,6 +150,6 @@
   RemoteTrackAdapterMap remote_track_adapters_;
 };
 
-}  // namespace content
+}  // namespace blink
 
-#endif  // CONTENT_RENDERER_MEDIA_WEBRTC_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_MAP_H_
+#endif  // THIRD_PARTY_BLINK_PUBLIC_WEB_MODULES_PEERCONNECTION_WEBRTC_MEDIA_STREAM_TRACK_ADAPTER_MAP_H_
diff --git a/third_party/blink/public/web/web_navigation_params.h b/third_party/blink/public/web/web_navigation_params.h
index 8f25352..39df65d8c 100644
--- a/third_party/blink/public/web/web_navigation_params.h
+++ b/third_party/blink/public/web/web_navigation_params.h
@@ -282,6 +282,9 @@
   WebHistoryItem history_item;
   // Whether this navigation is a result of client redirect.
   bool is_client_redirect = false;
+  // Cache mode to be used for subresources, instead of the one determined
+  // by |frame_load_type|.
+  base::Optional<blink::mojom::FetchCacheMode> force_fetch_cache_mode;
 
   // Miscellaneous parameters.
 
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
index f4f489e..cf6f28c8 100644
--- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
+++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc
@@ -8,13 +8,13 @@
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/web_crypto.h"
 #include "third_party/blink/public/platform/web_crypto_key_algorithm.h"
-#include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
 #include "third_party/blink/renderer/bindings/modules/v8/serialization/web_crypto_sub_tags.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/modules/crypto/crypto_key.h"
 #include "third_party/blink/renderer/modules/filesystem/dom_file_system.h"
 #include "third_party/blink/renderer/modules/imagecapture/point_2d.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h"
 #include "third_party/blink/renderer/modules/shapedetection/detected_barcode.h"
 #include "third_party/blink/renderer/modules/shapedetection/detected_face.h"
 #include "third_party/blink/renderer/modules/shapedetection/detected_text.h"
@@ -53,8 +53,8 @@
       if (!ReadUTF8String(&pem_private_key) ||
           !ReadUTF8String(&pem_certificate))
         return nullptr;
-      std::unique_ptr<WebRTCCertificateGenerator> certificate_generator(
-          Platform::Current()->CreateRTCCertificateGenerator());
+      std::unique_ptr<RTCCertificateGenerator> certificate_generator =
+          std::make_unique<RTCCertificateGenerator>();
       if (!certificate_generator)
         return nullptr;
       rtc::scoped_refptr<rtc::RTCCertificate> certificate =
diff --git a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
index 58e9887..c6fa496e7 100644
--- a/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
+++ b/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules_test.cc
@@ -7,10 +7,10 @@
 #include "build/build_config.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
 #include "third_party/blink/public/platform/web_crypto_algorithm_params.h"
-#include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_function.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
 #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h"
@@ -30,6 +30,7 @@
 #include "third_party/blink/renderer/modules/filesystem/dom_file_system.h"
 #include "third_party/blink/renderer/modules/imagecapture/point_2d.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h"
 #include "third_party/blink/renderer/modules/shapedetection/landmark.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
@@ -155,8 +156,8 @@
 
 TEST(V8ScriptValueSerializerForModulesTest, RoundTripRTCCertificate) {
   // If WebRTC is not supported in this build, this test is meaningless.
-  std::unique_ptr<WebRTCCertificateGenerator> certificate_generator(
-      Platform::Current()->CreateRTCCertificateGenerator());
+  std::unique_ptr<RTCCertificateGenerator> certificate_generator =
+      std::make_unique<RTCCertificateGenerator>();
   if (!certificate_generator)
     return;
 
@@ -185,8 +186,8 @@
 
 TEST(V8ScriptValueSerializerForModulesTest, DecodeRTCCertificate) {
   // If WebRTC is not supported in this build, this test is meaningless.
-  std::unique_ptr<WebRTCCertificateGenerator> certificate_generator(
-      Platform::Current()->CreateRTCCertificateGenerator());
+  std::unique_ptr<RTCCertificateGenerator> certificate_generator =
+      std::make_unique<RTCCertificateGenerator>();
   if (!certificate_generator)
     return;
 
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index 02aebb6..4924191 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -2104,9 +2104,8 @@
     },
     {
       name: "list-style-type",
-      property_methods: ["CSSValueFromComputedStyleInternal"],
+      property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
       inherited: true,
-      field_template: "keyword",
       keywords: [
         "disc", "circle", "square", "decimal", "decimal-leading-zero",
         "arabic-indic", "bengali", "cambodian", "khmer", "devanagari",
@@ -2122,7 +2121,7 @@
         "simp-chinese-informal", "trad-chinese-formal", "trad-chinese-informal",
         "hiragana", "katakana", "hiragana-iroha", "katakana-iroha", "none"
       ],
-      default_value: "disc",
+      style_builder_custom_functions: ["initial", "inherit", "value"],
     },
     {
       name: "margin-bottom",
diff --git a/third_party/blink/renderer/core/css/css_selector.cc b/third_party/blink/renderer/core/css/css_selector.cc
index bad20600..66db83f 100644
--- a/third_party/blink/renderer/core/css/css_selector.cc
+++ b/third_party/blink/renderer/core/css/css_selector.cc
@@ -278,6 +278,7 @@
     case kPseudoHost:
     case kPseudoHostContext:
     case kPseudoPart:
+    case kPseudoState:
     case kPseudoShadow:
     case kPseudoFullScreen:
     case kPseudoFullScreenAncestor:
@@ -418,6 +419,7 @@
     {"nth-of-type", CSSSelector::kPseudoNthOfType},
     {"part", CSSSelector::kPseudoPart},
     {"slotted", CSSSelector::kPseudoSlotted},
+    {"state", CSSSelector::kPseudoState},
     {"where", CSSSelector::kPseudoWhere},
 };
 
@@ -459,6 +461,11 @@
       !RuntimeEnabledFeatures::CSSPictureInPictureEnabled())
     return CSSSelector::kPseudoUnknown;
 
+  if (match->type == CSSSelector::kPseudoState &&
+      !RuntimeEnabledFeatures::CustomStatePseudoClassEnabled()) {
+    return CSSSelector::kPseudoUnknown;
+  }
+
   return static_cast<CSSSelector::PseudoType>(match->type);
 }
 
@@ -649,6 +656,7 @@
     case kPseudoScope:
     case kPseudoSingleButton:
     case kPseudoStart:
+    case kPseudoState:
     case kPseudoTarget:
     case kPseudoUnknown:
     case kPseudoValid:
@@ -768,6 +776,7 @@
           break;
         }
         case kPseudoLang:
+        case kPseudoState:
           builder.Append('(');
           builder.Append(simple_selector->Argument());
           builder.Append(')');
diff --git a/third_party/blink/renderer/core/css/css_selector.h b/third_party/blink/renderer/core/css/css_selector.h
index 2c4492b..e6b6661 100644
--- a/third_party/blink/renderer/core/css/css_selector.h
+++ b/third_party/blink/renderer/core/css/css_selector.h
@@ -160,6 +160,7 @@
     kPseudoNthLastChild,
     kPseudoNthLastOfType,
     kPseudoPart,
+    kPseudoState,
     kPseudoLink,
     kPseudoVisited,
     kPseudoAny,
diff --git a/third_party/blink/renderer/core/css/css_value_id_mappings.h b/third_party/blink/renderer/core/css/css_value_id_mappings.h
index ffa22b63c..c6490c8 100644
--- a/third_party/blink/renderer/core/css/css_value_id_mappings.h
+++ b/third_party/blink/renderer/core/css/css_value_id_mappings.h
@@ -174,6 +174,130 @@
 }
 
 template <>
+inline EListStyleType CssValueIDToPlatformEnum(CSSValueID v) {
+  switch (v) {
+    case CSSValueID::kDisc:
+      return EListStyleType::kDisc;
+    case CSSValueID::kCircle:
+      return EListStyleType::kCircle;
+    case CSSValueID::kSquare:
+      return EListStyleType::kSquare;
+    case CSSValueID::kDecimal:
+      return EListStyleType::kDecimal;
+    case CSSValueID::kDecimalLeadingZero:
+      return EListStyleType::kDecimalLeadingZero;
+    case CSSValueID::kArabicIndic:
+      return EListStyleType::kArabicIndic;
+    case CSSValueID::kBengali:
+      return EListStyleType::kBengali;
+    case CSSValueID::kCambodian:
+      return EListStyleType::kCambodian;
+    case CSSValueID::kKhmer:
+      return EListStyleType::kKhmer;
+    case CSSValueID::kDevanagari:
+      return EListStyleType::kDevanagari;
+    case CSSValueID::kGujarati:
+      return EListStyleType::kGujarati;
+    case CSSValueID::kGurmukhi:
+      return EListStyleType::kGurmukhi;
+    case CSSValueID::kKannada:
+      return EListStyleType::kKannada;
+    case CSSValueID::kLao:
+      return EListStyleType::kLao;
+    case CSSValueID::kMalayalam:
+      return EListStyleType::kMalayalam;
+    case CSSValueID::kMongolian:
+      return EListStyleType::kMongolian;
+    case CSSValueID::kMyanmar:
+      return EListStyleType::kMyanmar;
+    case CSSValueID::kOriya:
+      return EListStyleType::kOriya;
+    case CSSValueID::kPersian:
+      return EListStyleType::kPersian;
+    case CSSValueID::kUrdu:
+      return EListStyleType::kUrdu;
+    case CSSValueID::kTelugu:
+      return EListStyleType::kTelugu;
+    case CSSValueID::kTibetan:
+      return EListStyleType::kTibetan;
+    case CSSValueID::kThai:
+      return EListStyleType::kThai;
+    case CSSValueID::kLowerRoman:
+      return EListStyleType::kLowerRoman;
+    case CSSValueID::kUpperRoman:
+      return EListStyleType::kUpperRoman;
+    case CSSValueID::kLowerGreek:
+      return EListStyleType::kLowerGreek;
+    case CSSValueID::kLowerAlpha:
+      return EListStyleType::kLowerAlpha;
+    case CSSValueID::kLowerLatin:
+      return EListStyleType::kLowerLatin;
+    case CSSValueID::kUpperAlpha:
+      return EListStyleType::kUpperAlpha;
+    case CSSValueID::kUpperLatin:
+      return EListStyleType::kUpperLatin;
+    case CSSValueID::kCjkEarthlyBranch:
+      return EListStyleType::kCjkEarthlyBranch;
+    case CSSValueID::kCjkHeavenlyStem:
+      return EListStyleType::kCjkHeavenlyStem;
+    case CSSValueID::kEthiopicHalehame:
+      return EListStyleType::kEthiopicHalehame;
+    case CSSValueID::kEthiopicHalehameAm:
+      return EListStyleType::kEthiopicHalehameAm;
+    case CSSValueID::kEthiopicHalehameTiEr:
+      return EListStyleType::kEthiopicHalehameTiEr;
+    case CSSValueID::kEthiopicHalehameTiEt:
+      return EListStyleType::kEthiopicHalehameTiEt;
+    case CSSValueID::kHangul:
+      return EListStyleType::kHangul;
+    case CSSValueID::kHangulConsonant:
+      return EListStyleType::kHangulConsonant;
+    case CSSValueID::kKoreanHangulFormal:
+      return EListStyleType::kKoreanHangulFormal;
+    case CSSValueID::kKoreanHanjaFormal:
+      return EListStyleType::kKoreanHanjaFormal;
+    case CSSValueID::kKoreanHanjaInformal:
+      return EListStyleType::kKoreanHanjaInformal;
+    case CSSValueID::kHebrew:
+      return EListStyleType::kHebrew;
+    case CSSValueID::kArmenian:
+      return EListStyleType::kArmenian;
+    case CSSValueID::kLowerArmenian:
+      return EListStyleType::kLowerArmenian;
+    case CSSValueID::kUpperArmenian:
+      return EListStyleType::kUpperArmenian;
+    case CSSValueID::kGeorgian:
+      return EListStyleType::kGeorgian;
+    case CSSValueID::kCjkIdeographic:
+      return EListStyleType::kCjkIdeographic;
+    case CSSValueID::kSimpChineseFormal:
+      return EListStyleType::kSimpChineseFormal;
+    case CSSValueID::kSimpChineseInformal:
+      return EListStyleType::kSimpChineseInformal;
+    case CSSValueID::kTradChineseFormal:
+      return EListStyleType::kTradChineseFormal;
+    case CSSValueID::kTradChineseInformal:
+      return EListStyleType::kTradChineseInformal;
+    case CSSValueID::kHiragana:
+      return EListStyleType::kHiragana;
+    case CSSValueID::kKatakana:
+      return EListStyleType::kKatakana;
+    case CSSValueID::kHiraganaIroha:
+      return EListStyleType::kHiraganaIroha;
+    case CSSValueID::kKatakanaIroha:
+      return EListStyleType::kKatakanaIroha;
+    case CSSValueID::kNone:
+      return EListStyleType::kNone;
+    default:
+      NOTREACHED();
+      break;
+  }
+
+  NOTREACHED();
+  return EListStyleType::kDisc;
+}
+
+template <>
 inline EUserSelect CssValueIDToPlatformEnum(CSSValueID v) {
   if (v == CSSValueID::kAuto)
     return EUserSelect::kAuto;
@@ -233,6 +357,130 @@
   return CSSValueID::kInline;
 }
 
+template <>
+inline CSSValueID PlatformEnumToCSSValueID(EListStyleType v) {
+  switch (v) {
+    case EListStyleType::kDisc:
+      return CSSValueID::kDisc;
+    case EListStyleType::kCircle:
+      return CSSValueID::kCircle;
+    case EListStyleType::kSquare:
+      return CSSValueID::kSquare;
+    case EListStyleType::kDecimal:
+      return CSSValueID::kDecimal;
+    case EListStyleType::kDecimalLeadingZero:
+      return CSSValueID::kDecimalLeadingZero;
+    case EListStyleType::kArabicIndic:
+      return CSSValueID::kArabicIndic;
+    case EListStyleType::kBengali:
+      return CSSValueID::kBengali;
+    case EListStyleType::kCambodian:
+      return CSSValueID::kCambodian;
+    case EListStyleType::kKhmer:
+      return CSSValueID::kKhmer;
+    case EListStyleType::kDevanagari:
+      return CSSValueID::kDevanagari;
+    case EListStyleType::kGujarati:
+      return CSSValueID::kGujarati;
+    case EListStyleType::kGurmukhi:
+      return CSSValueID::kGurmukhi;
+    case EListStyleType::kKannada:
+      return CSSValueID::kKannada;
+    case EListStyleType::kLao:
+      return CSSValueID::kLao;
+    case EListStyleType::kMalayalam:
+      return CSSValueID::kMalayalam;
+    case EListStyleType::kMongolian:
+      return CSSValueID::kMongolian;
+    case EListStyleType::kMyanmar:
+      return CSSValueID::kMyanmar;
+    case EListStyleType::kOriya:
+      return CSSValueID::kOriya;
+    case EListStyleType::kPersian:
+      return CSSValueID::kPersian;
+    case EListStyleType::kUrdu:
+      return CSSValueID::kUrdu;
+    case EListStyleType::kTelugu:
+      return CSSValueID::kTelugu;
+    case EListStyleType::kTibetan:
+      return CSSValueID::kTibetan;
+    case EListStyleType::kThai:
+      return CSSValueID::kThai;
+    case EListStyleType::kLowerRoman:
+      return CSSValueID::kLowerRoman;
+    case EListStyleType::kUpperRoman:
+      return CSSValueID::kUpperRoman;
+    case EListStyleType::kLowerGreek:
+      return CSSValueID::kLowerGreek;
+    case EListStyleType::kLowerAlpha:
+      return CSSValueID::kLowerAlpha;
+    case EListStyleType::kLowerLatin:
+      return CSSValueID::kLowerLatin;
+    case EListStyleType::kUpperAlpha:
+      return CSSValueID::kUpperAlpha;
+    case EListStyleType::kUpperLatin:
+      return CSSValueID::kUpperLatin;
+    case EListStyleType::kCjkEarthlyBranch:
+      return CSSValueID::kCjkEarthlyBranch;
+    case EListStyleType::kCjkHeavenlyStem:
+      return CSSValueID::kCjkHeavenlyStem;
+    case EListStyleType::kEthiopicHalehame:
+      return CSSValueID::kEthiopicHalehame;
+    case EListStyleType::kEthiopicHalehameAm:
+      return CSSValueID::kEthiopicHalehameAm;
+    case EListStyleType::kEthiopicHalehameTiEr:
+      return CSSValueID::kEthiopicHalehameTiEr;
+    case EListStyleType::kEthiopicHalehameTiEt:
+      return CSSValueID::kEthiopicHalehameTiEt;
+    case EListStyleType::kHangul:
+      return CSSValueID::kHangul;
+    case EListStyleType::kHangulConsonant:
+      return CSSValueID::kHangulConsonant;
+    case EListStyleType::kKoreanHangulFormal:
+      return CSSValueID::kKoreanHangulFormal;
+    case EListStyleType::kKoreanHanjaFormal:
+      return CSSValueID::kKoreanHanjaFormal;
+    case EListStyleType::kKoreanHanjaInformal:
+      return CSSValueID::kKoreanHanjaInformal;
+    case EListStyleType::kHebrew:
+      return CSSValueID::kHebrew;
+    case EListStyleType::kArmenian:
+      return CSSValueID::kArmenian;
+    case EListStyleType::kLowerArmenian:
+      return CSSValueID::kLowerArmenian;
+    case EListStyleType::kUpperArmenian:
+      return CSSValueID::kUpperArmenian;
+    case EListStyleType::kGeorgian:
+      return CSSValueID::kGeorgian;
+    case EListStyleType::kCjkIdeographic:
+      return CSSValueID::kCjkIdeographic;
+    case EListStyleType::kSimpChineseFormal:
+      return CSSValueID::kSimpChineseFormal;
+    case EListStyleType::kSimpChineseInformal:
+      return CSSValueID::kSimpChineseInformal;
+    case EListStyleType::kTradChineseFormal:
+      return CSSValueID::kTradChineseFormal;
+    case EListStyleType::kTradChineseInformal:
+      return CSSValueID::kTradChineseInformal;
+    case EListStyleType::kHiragana:
+      return CSSValueID::kHiragana;
+    case EListStyleType::kKatakana:
+      return CSSValueID::kKatakana;
+    case EListStyleType::kHiraganaIroha:
+      return CSSValueID::kHiraganaIroha;
+    case EListStyleType::kKatakanaIroha:
+      return CSSValueID::kKatakanaIroha;
+    case EListStyleType::kNone:
+      return CSSValueID::kNone;
+    case EListStyleType::kString:
+      NOTREACHED();
+      break;
+  }
+
+  NOTREACHED();
+  return CSSValueID::kDisc;
+}
+
 }  // namespace blink
 
 #endif
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc b/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc
index eecdcb0..63a966880 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc
+++ b/third_party/blink/renderer/core/css/parser/css_parser_fast_paths.cc
@@ -1095,6 +1095,7 @@
 bool CSSParserFastPaths::IsPartialKeywordPropertyID(CSSPropertyID property_id) {
   switch (property_id) {
     case CSSPropertyID::kDisplay:
+    case CSSPropertyID::kListStyleType:
       return true;
     default:
       return false;
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 3a5aec7..d2e0229 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
@@ -252,6 +252,8 @@
     case CSSSelector::kPseudoSelection:
       return pseudo_class == CSSSelector::kPseudoWindowInactive;
     case CSSSelector::kPseudoPart:
+      return IsUserActionPseudoClass(pseudo_class) ||
+             pseudo_class == CSSSelector::kPseudoState;
     case CSSSelector::kPseudoWebKitCustomElement:
     case CSSSelector::kPseudoBlinkInternalElement:
       return IsUserActionPseudoClass(pseudo_class);
@@ -599,6 +601,7 @@
       selector->AdoptSelectorVector(selector_vector);
       return selector;
     }
+    case CSSSelector::kPseudoState:
     case CSSSelector::kPseudoPart: {
       const CSSParserToken& ident = block.ConsumeIncludingWhitespace();
       if (ident.GetType() != kIdentToken || !block.AtEnd())
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 890be20d..c00a12c 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
@@ -3778,14 +3778,53 @@
   return CSSIdentifierValue::Create(style.ListStylePosition());
 }
 
+const CSSValue* ListStyleType::ParseSingleValue(
+    CSSParserTokenRange& range,
+    const CSSParserContext& context,
+    const CSSParserLocalContext&) const {
+  // NOTE: All the keyword values for the list-style-type property are handled
+  // by the CSSParserFastPaths.
+  return css_property_parser_helpers::ConsumeString(range);
+}
+
 const CSSValue* ListStyleType::CSSValueFromComputedStyleInternal(
     const ComputedStyle& style,
     const SVGComputedStyle&,
     const LayoutObject*,
     bool allow_visited_style) const {
+  if (style.ListStyleType() == EListStyleType::kString)
+    return MakeGarbageCollected<CSSStringValue>(style.ListStyleStringValue());
   return CSSIdentifierValue::Create(style.ListStyleType());
 }
 
+void ListStyleType::ApplyInitial(StyleResolverState& state) const {
+  state.Style()->SetListStyleType(
+      ComputedStyleInitialValues::InitialListStyleType());
+  state.Style()->SetListStyleStringValue(
+      ComputedStyleInitialValues::InitialListStyleStringValue());
+}
+
+void ListStyleType::ApplyInherit(StyleResolverState& state) const {
+  state.Style()->SetListStyleType(state.ParentStyle()->ListStyleType());
+  state.Style()->SetListStyleStringValue(
+      state.ParentStyle()->ListStyleStringValue());
+}
+
+void ListStyleType::ApplyValue(StyleResolverState& state,
+                               const CSSValue& value) const {
+  if (auto* identifier_value = DynamicTo<CSSIdentifierValue>(value)) {
+    state.Style()->SetListStyleType(
+        identifier_value->ConvertTo<EListStyleType>());
+    state.Style()->SetListStyleStringValue(
+        ComputedStyleInitialValues::InitialListStyleStringValue());
+    return;
+  }
+
+  state.Style()->SetListStyleType(EListStyleType::kString);
+  state.Style()->SetListStyleStringValue(
+      AtomicString(To<CSSStringValue>(value).Value()));
+}
+
 bool MarginBlockEnd::IsLayoutDependent(const ComputedStyle* style,
                                        LayoutObject* layout_object) const {
   return layout_object && layout_object->IsBox();
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 29365b5..4ec88a508 100644
--- a/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_adjuster.cc
@@ -566,7 +566,9 @@
     AdjustStyleForFirstLetter(style);
   }
 
-  if (element && RuntimeEnabledFeatures::DisplayLockingEnabled() &&
+  if (element &&
+      RuntimeEnabledFeatures::DisplayLockingEnabled(
+          element->GetExecutionContext()) &&
       element->hasAttribute(html_names::kRendersubtreeAttr)) {
     // The element has the rendersubtree attr, so we should add style and
     // layout containment. If the attribute contains "invisible" we should
diff --git a/third_party/blink/renderer/core/css/rule_feature_set.cc b/third_party/blink/renderer/core/css/rule_feature_set.cc
index 5139f78..38bd45b 100644
--- a/third_party/blink/renderer/core/css/rule_feature_set.cc
+++ b/third_party/blink/renderer/core/css/rule_feature_set.cc
@@ -89,6 +89,7 @@
     case CSSSelector::kPseudoNthLastChild:
     case CSSSelector::kPseudoNthLastOfType:
     case CSSSelector::kPseudoPart:
+    case CSSSelector::kPseudoState:
     case CSSSelector::kPseudoLink:
     case CSSSelector::kPseudoVisited:
     case CSSSelector::kPseudoAny:
@@ -534,6 +535,7 @@
       case CSSSelector::kPseudoRequired:
       case CSSSelector::kPseudoReadOnly:
       case CSSSelector::kPseudoReadWrite:
+      case CSSSelector::kPseudoState:
       case CSSSelector::kPseudoValid:
       case CSSSelector::kPseudoInvalid:
       case CSSSelector::kPseudoIndeterminate:
diff --git a/third_party/blink/renderer/core/css/selector_checker.cc b/third_party/blink/renderer/core/css/selector_checker.cc
index abd7049..64bc412 100644
--- a/third_party/blink/renderer/core/css/selector_checker.cc
+++ b/third_party/blink/renderer/core/css/selector_checker.cc
@@ -46,6 +46,7 @@
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/picture_in_picture_controller.h"
 #include "third_party/blink/renderer/core/fullscreen/fullscreen.h"
+#include "third_party/blink/renderer/core/html/custom/element_internals.h"
 #include "third_party/blink/renderer/core/html/forms/html_form_control_element.h"
 #include "third_party/blink/renderer/core/html/forms/html_input_element.h"
 #include "third_party/blink/renderer/core/html/forms/html_option_element.h"
@@ -1109,6 +1110,10 @@
       if (!context.has_selection_pseudo)
         return false;
       return !element.GetDocument().GetPage()->GetFocusController().IsActive();
+    case CSSSelector::kPseudoState: {
+      return element.DidAttachInternals() &&
+             element.EnsureElementInternals().HasState(selector.Argument());
+    }
     case CSSSelector::kPseudoHorizontal:
     case CSSSelector::kPseudoVertical:
     case CSSSelector::kPseudoDecrement:
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
index 47c69cb..763e9ea 100644
--- a/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
+++ b/third_party/blink/renderer/core/display_lock/display_lock_utilities.cc
@@ -32,7 +32,7 @@
 
 bool DisplayLockUtilities::ActivateFindInPageMatchRangeIfNeeded(
     const EphemeralRangeInFlatTree& range) {
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled())
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(&range.GetDocument()))
     return false;
   DCHECK(!range.IsNull());
   DCHECK(!range.IsCollapsed());
@@ -56,7 +56,7 @@
     const EphemeralRangeInFlatTree& range) {
   if (range.IsNull() || range.IsCollapsed())
     return false;
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled() ||
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(&range.GetDocument()) ||
       range.GetDocument().LockedDisplayLockCount() ==
           range.GetDocument().ActivationBlockingDisplayLockCount())
     return false;
@@ -79,7 +79,7 @@
     const EphemeralRangeInFlatTree& range) {
   if (range.IsNull() || range.IsCollapsed())
     return false;
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled() ||
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(&range.GetDocument()) ||
       range.GetDocument().LockedDisplayLockCount() ==
           range.GetDocument().ActivationBlockingDisplayLockCount())
     return false;
@@ -105,7 +105,8 @@
 DisplayLockUtilities::ActivatableLockedInclusiveAncestors(const Node& node) {
   HeapVector<Member<Element>> elements_to_activate;
   const_cast<Node*>(&node)->UpdateDistributionForFlatTreeTraversal();
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled() ||
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
+          node.GetExecutionContext()) ||
       node.GetDocument().LockedDisplayLockCount() ==
           node.GetDocument().ActivationBlockingDisplayLockCount())
     return elements_to_activate;
@@ -132,7 +133,8 @@
 DisplayLockUtilities::ScopedChainForcedUpdate::ScopedChainForcedUpdate(
     const Node* node,
     bool include_self) {
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled())
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
+          node->GetExecutionContext()))
     return;
 
   CreateParentFrameScopeIfNeeded(node);
@@ -188,8 +190,9 @@
   auto* element = DynamicTo<Element>(node);
   if (!element)
     return NearestLockedExclusiveAncestor(node);
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled() || !node.isConnected() ||
-      node.GetDocument().LockedDisplayLockCount() == 0 ||
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
+          node.GetExecutionContext()) ||
+      !node.isConnected() || node.GetDocument().LockedDisplayLockCount() == 0 ||
       !node.CanParticipateInFlatTree()) {
     return nullptr;
   }
@@ -207,8 +210,9 @@
 
 Element* DisplayLockUtilities::NearestLockedExclusiveAncestor(
     const Node& node) {
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled() || !node.isConnected() ||
-      node.GetDocument().LockedDisplayLockCount() == 0 ||
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
+          node.GetExecutionContext()) ||
+      !node.isConnected() || node.GetDocument().LockedDisplayLockCount() == 0 ||
       !node.CanParticipateInFlatTree()) {
     return nullptr;
   }
@@ -229,7 +233,8 @@
 
 Element* DisplayLockUtilities::HighestLockedInclusiveAncestor(
     const Node& node) {
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled() ||
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
+          node.GetExecutionContext()) ||
       node.GetDocument().LockedDisplayLockCount() == 0 ||
       !node.CanParticipateInFlatTree()) {
     return nullptr;
@@ -250,7 +255,8 @@
 
 Element* DisplayLockUtilities::HighestLockedExclusiveAncestor(
     const Node& node) {
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled() ||
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
+          node.GetExecutionContext()) ||
       node.GetDocument().LockedDisplayLockCount() == 0 ||
       !node.CanParticipateInFlatTree()) {
     return nullptr;
@@ -284,7 +290,8 @@
 }
 
 bool DisplayLockUtilities::IsInNonActivatableLockedSubtree(const Node& node) {
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled() ||
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
+          node.GetExecutionContext()) ||
       node.GetDocument().LockedDisplayLockCount() == 0 ||
       node.GetDocument().ActivationBlockingDisplayLockCount() == 0 ||
       !node.CanParticipateInFlatTree()) {
@@ -301,7 +308,8 @@
 
 bool DisplayLockUtilities::IsInLockedSubtreeCrossingFrames(
     const Node& source_node) {
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled())
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
+          source_node.GetExecutionContext()))
     return false;
   const Node* node = &source_node;
 
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 9587ce8..26a4f29 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -2669,7 +2669,9 @@
   Node* node = &root;
   while (node) {
     auto* element = DynamicTo<Element>(node);
-    if (element && RuntimeEnabledFeatures::DisplayLockingEnabled() &&
+    if (element &&
+        RuntimeEnabledFeatures::DisplayLockingEnabled(
+            root.GetExecutionContext()) &&
         element->StyleRecalcBlockedByDisplayLock(
             DisplayLockLifecycleTarget::kChildren)) {
       node = FlatTreeTraversal::NextSkippingChildren(*node);
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index c2b3aa06..8e391cf 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2352,7 +2352,8 @@
       GetElementData()->presentation_attribute_style_is_dirty_ = true;
       SetNeedsStyleRecalc(kLocalStyleChange,
                           StyleChangeReasonForTracing::FromAttribute(name));
-    } else if (RuntimeEnabledFeatures::DisplayLockingEnabled() &&
+    } else if (RuntimeEnabledFeatures::DisplayLockingEnabled(
+                   GetExecutionContext()) &&
                name == html_names::kRendersubtreeAttr &&
                params.old_value != params.new_value) {
       UseCounter::Count(GetDocument(), WebFeature::kRenderSubtreeAttribute);
@@ -4198,7 +4199,7 @@
 }
 
 bool Element::ActivateDisplayLockIfNeeded() {
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled() ||
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(GetExecutionContext()) ||
       GetDocument().LockedDisplayLockCount() ==
           GetDocument().ActivationBlockingDisplayLockCount())
     return false;
@@ -4233,7 +4234,7 @@
 }
 
 bool Element::DisplayLockPreventsActivation() const {
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled())
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(GetExecutionContext()))
     return false;
 
   if (GetDocument().ActivationBlockingDisplayLockCount() == 0)
@@ -4612,7 +4613,7 @@
 }
 
 DisplayLockContext* Element::GetDisplayLockContext() const {
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled())
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(GetExecutionContext()))
     return nullptr;
   return HasRareData() ? GetElementRareData()->GetDisplayLockContext()
                        : nullptr;
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc
index e5de4bb3..a4f6e78 100644
--- a/third_party/blink/renderer/core/dom/node.cc
+++ b/third_party/blink/renderer/core/dom/node.cc
@@ -1219,7 +1219,7 @@
       break;
     // If we reach a locked ancestor, we should abort since the ancestor marking
     // will be done when the lock is committed.
-    if (RuntimeEnabledFeatures::DisplayLockingEnabled()) {
+    if (RuntimeEnabledFeatures::DisplayLockingEnabled(GetExecutionContext())) {
       auto* ancestor_element = DynamicTo<Element>(ancestor);
       if (ancestor_element && ancestor_element->StyleRecalcBlockedByDisplayLock(
                                   DisplayLockLifecycleTarget::kChildren)) {
@@ -1238,7 +1238,7 @@
   // roots. These would be updated when we commit the lock. If we have locked
   // display locks somewhere in the document, we iterate up the ancestor chain
   // to check if we're in one such subtree.
-  if (RuntimeEnabledFeatures::DisplayLockingEnabled() &&
+  if (RuntimeEnabledFeatures::DisplayLockingEnabled(GetExecutionContext()) &&
       GetDocument().LockedDisplayLockCount() > 0) {
     for (auto* ancestor_copy = ancestor; ancestor_copy;
          ancestor_copy = ancestor_copy->GetStyleRecalcParent()) {
diff --git a/third_party/blink/renderer/core/editing/finder/find_buffer.cc b/third_party/blink/renderer/core/editing/finder/find_buffer.cc
index 3e78579..a0948ff 100644
--- a/third_party/blink/renderer/core/editing/finder/find_buffer.cc
+++ b/third_party/blink/renderer/core/editing/finder/find_buffer.cc
@@ -244,7 +244,8 @@
 void FindBuffer::CollectScopedForcedUpdates(Node& start_node,
                                             const Node* search_range_end_node,
                                             const Node* node_after_block) {
-  if (!RuntimeEnabledFeatures::DisplayLockingEnabled())
+  if (!RuntimeEnabledFeatures::DisplayLockingEnabled(
+          start_node.GetExecutionContext()))
     return;
   if (start_node.GetDocument().LockedDisplayLockCount() ==
       start_node.GetDocument().ActivationBlockingDisplayLockCount())
diff --git a/third_party/blink/renderer/core/editing/finder/text_finder.cc b/third_party/blink/renderer/core/editing/finder/text_finder.cc
index 4882a6c..a81b9b3 100644
--- a/third_party/blink/renderer/core/editing/finder/text_finder.cc
+++ b/third_party/blink/renderer/core/editing/finder/text_finder.cc
@@ -75,7 +75,8 @@
 static void ScrollToVisible(Range* match) {
   const Node& first_node = *match->FirstNode();
   if (RuntimeEnabledFeatures::InvisibleDOMEnabled() ||
-      RuntimeEnabledFeatures::DisplayLockingEnabled()) {
+      RuntimeEnabledFeatures::DisplayLockingEnabled(
+          first_node.GetExecutionContext())) {
     const EphemeralRangeInFlatTree range(match);
     if (InvisibleDOM::ActivateRangeIfNeeded(range) ||
         DisplayLockUtilities::ActivateFindInPageMatchRangeIfNeeded(range))
diff --git a/third_party/blink/renderer/core/editing/testing/editing_test_base.cc b/third_party/blink/renderer/core/editing/testing/editing_test_base.cc
index 941df98..b66976c 100644
--- a/third_party/blink/renderer/core/editing/testing/editing_test_base.cc
+++ b/third_party/blink/renderer/core/editing/testing/editing_test_base.cc
@@ -12,40 +12,15 @@
 #include "third_party/blink/renderer/core/editing/selection_template.h"
 #include "third_party/blink/renderer/core/editing/testing/selection_sample.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
-#include "third_party/blink/renderer/core/html/html_collection.h"
 #include "third_party/blink/renderer/core/html/html_element.h"
 #include "third_party/blink/renderer/core/testing/dummy_page_holder.h"
 
 namespace blink {
 
-namespace {
-
-Element* GetOrCreateElement(ContainerNode* parent,
-                            const HTMLQualifiedName& tag_name) {
-  HTMLCollection* elements = parent->getElementsByTagNameNS(
-      tag_name.NamespaceURI(), tag_name.LocalName());
-  if (!elements->IsEmpty())
-    return elements->item(0);
-  return parent->ownerDocument()->CreateRawElement(
-      tag_name, CreateElementFlags::ByCreateElement());
-}
-
-}  // namespace
-
 EditingTestBase::EditingTestBase() = default;
 
 EditingTestBase::~EditingTestBase() = default;
 
-void EditingTestBase::InsertStyleElement(const std::string& style_rules) {
-  Element* const head =
-      GetOrCreateElement(&GetDocument(), html_names::kHeadTag);
-  DCHECK_EQ(head, GetOrCreateElement(&GetDocument(), html_names::kHeadTag));
-  Element* const style = GetDocument().CreateRawElement(
-      html_names::kStyleTag, CreateElementFlags::ByCreateElement());
-  style->setTextContent(String(style_rules.data(), style_rules.size()));
-  head->appendChild(style);
-}
-
 Position EditingTestBase::SetCaretTextToBody(
     const std::string& selection_text) {
   const SelectionInDOMTree selection = SetSelectionTextToBody(selection_text);
diff --git a/third_party/blink/renderer/core/editing/testing/editing_test_base.h b/third_party/blink/renderer/core/editing/testing/editing_test_base.h
index bd810b7..091d4a2 100644
--- a/third_party/blink/renderer/core/editing/testing/editing_test_base.h
+++ b/third_party/blink/renderer/core/editing/testing/editing_test_base.h
@@ -29,10 +29,6 @@
   EditingTestBase();
   ~EditingTestBase() override;
 
-  // Insert STYLE element with |style_rules|, no need to have "<style>", into
-  // HEAD.
-  void InsertStyleElement(const std::string& style_rules);
-
   // Returns |Position| for specified |caret_text|, which is HTML markup with
   // caret marker "|".
   Position SetCaretTextToBody(const std::string& caret_text);
diff --git a/third_party/blink/renderer/core/fileapi/public_url_manager.cc b/third_party/blink/renderer/core/fileapi/public_url_manager.cc
index f717b64..d1e70d86 100644
--- a/third_party/blink/renderer/core/fileapi/public_url_manager.cc
+++ b/third_party/blink/renderer/core/fileapi/public_url_manager.cc
@@ -164,7 +164,8 @@
 
 void PublicURLManager::Resolve(
     const KURL& url,
-    network::mojom::blink::URLLoaderFactoryRequest factory_request) {
+    mojo::PendingReceiver<network::mojom::blink::URLLoaderFactory>
+        factory_receiver) {
   if (is_stopped_)
     return;
 
@@ -174,7 +175,7 @@
         GetExecutionContext()->GetSecurityOrigin(),
         url_store_.BindNewEndpointAndPassReceiver());
   }
-  url_store_->ResolveAsURLLoaderFactory(url, std::move(factory_request));
+  url_store_->ResolveAsURLLoaderFactory(url, std::move(factory_receiver));
 }
 
 void PublicURLManager::Resolve(
diff --git a/third_party/blink/renderer/core/fileapi/public_url_manager.h b/third_party/blink/renderer/core/fileapi/public_url_manager.h
index 89ede27..ed87d45 100644
--- a/third_party/blink/renderer/core/fileapi/public_url_manager.h
+++ b/third_party/blink/renderer/core/fileapi/public_url_manager.h
@@ -27,6 +27,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_FILEAPI_PUBLIC_URL_MANAGER_H_
 
 #include "mojo/public/cpp/bindings/associated_remote.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/mojom/url_loader_factory.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h"
 #include "third_party/blink/renderer/core/core_export.h"
@@ -59,7 +60,8 @@
   void Revoke(const KURL&);
   // When mojo Blob URLs are enabled this resolves the provided URL to a
   // factory capable of creating loaders for the specific URL.
-  void Resolve(const KURL&, network::mojom::blink::URLLoaderFactoryRequest);
+  void Resolve(const KURL&,
+               mojo::PendingReceiver<network::mojom::blink::URLLoaderFactory>);
   // When mojo Blob URLs are enabled this resolves the provided URL to a mojom
   // BlobURLToken. This token can be used by the browser process to securely
   // lookup what blob a URL used to refer to, even after the URL is revoked.
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc
index 89ae1d2..1d6f032 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc
+++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc
@@ -127,7 +127,10 @@
   // The end of a script task that drew content to the canvas is the point
   // at which the current frame may be considered complete.
   if (Host())
-    Host()->FinalizeFrame();
+    Host()->PreFinalizeFrame();
+  FinalizeFrame();
+  if (Host())
+    Host()->PostFinalizeFrame();
 }
 
 CanvasRenderingContext::ContextType CanvasRenderingContext::ContextTypeFromId(
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
index 7d10e624d..4985dc7 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
+++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h
@@ -94,7 +94,7 @@
   virtual bool IsOriginTopLeft() const {
     // Canvas contexts have the origin of coordinates on the top left corner.
     // Accelerated resources (e.g. GPU textures) have their origin of
-    // coordinates in the uppper left corner.
+    // coordinates in the upper left corner.
     return !IsAccelerated();
   }
   virtual bool ShouldAntialias() const { return false; }
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h
index a4f4175..851de57 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h
+++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h
@@ -46,7 +46,8 @@
   virtual void DidDraw(const FloatRect& rect) = 0;
   virtual void DidDraw() = 0;
 
-  virtual void FinalizeFrame() = 0;
+  virtual void PreFinalizeFrame() = 0;
+  virtual void PostFinalizeFrame() = 0;
   virtual bool PushFrame(scoped_refptr<CanvasResource> frame,
                          const SkIRect& damage_rect) = 0;
   virtual bool OriginClean() const = 0;
@@ -96,7 +97,7 @@
   CanvasColorParams ColorParams() const;
 
   // For deferred canvases this will have the side effect of drawing recorded
-  // commands in order to finalize the frame
+  // commands in order to finalize the frame.
   ScriptPromise convertToBlob(ScriptState*,
                               const ImageEncodeOptions*,
                               ExceptionState&);
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
index 8935a28b..da01ba4 100644
--- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
+++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc
@@ -393,43 +393,35 @@
   DidDraw(FloatRect(0, 0, Size().Width(), Size().Height()));
 }
 
-void HTMLCanvasElement::FinalizeFrame() {
-  TRACE_EVENT0("blink", "HTMLCanvasElement::FinalizeFrame");
+void HTMLCanvasElement::PreFinalizeFrame() {
   RecordCanvasSizeToUMA(size_);
 
-  // FinalizeFrame indicates the end of a script task that may have rendered
+  // PreFinalizeFrame indicates the end of a script task that may have rendered
   // into the canvas, now is a good time to unlock cache entries.
   auto* resource_provider = ResourceProvider();
   if (resource_provider)
     resource_provider->ReleaseLockedImages();
 
-  // Low-latency 2d canvases will produce their frames after the resource gets
-  // single buffered
-  if (context_ && !(Is2d() && LowLatencyEnabled()))
-    context_->FinalizeFrame();
-
+  // Low-latency 2d canvases produce their frames after the resource gets
+  // single buffered.
   if (LowLatencyEnabled() && !dirty_rect_.IsEmpty()) {
     if (GetOrCreateCanvasResourceProvider(kPreferAcceleration)) {
       const bool webgl_overlay_enabled =
           RuntimeEnabledFeatures::WebGLImageChromiumEnabled() ||
           context_->UsingSwapChain();
-      // TryEnableSingleBuffering() the first time we FinalizeFrame().
+      // TryEnableSingleBuffering() the first time we finalize a frame.
       if (!ResourceProvider()->IsSingleBuffered()) {
         ResourceProvider()->TryEnableSingleBuffering();
         if (Is3d() && webgl_overlay_enabled)
           context_->ProvideBackBufferToResourceProvider();
       }
+    }
+  }
+}
 
-      // TODO(aaronhk) This should just be a generic call to finalize frame
-      // but the pixel 2 bot hanging prevents it (crbug.com/1002946)
-      if (canvas2d_bridge_) {
-        canvas2d_bridge_->FlushRecording();
-      } else {
-        DCHECK(Is3d());
-        if (!webgl_overlay_enabled)
-          context_->PaintRenderingResultsToCanvas(kBackBuffer);
-      }
-
+void HTMLCanvasElement::PostFinalizeFrame() {
+  if (LowLatencyEnabled() && !dirty_rect_.IsEmpty()) {
+    if (GetOrCreateCanvasResourceProvider(kPreferAcceleration)) {
       const base::TimeTicks start_time = base::TimeTicks::Now();
       const scoped_refptr<CanvasResource> canvas_resource =
           ResourceProvider()->ProduceCanvasResource();
diff --git a/third_party/blink/renderer/core/html/canvas/html_canvas_element.h b/third_party/blink/renderer/core/html/canvas/html_canvas_element.h
index fc2dd311c..978e4fd 100644
--- a/third_party/blink/renderer/core/html/canvas/html_canvas_element.h
+++ b/third_party/blink/renderer/core/html/canvas/html_canvas_element.h
@@ -185,7 +185,8 @@
 
   void DoDeferredPaintInvalidation();
 
-  void FinalizeFrame() override;
+  void PreFinalizeFrame() override;
+  void PostFinalizeFrame() override;
 
   CanvasResourceDispatcher* GetOrCreateResourceDispatcher() override;
 
diff --git a/third_party/blink/renderer/core/html/custom/element_internals.cc b/third_party/blink/renderer/core/html/custom/element_internals.cc
index 636f1c21..946528c 100644
--- a/third_party/blink/renderer/core/html/custom/element_internals.cc
+++ b/third_party/blink/renderer/core/html/custom/element_internals.cc
@@ -41,8 +41,8 @@
 
   void setValue(const AtomicString& new_value) override {
     DidUpdateAttributeValue(value(), new_value);
-    // TODO(crbug.com/1012098): Calls GetElement().PseudoStateChanged() for
-    // ':state()'
+    // Should we have invalidation set for each of state tokens?
+    GetElement().PseudoStateChanged(CSSSelector::kPseudoState);
   }
 };
 
@@ -235,6 +235,10 @@
   return custom_states_;
 }
 
+bool ElementInternals::HasState(const AtomicString& state) const {
+  return custom_states_ && custom_states_->contains(state);
+}
+
 const AtomicString& ElementInternals::FastGetAttribute(
     const QualifiedName& attribute) const {
   return accessibility_semantics_map_.at(attribute);
diff --git a/third_party/blink/renderer/core/html/custom/element_internals.h b/third_party/blink/renderer/core/html/custom/element_internals.h
index bef9450..1b5185e 100644
--- a/third_party/blink/renderer/core/html/custom/element_internals.h
+++ b/third_party/blink/renderer/core/html/custom/element_internals.h
@@ -53,6 +53,8 @@
   LabelsNodeList* labels(ExceptionState& exception_state);
   DOMTokenList* states();
 
+  bool HasState(const AtomicString& state) const;
+
   // We need these functions because we are reflecting ARIA attributes.
   // See dom/aria_attributes.idl.
   const AtomicString& FastGetAttribute(const QualifiedName&) const;
diff --git a/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css b/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css
index 274e000..860e2a39 100644
--- a/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css
+++ b/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css
@@ -78,3 +78,15 @@
 .controls-refresh .suggestion-list-entry .label {
   color: rgba(16, 16, 16, 0.6) !important;
 }
+
+@media (forced-colors: active) {
+  .suggestion-list-entry:focus {
+    background-color: Highlight !important;
+    color: Window !important;
+    forced-color-adjust: none;
+  }
+
+  .suggestion-list-entry:focus .label {
+    color: Window !important;
+  }
+}
diff --git a/third_party/blink/renderer/core/inspector/browser_protocol.pdl b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
index b50b54e..10a9a87d 100644
--- a/third_party/blink/renderer/core/inspector/browser_protocol.pdl
+++ b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
@@ -844,6 +844,10 @@
       number startColumn
       # Size of the content (in characters).
       number length
+      # Line offset of the end of the stylesheet within the resource (zero based).
+      number endLine
+      # Column offset of the end of the stylesheet within the resource (zero based).
+      number endColumn
 
   # CSS rule representation.
   type CSSRule extends object
diff --git a/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc b/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
index bce7ab9..21246912 100644
--- a/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
@@ -1447,6 +1447,29 @@
   }
 }
 
+namespace {
+
+TextPosition TextPositionFromOffsetAndLineEndingsRelativeToStartPosition(
+    unsigned offset,
+    const Vector<unsigned>& line_endings,
+    const TextPosition& start_position) {
+  TextPosition position =
+      TextPosition::FromOffsetAndLineEndings(offset, line_endings);
+  unsigned column = position.column_.ZeroBasedInt();
+  // A non-zero `start_position.column_` means that the text started in the
+  // middle of a line, so the start column position must be added if `offset`
+  // translates to a `position` in the first line of the text.
+  if (position.line_.ZeroBasedInt() == 0) {
+    column += start_position.column_.ZeroBasedInt();
+  }
+  unsigned line_index =
+      start_position.line_.ZeroBasedInt() + position.line_.ZeroBasedInt();
+  return TextPosition(OrdinalNumber::FromZeroBasedInt(line_index),
+                      OrdinalNumber::FromZeroBasedInt(column));
+}
+
+}  // namespace
+
 std::unique_ptr<protocol::CSS::CSSStyleSheetHeader>
 InspectorStyleSheet::BuildObjectForStyleSheetInfo() {
   CSSStyleSheet* style_sheet = PageStyleSheet();
@@ -1455,8 +1478,16 @@
 
   Document* document = style_sheet->OwnerDocument();
   LocalFrame* frame = document ? document->GetFrame() : nullptr;
-  String text;
-  GetText(&text);
+  const LineEndings* line_endings = this->GetLineEndings();
+  TextPosition start = style_sheet->StartPositionInSource();
+  TextPosition end = start;
+  unsigned text_length = 0;
+  if (line_endings->size() > 0) {
+    text_length = line_endings->back();
+    end = TextPositionFromOffsetAndLineEndingsRelativeToStartPosition(
+        text_length, *line_endings, start);
+  }
+
   std::unique_ptr<protocol::CSS::CSSStyleSheetHeader> result =
       protocol::CSS::CSSStyleSheetHeader::create()
           .setStyleSheetId(Id())
@@ -1466,11 +1497,11 @@
           .setTitle(style_sheet->title())
           .setFrameId(frame ? IdentifiersFactory::FrameId(frame) : "")
           .setIsInline(style_sheet->IsInline() && !StartsAtZero())
-          .setStartLine(
-              style_sheet->StartPositionInSource().line_.ZeroBasedInt())
-          .setStartColumn(
-              style_sheet->StartPositionInSource().column_.ZeroBasedInt())
-          .setLength(text.length())
+          .setStartLine(start.line_.ZeroBasedInt())
+          .setStartColumn(start.column_.ZeroBasedInt())
+          .setLength(text_length)
+          .setEndLine(end.line_.ZeroBasedInt())
+          .setEndColumn(end.column_.ZeroBasedInt())
           .build();
 
   if (HasSourceURL())
diff --git a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
index 27c534a..6554600 100644
--- a/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_trace_events.cc
@@ -258,6 +258,7 @@
     DEFINE_STRING_MAPPING(PseudoNthLastChild)
     DEFINE_STRING_MAPPING(PseudoNthLastOfType)
     DEFINE_STRING_MAPPING(PseudoPart)
+    DEFINE_STRING_MAPPING(PseudoState)
     DEFINE_STRING_MAPPING(PseudoLink)
     DEFINE_STRING_MAPPING(PseudoVisited)
     DEFINE_STRING_MAPPING(PseudoAny)
diff --git a/third_party/blink/renderer/core/layout/layout_list_marker.cc b/third_party/blink/renderer/core/layout/layout_list_marker.cc
index 15986960..6ef9788 100644
--- a/third_party/blink/renderer/core/layout/layout_list_marker.cc
+++ b/third_party/blink/renderer/core/layout/layout_list_marker.cc
@@ -84,7 +84,10 @@
                                        const ComputedStyle& new_style) {
   if (Style() &&
       (new_style.ListStylePosition() != StyleRef().ListStylePosition() ||
-       new_style.ListStyleType() != StyleRef().ListStyleType())) {
+       new_style.ListStyleType() != StyleRef().ListStyleType() ||
+       (new_style.ListStyleType() == EListStyleType::kString &&
+        new_style.ListStyleStringValue() !=
+            StyleRef().ListStyleStringValue()))) {
     SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
         layout_invalidation_reason::kStyleChange);
   }
@@ -201,21 +204,31 @@
       text_ = list_marker_text::GetText(StyleRef().ListStyleType(),
                                         list_item_->Value());
       break;
+    case ListStyleCategory::kStaticString:
+      text_ = StyleRef().ListStyleStringValue();
+      break;
   }
 }
 
 String LayoutListMarker::TextAlternative() const {
+  if (GetListStyleCategory() == ListStyleCategory::kStaticString)
+    return text_;
   UChar suffix =
       list_marker_text::Suffix(StyleRef().ListStyleType(), list_item_->Value());
   // Return suffix after the marker text, even in RTL, reflecting speech order.
   return text_ + suffix + ' ';
 }
 
-LayoutUnit LayoutListMarker::GetWidthOfTextWithSuffix() const {
+LayoutUnit LayoutListMarker::GetWidthOfText(ListStyleCategory category) const {
+  // TODO(crbug.com/1012289): this code doesn't support bidi algorithm.
   if (text_.IsEmpty())
     return LayoutUnit();
   const Font& font = StyleRef().GetFont();
   LayoutUnit item_width = LayoutUnit(font.Width(TextRun(text_)));
+  if (category == ListStyleCategory::kStaticString) {
+    // Don't add a suffix.
+    return item_width;
+  }
   // TODO(wkorman): Look into constructing a text run for both text and suffix
   // and painting them together.
   UChar suffix[2] = {
@@ -242,14 +255,16 @@
   }
 
   LayoutUnit logical_width;
-  switch (GetListStyleCategory()) {
+  ListStyleCategory category = GetListStyleCategory();
+  switch (category) {
     case ListStyleCategory::kNone:
       break;
     case ListStyleCategory::kSymbol:
       logical_width = WidthOfSymbol(StyleRef());
       break;
     case ListStyleCategory::kLanguage:
-      logical_width = GetWidthOfTextWithSuffix();
+    case ListStyleCategory::kStaticString:
+      logical_width = GetWidthOfText(category);
       break;
   }
 
@@ -395,6 +410,8 @@
   switch (type) {
     case EListStyleType::kNone:
       return ListStyleCategory::kNone;
+    case EListStyleType::kString:
+      return ListStyleCategory::kStaticString;
     case EListStyleType::kDisc:
     case EListStyleType::kCircle:
     case EListStyleType::kSquare:
@@ -468,18 +485,20 @@
     return LayoutRect(LayoutPoint(), ImageBulletSize());
 
   LayoutRect relative_rect;
-  switch (GetListStyleCategory()) {
+  ListStyleCategory category = GetListStyleCategory();
+  switch (category) {
     case ListStyleCategory::kNone:
       return LayoutRect();
     case ListStyleCategory::kSymbol:
       return RelativeSymbolMarkerRect(StyleRef(), Size().Width());
-    case ListStyleCategory::kLanguage: {
+    case ListStyleCategory::kLanguage:
+    case ListStyleCategory::kStaticString: {
       const SimpleFontData* font_data = StyleRef().GetFont().PrimaryFont();
       DCHECK(font_data);
       if (!font_data)
         return relative_rect;
       relative_rect =
-          LayoutRect(LayoutUnit(), LayoutUnit(), GetWidthOfTextWithSuffix(),
+          LayoutRect(LayoutUnit(), LayoutUnit(), GetWidthOfText(category),
                      LayoutUnit(font_data->GetFontMetrics().Height()));
       break;
     }
diff --git a/third_party/blink/renderer/core/layout/layout_list_marker.h b/third_party/blink/renderer/core/layout/layout_list_marker.h
index 69c6ed6..68d1a29 100644
--- a/third_party/blink/renderer/core/layout/layout_list_marker.h
+++ b/third_party/blink/renderer/core/layout/layout_list_marker.h
@@ -46,7 +46,7 @@
 
   // A reduced set of list style categories allowing for more concise expression
   // of list style specific logic.
-  enum class ListStyleCategory { kNone, kSymbol, kLanguage };
+  enum class ListStyleCategory { kNone, kSymbol, kLanguage, kStaticString };
 
   // Returns the list's style as one of a reduced high level categorical set of
   // styles.
@@ -113,7 +113,7 @@
 
   bool IsText() const { return !IsImage(); }
 
-  LayoutUnit GetWidthOfTextWithSuffix() const;
+  LayoutUnit GetWidthOfText(ListStyleCategory) const;
   void UpdateMargins();
   void UpdateContent();
 
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index dce3b50..098c883 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -2465,7 +2465,7 @@
   }
 
   DisplayLockContext* GetDisplayLockContext() const {
-    if (!RuntimeEnabledFeatures::DisplayLockingEnabled())
+    if (!RuntimeEnabledFeatures::DisplayLockingEnabled(&GetDocument()))
       return nullptr;
     auto* element = DynamicTo<Element>(GetNode());
     if (!element)
diff --git a/third_party/blink/renderer/core/layout/list_marker_text.cc b/third_party/blink/renderer/core/layout/list_marker_text.cc
index 4d76b7e4..174c83e 100644
--- a/third_party/blink/renderer/core/layout/list_marker_text.cc
+++ b/third_party/blink/renderer/core/layout/list_marker_text.cc
@@ -515,6 +515,9 @@
     case EListStyleType::kUpperAlpha:
     case EListStyleType::kUpperLatin:
       return (count < 1) ? EListStyleType::kDecimal : type;
+    case EListStyleType::kString:
+      NOTREACHED();
+      break;
   }
 
   NOTREACHED();
@@ -590,6 +593,9 @@
     case EListStyleType::kKoreanHanjaFormal:
     case EListStyleType::kKoreanHanjaInformal:
       return 0x3001;
+    case EListStyleType::kString:
+      NOTREACHED();
+      break;
   }
 
   NOTREACHED();
@@ -924,6 +930,10 @@
       return ToGeorgian(count);
     case EListStyleType::kHebrew:
       return ToHebrew(count);
+
+    case EListStyleType::kString:
+      NOTREACHED();
+      break;
   }
 
   NOTREACHED();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
index 3e7a0f8e..ab9ab64 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
@@ -16,7 +16,8 @@
       type_(kText),
       style_variant_(static_cast<unsigned>(text.StyleVariant())),
       is_flow_control_(text.IsFlowControl()),
-      is_hidden_for_paint_(false) {
+      is_hidden_for_paint_(false),
+      text_direction_(static_cast<unsigned>(text.ResolvedDirection())) {
   DCHECK_LE(text_.start_offset, text_.end_offset);
 #if DCHECK_IS_ON()
   if (text_.shape_result) {
@@ -34,7 +35,8 @@
       rect_({PhysicalOffset(), line.Size()}),
       type_(kLine),
       style_variant_(static_cast<unsigned>(line.StyleVariant())),
-      is_hidden_for_paint_(false) {}
+      is_hidden_for_paint_(false),
+      text_direction_(static_cast<unsigned>(line.BaseDirection())) {}
 
 NGFragmentItem::NGFragmentItem(const NGPhysicalBoxFragment& box,
                                wtf_size_t item_count)
@@ -43,7 +45,10 @@
       rect_({PhysicalOffset(), box.Size()}),
       type_(kBox),
       style_variant_(static_cast<unsigned>(box.StyleVariant())),
-      is_hidden_for_paint_(false) {}
+      is_hidden_for_paint_(false),
+      // TODO(yosin): We should have |textDirection| parameter from
+      // |NGLineBoxFragmentBuilder::Child::BidiLevel()|
+      text_direction_(box.IsAtomicInline() && IsLtr(box.ResolvedDirection())) {}
 
 NGFragmentItem::~NGFragmentItem() {
   switch (Type()) {
@@ -62,6 +67,22 @@
   }
 }
 
+bool NGFragmentItem::HasSameParent(const NGFragmentItem& other) const {
+  if (!GetLayoutObject())
+    return !other.GetLayoutObject();
+  if (!other.GetLayoutObject())
+    return false;
+  return GetLayoutObject()->Parent() == other.GetLayoutObject()->Parent();
+}
+
+bool NGFragmentItem::IsAtomicInline() const {
+  if (Type() != kBox)
+    return false;
+  if (const NGPhysicalBoxFragment* box = BoxFragment())
+    return box->IsAtomicInline();
+  return false;
+}
+
 PhysicalRect NGFragmentItem::SelfInkOverflow() const {
   // TODO(kojii): Implement.
   return LocalRect();
@@ -114,6 +135,16 @@
   return {};
 }
 
+TextDirection NGFragmentItem::BaseDirection() const {
+  DCHECK_EQ(Type(), kLine);
+  return static_cast<TextDirection>(text_direction_);
+}
+
+TextDirection NGFragmentItem::ResolvedDirection() const {
+  DCHECK(Type() == kText || Type() == kGeneratedText || IsAtomicInline());
+  return static_cast<TextDirection>(text_direction_);
+}
+
 String NGFragmentItem::DebugName() const {
   return "NGFragmentItem";
 }
@@ -180,4 +211,47 @@
   return *this;
 }
 
+std::ostream& operator<<(std::ostream& ostream, const NGFragmentItem& item) {
+  ostream << "{";
+  switch (item.Type()) {
+    case NGFragmentItem::kText:
+      ostream << "Text " << item.StartOffset() << "-" << item.EndOffset() << " "
+              << (IsLtr(item.ResolvedDirection()) ? "LTR" : "RTL");
+      break;
+    case NGFragmentItem::kGeneratedText:
+      ostream << "GeneratedText \"" << item.GeneratedText() << "\"";
+      break;
+    case NGFragmentItem::kLine:
+      ostream << "Line #descendants=" << item.DescendantsCount() << " "
+              << (IsLtr(item.BaseDirection()) ? "LTR" : "RTL");
+      break;
+    case NGFragmentItem::kBox:
+      ostream << "Box #descendants=" << item.DescendantsCount();
+      if (item.IsAtomicInline()) {
+        ostream << " AtomicInline"
+                << (IsLtr(item.ResolvedDirection()) ? "LTR" : "RTL");
+      }
+      break;
+  }
+  ostream << " ";
+  switch (item.StyleVariant()) {
+    case NGStyleVariant::kStandard:
+      ostream << "Standard";
+      break;
+    case NGStyleVariant::kFirstLine:
+      ostream << "FirstLine";
+      break;
+    case NGStyleVariant::kEllipsis:
+      ostream << "Ellipsis";
+      break;
+  }
+  return ostream << "}";
+}
+
+std::ostream& operator<<(std::ostream& ostream, const NGFragmentItem* item) {
+  if (!item)
+    return ostream << "<null>";
+  return ostream << *item;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
index 5397a62b..526f635e 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
@@ -42,18 +42,20 @@
   struct LineItem {
     NGLineHeightMetrics metrics;
     scoped_refptr<const NGInlineBreakToken> inline_break_token;
-    wtf_size_t children_count;
+    wtf_size_t descendants_count;
   };
   // Represents a box fragment appeared in a line. This includes inline boxes
   // (e.g., <span>text</span>) and atomic inlines.
   struct BoxItem {
     // If this item is an inline box, its children are stored as following
-    // items. |children_count_| has the number of such items.
+    // items. |descendants_count_| has the number of such items.
     //
     // If this item is a root of another IFC/BFC, children are stored normally,
     // as children of |box_fragment|.
+    //
+    // Note:|box_fragment| can be null for <span>.
     scoped_refptr<const NGPhysicalBoxFragment> box_fragment;
-    wtf_size_t children_count;
+    wtf_size_t descendants_count;
   };
 
   enum ItemType { kText, kGeneratedText, kLine, kBox };
@@ -67,6 +69,7 @@
 
   ItemType Type() const { return static_cast<ItemType>(type_); }
 
+  bool IsAtomicInline() const;
   bool IsHiddenForPaint() const { return is_hidden_for_paint_; }
 
   NGStyleVariant StyleVariant() const {
@@ -85,6 +88,7 @@
     return layout_object_->EffectiveStyle(StyleVariant());
   }
   const LayoutObject* GetLayoutObject() const { return layout_object_; }
+  bool HasSameParent(const NGFragmentItem& other) const;
 
   const PhysicalRect& Rect() const { return rect_; }
   const PhysicalOffset& Offset() const { return rect_.offset; }
@@ -96,12 +100,12 @@
 
   // Count of following items that are descendants of this item in the box tree,
   // including this item. 1 means this is a box (box or line box) without
-  // children. 0 if this item type cannot have children.
-  wtf_size_t ChildrenCount() const {
+  // descendants. 0 if this item type cannot have children.
+  wtf_size_t DescendantsCount() const {
     if (Type() == kBox)
-      return box_.children_count;
+      return box_.descendants_count;
     if (Type() == kLine)
-      return line_.children_count;
+      return line_.descendants_count;
     return 0;
   }
 
@@ -211,6 +215,10 @@
   unsigned EndOffset() const;
   unsigned TextLength() const { return EndOffset() - StartOffset(); }
   StringView Text(const NGFragmentItems& items) const;
+  String GeneratedText() const {
+    DCHECK_EQ(Type(), kGeneratedText);
+    return generated_text_.text;
+  }
 
   // Compute the inline position from text offset, in logical coordinate
   // relative to this fragment.
@@ -235,6 +243,16 @@
                          unsigned start_offset,
                          unsigned end_offset) const;
 
+  // The base direction of line. Also known as the paragraph direction. This may
+  // be different from the direction of the container box when first-line style
+  // is used, or when 'unicode-bidi: plaintext' is used.
+  // Note: This is valid only for |LineItem|.
+  TextDirection BaseDirection() const;
+
+  // Direction of this item valid for |TextItem| and |IsAtomicInline()|.
+  // Note: <span> doesn't have text direction.
+  TextDirection ResolvedDirection() const;
+
  private:
   const LayoutObject* layout_object_;
 
@@ -269,12 +287,16 @@
   // Item index delta to the next item for the same |LayoutObject|.
   // wtf_size_t delta_to_next_for_same_layout_object_ = 0;
 
+  // Note: We should not add |bidi_level_| because it is used only for layout.
   unsigned type_ : 2;           // ItemType
   unsigned style_variant_ : 2;  // NGStyleVariant
   // TODO(yosin): We will change |is_flow_control_| to call |IsLineBreak()| and
   // |TextType() == kFlowControl|.
   unsigned is_flow_control_ : 1;
   unsigned is_hidden_for_paint_ : 1;
+  // Note: For |TextItem| and |GeneratedTextItem|, |text_direction_| equals to
+  // |ShapeResult::Direction()|.
+  unsigned text_direction_ : 1;  // TextDirection.
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
index 773066d..180378cd 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.cc
@@ -6,17 +6,17 @@
 
 #include "third_party/blink/renderer/core/layout/layout_block_flow.h"
 #include "third_party/blink/renderer/core/layout/ng/inline/ng_fragment_items.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_physical_line_box_fragment.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h"
 #include "third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h"
 
 namespace blink {
 
 void NGInlineCursor::MoveToItem(const ItemsSpan::iterator& iter) {
-  DCHECK((items_.data() || !items_.size()) && !root_paint_fragment_);
-  DCHECK(iter == items_.end() ||
-         (&*iter >= items_.data() && iter < items_.end()));
+  DCHECK(IsItemCursor());
+  DCHECK(iter >= items_.begin() && iter <= items_.end());
   item_iter_ = iter;
-  current_item_ = item_iter_ != items_.end() ? item_iter_->get() : nullptr;
+  current_item_ = iter == items_.end() ? nullptr : iter->get();
 }
 
 void NGInlineCursor::SetRoot(ItemsSpan items) {
@@ -33,6 +33,7 @@
 
 void NGInlineCursor::SetRoot(const NGPaintFragment& root_paint_fragment) {
   DCHECK(&root_paint_fragment);
+  DCHECK(!root_paint_fragment.Parent()) << root_paint_fragment;
   root_paint_fragment_ = &root_paint_fragment;
   current_paint_fragment_ = root_paint_fragment.FirstChild();
 }
@@ -42,6 +43,7 @@
 
   if (const NGPhysicalBoxFragment* fragment = block_flow.CurrentFragment()) {
     if (const NGFragmentItems* items = fragment->Items()) {
+      fragment_items_ = items;
       SetRoot(*items);
       return;
     }
@@ -64,6 +66,144 @@
   SetRoot(root_paint_fragment);
 }
 
+NGInlineCursor::NGInlineCursor(const NGInlineCursor& other)
+    : items_(other.items_),
+      item_iter_(other.item_iter_),
+      current_item_(other.current_item_),
+      fragment_items_(other.fragment_items_),
+      root_paint_fragment_(other.root_paint_fragment_),
+      current_paint_fragment_(other.current_paint_fragment_) {}
+
+bool NGInlineCursor::operator==(const NGInlineCursor& other) const {
+  if (root_paint_fragment_) {
+    return root_paint_fragment_ == other.root_paint_fragment_ &&
+           current_paint_fragment_ == other.current_paint_fragment_;
+  }
+  if (current_item_ != other.current_item_)
+    return false;
+  DCHECK_EQ(items_.data(), other.items_.data());
+  DCHECK_EQ(items_.size(), other.items_.size());
+  DCHECK_EQ(fragment_items_, other.fragment_items_);
+  DCHECK(item_iter_ == other.item_iter_);
+  return true;
+}
+
+const LayoutBlockFlow* NGInlineCursor::GetLayoutBlockFlow() const {
+  if (root_paint_fragment_)
+    return To<LayoutBlockFlow>(root_paint_fragment_->GetLayoutObject());
+  for (const auto& item : items_) {
+    if (item->GetLayoutObject() && item->GetLayoutObject()->IsInline())
+      return item->GetLayoutObject()->RootInlineFormattingContext();
+  }
+  NOTREACHED();
+  return nullptr;
+}
+
+bool NGInlineCursor::HasChildren() const {
+  if (current_paint_fragment_)
+    return current_paint_fragment_->FirstChild();
+  if (current_item_) {
+    // Note: |DescendantsCount() == 1| means box/line without children.
+    return current_item_->DescendantsCount() > 1;
+  }
+  NOTREACHED();
+  return false;
+}
+
+bool NGInlineCursor::IsAtomicInline() const {
+  if (current_paint_fragment_)
+    return current_paint_fragment_->PhysicalFragment().IsAtomicInline();
+  if (current_item_)
+    return current_item_->IsAtomicInline();
+  NOTREACHED();
+  return false;
+}
+
+bool NGInlineCursor::IsEllipsis() const {
+  if (current_paint_fragment_)
+    return current_paint_fragment_->IsEllipsis();
+  if (current_item_)
+    return current_item_->IsEllipsis();
+  NOTREACHED();
+  return false;
+}
+
+bool NGInlineCursor::IsHiddenForPaint() const {
+  if (current_paint_fragment_)
+    return current_paint_fragment_->PhysicalFragment().IsHiddenForPaint();
+  if (current_item_)
+    return current_item_->IsHiddenForPaint();
+  NOTREACHED();
+  return false;
+}
+
+bool NGInlineCursor::IsLastLineInInlineBlock() const {
+  DCHECK(IsLineBox());
+  if (!GetLayoutBlockFlow()->IsAtomicInlineLevel())
+    return false;
+  NGInlineCursor next_sibling(*this);
+  for (;;) {
+    next_sibling.MoveToNextSibling();
+    if (!next_sibling)
+      return true;
+    if (next_sibling.IsLineBox())
+      return false;
+    // There maybe other top-level objects such as floats, OOF, or list-markers.
+  }
+}
+
+bool NGInlineCursor::IsLineBreak() const {
+  if (current_paint_fragment_) {
+    if (auto* text_fragment = DynamicTo<NGPhysicalTextFragment>(
+            current_paint_fragment_->PhysicalFragment()))
+      return text_fragment->IsLineBreak();
+    return false;
+  }
+  if (current_item_)
+    return current_item_->IsLineBreak();
+  NOTREACHED();
+  return false;
+}
+
+bool NGInlineCursor::IsBeforeSoftLineBreak() const {
+  if (IsLineBreak())
+    return false;
+  // Inline block is not be container line box.
+  // See paint/selection/text-selection-inline-block.html.
+  NGInlineCursor line(*this);
+  line.MoveToContainingLine();
+  if (line.IsLastLineInInlineBlock()) {
+    // We don't paint a line break the end of inline-block
+    // because if an inline-block is at the middle of line, we should not paint
+    // a line break.
+    // Old layout paints line break if the inline-block is at the end of line,
+    // but since its complex to determine if the inline-block is at the end of
+    // line on NG, we just cancels block-end line break painting for any
+    // inline-block.
+    return false;
+  }
+  NGInlineCursor last_leaf(line);
+  last_leaf.MoveToLastLogicalLeaf();
+  if (last_leaf != *this)
+    return false;
+  // Even If |fragment| is before linebreak, if its direction differs to line
+  // direction, we don't paint line break. See
+  // paint/selection/text-selection-newline-mixed-ltr-rtl.html.
+  return line.CurrentBaseDirection() == CurrentResolvedDirection();
+}
+
+bool NGInlineCursor::CanHaveChildren() const {
+  if (current_paint_fragment_)
+    return current_paint_fragment_->PhysicalFragment().IsContainer();
+  if (current_item_) {
+    return current_item_->Type() == NGFragmentItem::kLine ||
+           (current_item_->Type() == NGFragmentItem::kBox &&
+            !current_item_->IsAtomicInline());
+  }
+  NOTREACHED();
+  return false;
+}
+
 bool NGInlineCursor::IsLineBox() const {
   if (current_paint_fragment_)
     return current_paint_fragment_->PhysicalFragment().IsLineBox();
@@ -73,6 +213,19 @@
   return false;
 }
 
+TextDirection NGInlineCursor::CurrentBaseDirection() const {
+  DCHECK(IsLineBox());
+  if (current_paint_fragment_) {
+    return To<NGPhysicalLineBoxFragment>(
+               current_paint_fragment_->PhysicalFragment())
+        .BaseDirection();
+  }
+  if (current_item_)
+    return current_item_->BaseDirection();
+  NOTREACHED();
+  return TextDirection::kLtr;
+}
+
 const NGPhysicalBoxFragment* NGInlineCursor::CurrentBoxFragment() const {
   if (current_paint_fragment_) {
     return DynamicTo<NGPhysicalBoxFragment>(
@@ -102,46 +255,233 @@
   return PhysicalOffset();
 }
 
-void NGInlineCursor::MoveToNext() {
+TextDirection NGInlineCursor::CurrentResolvedDirection() const {
+  if (current_paint_fragment_)
+    return current_paint_fragment_->PhysicalFragment().ResolvedDirection();
+  if (current_item_)
+    return current_item_->ResolvedDirection();
+  NOTREACHED();
+  return TextDirection::kLtr;
+}
+
+const PhysicalSize NGInlineCursor::CurrentSize() const {
+  if (current_paint_fragment_)
+    return current_paint_fragment_->Size();
+  if (current_item_)
+    return current_item_->Size();
+  NOTREACHED();
+  return PhysicalSize();
+}
+
+const ComputedStyle& NGInlineCursor::CurrentStyle() const {
+  if (current_paint_fragment_)
+    return current_paint_fragment_->Style();
+  return current_item_->Style();
+}
+
+unsigned NGInlineCursor::CurrentTextStartOffset() const {
+  if (current_paint_fragment_) {
+    return To<NGPhysicalTextFragment>(
+               current_paint_fragment_->PhysicalFragment())
+        .StartOffset();
+  }
+  if (current_item_)
+    return current_item_->StartOffset();
+  NOTREACHED();
+  return 0u;
+}
+
+unsigned NGInlineCursor::CurrentTextEndOffset() const {
+  if (current_paint_fragment_) {
+    return To<NGPhysicalTextFragment>(
+               current_paint_fragment_->PhysicalFragment())
+        .EndOffset();
+  }
+  if (current_item_)
+    return current_item_->EndOffset();
+  NOTREACHED();
+  return 0u;
+}
+
+void NGInlineCursor::MakeNull() {
   if (root_paint_fragment_) {
-    MoveToNextPaintFragment();
+    current_paint_fragment_ = nullptr;
     return;
   }
+  if (fragment_items_)
+    return MoveToItem(items_.end());
+  NOTREACHED();
+}
+
+void NGInlineCursor::MoveTo(const LayoutObject& layout_object) {
+  DCHECK(layout_object.IsInLayoutNGInlineFormattingContext());
+  if (root_paint_fragment_) {
+    const auto fragments = NGPaintFragment::InlineFragmentsFor(&layout_object);
+    if (!fragments.IsInLayoutNGInlineFormattingContext() || fragments.IsEmpty())
+      return MakeNull();
+    return MoveTo(fragments.front());
+  }
+  DCHECK(IsItemCursor());
+  item_iter_ = items_.begin();
+  while (current_item_ && CurrentLayoutObject() != &layout_object)
+    MoveToNextItem();
+}
+
+void NGInlineCursor::MoveTo(const NGPaintFragment& paint_fragment) {
+  DCHECK(root_paint_fragment_);
+  DCHECK(paint_fragment.IsDescendantOfNotSelf(*root_paint_fragment_))
+      << paint_fragment << " " << root_paint_fragment_;
+  current_paint_fragment_ = &paint_fragment;
+}
+
+void NGInlineCursor::MoveToContainingLine() {
+  DCHECK(!IsLineBox());
+  if (current_paint_fragment_) {
+    current_paint_fragment_ = current_paint_fragment_->ContainerLineBox();
+    return;
+  }
+  if (current_item_) {
+    do {
+      MoveToPreviousItem();
+    } while (current_item_ && !IsLineBox());
+    return;
+  }
+  NOTREACHED();
+}
+
+void NGInlineCursor::MoveToFirstChild() {
+  DCHECK(CanHaveChildren());
+  if (!TryToMoveToFirstChild())
+    MakeNull();
+}
+
+void NGInlineCursor::MoveToLastChild() {
+  DCHECK(CanHaveChildren());
+  if (!TryToMoveToLastChild())
+    MakeNull();
+}
+
+void NGInlineCursor::MoveToLastLogicalLeaf() {
+  DCHECK(IsLineBox());
+  // TODO(yosin): This isn't correct for mixed Bidi. Fix it. Besides, we should
+  // compute and store it during layout.
+  // TODO(yosin): We should check direction of each container instead of line
+  // box. See also |NGPhysicalLineBoxFragment::LastLogicalLeaf()|.
+  if (IsLtr(CurrentStyle().Direction())) {
+    while (TryToMoveToLastChild())
+      continue;
+    return;
+  }
+  while (TryToMoveToFirstChild())
+    continue;
+}
+
+void NGInlineCursor::MoveToNext() {
+  if (root_paint_fragment_)
+    return MoveToNextPaintFragment();
   MoveToNextItem();
 }
 
-void NGInlineCursor::MoveToNextSkippingChildren() {
-  if (root_paint_fragment_) {
-    MoveToNextPaintFragmentSkippingChildren();
+void NGInlineCursor::MoveToNextForSameLayoutObject() {
+  if (current_paint_fragment_) {
+    if (auto* paint_fragment =
+            current_paint_fragment_->NextForSameLayoutObject())
+      return MoveTo(*paint_fragment);
+    return MakeNull();
+  }
+  if (current_item_) {
+    const LayoutObject* const layout_object = CurrentLayoutObject();
+    DCHECK(layout_object);
+    do {
+      MoveToNextItem();
+    } while (current_item_ && CurrentLayoutObject() != layout_object);
     return;
   }
+}
+
+void NGInlineCursor::MoveToNextSibling() {
+  if (current_paint_fragment_)
+    return MoveToNextSiblingPaintFragment();
+  return MoveToNextSiblingItem();
+}
+
+void NGInlineCursor::MoveToNextSkippingChildren() {
+  if (root_paint_fragment_)
+    return MoveToNextPaintFragmentSkippingChildren();
   MoveToNextItemSkippingChildren();
 }
 
-void NGInlineCursor::MoveToNextItem() {
-  DCHECK((items_.data() || !items_.size()) && !root_paint_fragment_);
-  if (current_item_) {
-    DCHECK(item_iter_ != items_.end());
-    ++item_iter_;
-    current_item_ = item_iter_ != items_.end() ? item_iter_->get() : nullptr;
+bool NGInlineCursor::TryToMoveToFirstChild() {
+  if (!HasChildren())
+    return false;
+  if (root_paint_fragment_) {
+    MoveTo(*current_paint_fragment_->FirstChild());
+    return true;
   }
+  MoveToItem(item_iter_ + 1);
+  return true;
+}
+
+bool NGInlineCursor::TryToMoveToLastChild() {
+  if (!HasChildren())
+    return false;
+  if (root_paint_fragment_) {
+    MoveTo(current_paint_fragment_->Children().back());
+    return true;
+  }
+  const auto end = item_iter_ + CurrentItem()->DescendantsCount();
+  MoveToNextItem();
+  DCHECK(!IsNull());
+  for (auto it = item_iter_ + 1; it != end; ++it) {
+    if (CurrentItem()->HasSameParent(**it))
+      MoveToItem(it);
+  }
+  return true;
+}
+
+void NGInlineCursor::MoveToNextItem() {
+  DCHECK(IsItemCursor());
+  if (UNLIKELY(!current_item_))
+    return;
+  DCHECK(item_iter_ != items_.end());
+  ++item_iter_;
+  MoveToItem(item_iter_);
 }
 
 void NGInlineCursor::MoveToNextItemSkippingChildren() {
-  DCHECK((items_.data() || !items_.size()) && !root_paint_fragment_);
+  DCHECK(IsItemCursor());
   if (UNLIKELY(!current_item_))
     return;
-  // If the current item has |ChildrenCount|, add it to move to the next
+  // If the current item has |DescendantsCount|, add it to move to the next
   // sibling, skipping all children and their descendants.
-  if (wtf_size_t children_count = current_item_->ChildrenCount()) {
-    MoveToItem(item_iter_ + children_count);
-    return;
-  }
+  if (wtf_size_t descendants_count = current_item_->DescendantsCount())
+    return MoveToItem(item_iter_ + descendants_count);
   return MoveToNextItem();
 }
 
+void NGInlineCursor::MoveToNextSiblingItem() {
+  DCHECK(IsItemCursor());
+  if (UNLIKELY(!current_item_))
+    return;
+  const NGFragmentItem& item = *CurrentItem();
+  MoveToNextItemSkippingChildren();
+  if (IsNull() || item.HasSameParent(*CurrentItem()))
+    return;
+  MakeNull();
+}
+
+void NGInlineCursor::MoveToPreviousItem() {
+  DCHECK(IsItemCursor());
+  if (UNLIKELY(!current_item_))
+    return;
+  if (item_iter_ == items_.begin())
+    return MakeNull();
+  --item_iter_;
+  current_item_ = item_iter_->get();
+}
+
 void NGInlineCursor::MoveToParentPaintFragment() {
-  DCHECK(root_paint_fragment_ && current_paint_fragment_);
+  DCHECK(IsPaintFragmentCursor() && current_paint_fragment_);
   const NGPaintFragment* parent = current_paint_fragment_->Parent();
   if (parent && parent != root_paint_fragment_) {
     current_paint_fragment_ = parent;
@@ -151,7 +491,7 @@
 }
 
 void NGInlineCursor::MoveToNextPaintFragment() {
-  DCHECK(root_paint_fragment_ && current_paint_fragment_);
+  DCHECK(IsPaintFragmentCursor() && current_paint_fragment_);
   if (const NGPaintFragment* child = current_paint_fragment_->FirstChild()) {
     current_paint_fragment_ = child;
     return;
@@ -159,8 +499,8 @@
   MoveToNextPaintFragmentSkippingChildren();
 }
 
-void NGInlineCursor::MoveToNextSibilingPaintFragment() {
-  DCHECK(root_paint_fragment_ && current_paint_fragment_);
+void NGInlineCursor::MoveToNextSiblingPaintFragment() {
+  DCHECK(IsPaintFragmentCursor() && current_paint_fragment_);
   if (const NGPaintFragment* next = current_paint_fragment_->NextSibling()) {
     current_paint_fragment_ = next;
     return;
@@ -169,8 +509,8 @@
 }
 
 void NGInlineCursor::MoveToNextPaintFragmentSkippingChildren() {
-  DCHECK(root_paint_fragment_ && current_paint_fragment_);
-  while (!IsAtEnd()) {
+  DCHECK(IsPaintFragmentCursor() && current_paint_fragment_);
+  while (current_paint_fragment_) {
     if (const NGPaintFragment* next = current_paint_fragment_->NextSibling()) {
       current_paint_fragment_ = next;
       return;
@@ -179,4 +519,21 @@
   }
 }
 
+std::ostream& operator<<(std::ostream& ostream, const NGInlineCursor& cursor) {
+  if (cursor.IsNull())
+    return ostream << "NGInlineCursor()";
+  if (cursor.IsPaintFragmentCursor()) {
+    return ostream << "NGInlineCursor(" << *cursor.CurrentPaintFragment()
+                   << ")";
+  }
+  DCHECK(cursor.IsItemCursor());
+  return ostream << "NGInlineCursor(" << *cursor.CurrentItem() << ")";
+}
+
+std::ostream& operator<<(std::ostream& ostream, const NGInlineCursor* cursor) {
+  if (!cursor)
+    return ostream << "<null>";
+  return ostream << *cursor;
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
index d0be72ea3..da63a2f1 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor.h
@@ -7,10 +7,12 @@
 
 #include "base/containers/span.h"
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/text/text_direction.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
 namespace blink {
 
+class ComputedStyle;
 class LayoutObject;
 class LayoutBlockFlow;
 class NGFragmentItem;
@@ -18,6 +20,7 @@
 class NGPaintFragment;
 class NGPhysicalBoxFragment;
 struct PhysicalOffset;
+struct PhysicalSize;
 
 // This class traverses fragments in an inline formatting context.
 //
@@ -30,52 +33,156 @@
   STACK_ALLOCATED();
 
  public:
-  NGInlineCursor(const LayoutBlockFlow& block_flow);
-  NGInlineCursor(const NGFragmentItems& items);
-  NGInlineCursor(const NGPaintFragment& root_paint_fragment);
+  explicit NGInlineCursor(const LayoutBlockFlow& block_flow);
+  explicit NGInlineCursor(const NGFragmentItems& items);
+  explicit NGInlineCursor(const NGPaintFragment& root_paint_fragment);
+  NGInlineCursor(const NGInlineCursor& other);
+
+  bool operator==(const NGInlineCursor& other) const;
+  bool operator!=(const NGInlineCursor& other) const {
+    return !operator==(other);
+  }
+
+  bool IsItemCursor() const { return fragment_items_; }
+  bool IsPaintFragmentCursor() const { return root_paint_fragment_; }
+
+  const NGFragmentItems& Items() const {
+    DCHECK(fragment_items_);
+    return *fragment_items_;
+  }
+
+  // Returns the |LayoutBlockFlow| containing this cursor.
+  const LayoutBlockFlow* GetLayoutBlockFlow() const;
 
   //
   // Functions to query the current position.
   //
 
-  bool IsAtEnd() const { return !current_item_ && !current_paint_fragment_; }
-  explicit operator bool() const { return !IsAtEnd(); }
+  // Returns true if cursor is out of fragment tree, e.g. before first fragment
+  // or after last fragment in tree.
+  bool IsNull() const { return !current_item_ && !current_paint_fragment_; }
+  bool IsNotNull() const { return !IsNull(); }
+  explicit operator bool() const { return !IsNull(); }
 
-  // True if the current position is a line box.
+  // True if fragment at the current position can have children.
+  bool CanHaveChildren() const;
+
+  // True if fragment at the current position has children.
+  bool HasChildren() const;
+
+  // True if the current position is a atomic inline. It is error to call at
+  // end.
+  bool IsAtomicInline() const;
+
+  // True if the current position is before soft line break. It is error to call
+  // at end.
+  bool IsBeforeSoftLineBreak() const;
+
+  // True if the current position is an ellipsis. It is error to call at end.
+  bool IsEllipsis() const;
+
+  // True if the current position is hidden for paint. It is error to call at
+  // end.
+  bool IsHiddenForPaint() const;
+
+  // True if the current position is a line box. It is error to call at end.
   bool IsLineBox() const;
 
+  // True if the current position is a line break. It is error to call at end.
+  bool IsLineBreak() const;
+
   // |Current*| functions return an object for the current position.
   const NGFragmentItem* CurrentItem() const { return current_item_; }
   const NGPaintFragment* CurrentPaintFragment() const {
     return current_paint_fragment_;
   }
+  // Returns text direction of current line. It is error to call at other than
+  // line.
+  TextDirection CurrentBaseDirection() const;
   const NGPhysicalBoxFragment* CurrentBoxFragment() const;
   const LayoutObject* CurrentLayoutObject() const;
-  const NGFragmentItems& Items() const {
-    DCHECK(fragment_items_);
-    return *fragment_items_;
-  }
+  // Returns text direction of current text or atomic inline. It is error to
+  // call at other than text or atomic inline. Note: <span> doesn't have
+  // reserved direction.
+  TextDirection CurrentResolvedDirection() const;
+  const ComputedStyle& CurrentStyle() const;
 
   // The offset relative to the root of the inline formatting context.
   const PhysicalOffset CurrentOffset() const;
+  const PhysicalSize CurrentSize() const;
+
+  // Returns start/end of offset in text content of current text fragment.
+  // It is error when this cursor doesn't point to text fragment.
+  unsigned CurrentTextStartOffset() const;
+  unsigned CurrentTextEndOffset() const;
 
   //
   // Functions to move the current position.
   //
 
-  // Move the current position to the next fragment in pre-order DFS. Returns
-  // |true| if the move was successful.
+  // Move the current posint at |paint_fragment|.
+  void MoveTo(const NGPaintFragment& paint_fragment);
+
+  // Move to first |NGFragmentItem| or |NGPaintFragment| associated to
+  // |layout_object|. When |layout_object| has no associated fragments, this
+  // cursor points nothing.
+  void MoveTo(const LayoutObject& layout_object);
+
+  // Move to containing line box. It is error if the current position is line.
+  void MoveToContainingLine();
+
+  // Move to first child of current container box. If the current position is
+  // at fragment without children, this cursor points nothing.
+  // See also |TryToMoveToFirstChild()|.
+  void MoveToFirstChild();
+
+  // Move to last child of current container box. If the current position is
+  // at fragment without children, this cursor points nothing.
+  // See also |TryToMoveToFirstChild()|.
+  void MoveToLastChild();
+
+  // Move to last logical leaf of current line box. If current line box has
+  // no children, curosr becomes null.
+  void MoveToLastLogicalLeaf();
+
+  // Move the current position to the next fragment in pre-order DFS. When
+  // the current position is at last fragment, this cursor points nothing.
   void MoveToNext();
 
+  // Move the current position to next fragment on same layout object.
+  void MoveToNextForSameLayoutObject();
+
+  // Move the current position to next sibling fragment.
+  void MoveToNextSibling();
+
   // Same as |MoveToNext| except that this skips children even if they exist.
   void MoveToNextSkippingChildren();
 
+  // Returns true if the current position moves to first child.
+  bool TryToMoveToFirstChild();
+
+  // Returns true if the current position moves to last child.
+  bool TryToMoveToLastChild();
+
   // TODO(kojii): Add more variations as needed, NextSibling,
   // NextSkippingChildren, Previous, etc.
 
  private:
   using ItemsSpan = base::span<const std::unique_ptr<NGFragmentItem>>;
 
+  // |NGInlineCursor| is either paint fragment cursor or fragment item cursor.
+  // TODO(yosin): When we implement default constructor of |NGInlineCursor|,
+  // we'll call it "void cursor" instead of "null cursor".
+  NGInlineCursor() = delete;
+
+  // True if the current position is a last line in inline block. It is error
+  // to call at end or the current position is not line.
+  bool IsLastLineInInlineBlock() const;
+
+  // Make the current position points nothing, e.g. cursor moves over start/end
+  // fragment, cursor moves to first/last child to parent has no children.
+  void MakeNull();
+
   void SetRoot(const NGFragmentItems& items);
   void SetRoot(ItemsSpan items);
   void SetRoot(const NGPaintFragment& root_paint_fragment);
@@ -83,10 +190,12 @@
   void MoveToItem(const ItemsSpan::iterator& iter);
   void MoveToNextItem();
   void MoveToNextItemSkippingChildren();
+  void MoveToNextSiblingItem();
+  void MoveToPreviousItem();
 
   void MoveToParentPaintFragment();
   void MoveToNextPaintFragment();
-  void MoveToNextSibilingPaintFragment();
+  void MoveToNextSiblingPaintFragment();
   void MoveToNextPaintFragmentSkippingChildren();
 
   ItemsSpan items_;
@@ -98,6 +207,9 @@
   const NGPaintFragment* current_paint_fragment_ = nullptr;
 };
 
+CORE_EXPORT std::ostream& operator<<(std::ostream&, const NGInlineCursor&);
+CORE_EXPORT std::ostream& operator<<(std::ostream&, const NGInlineCursor*);
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_INLINE_NG_INLINE_CURSOR_H_
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc
index dc23eb4..8ff6f47 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_cursor_test.cc
@@ -7,6 +7,7 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/core/layout/layout_text.h"
+#include "third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_data.h"
 #include "third_party/blink/renderer/core/layout/ng/ng_layout_test.h"
 
 namespace blink {
@@ -20,18 +21,31 @@
   NGInlineCursorTest() : ScopedLayoutNGFragmentItemForTest(GetParam()) {}
 
  protected:
-  Vector<String> ToDebugStringList(NGInlineCursor* cursor) {
+  NGInlineCursor SetupCursor(const String& html) {
+    SetBodyInnerHTML(html);
+    const LayoutBlockFlow& block_flow =
+        *To<LayoutBlockFlow>(GetLayoutObjectByElementId("root"));
+    return NGInlineCursor(block_flow);
+  }
+
+  Vector<String> ToDebugStringList(const NGInlineCursor& start) {
     Vector<String> list;
-    for (; *cursor; cursor->MoveToNext())
-      list.push_back(ToDebugString(*cursor));
+    for (NGInlineCursor cursor(start); cursor; cursor.MoveToNext())
+      list.push_back(ToDebugString(cursor));
     return list;
   }
 
   String ToDebugString(const NGInlineCursor& cursor) {
+    const String text_content =
+        cursor.GetLayoutBlockFlow()->GetNGInlineNodeData()->text_content;
     if (const LayoutObject* layout_object = cursor.CurrentLayoutObject()) {
-      if (const LayoutText* text = ToLayoutTextOrNull(layout_object))
-        return text->GetText().StripWhiteSpace();
-
+      if (layout_object->IsText()) {
+        return text_content
+            .Substring(
+                cursor.CurrentTextStartOffset(),
+                cursor.CurrentTextEndOffset() - cursor.CurrentTextStartOffset())
+            .StripWhiteSpace();
+      }
       if (const Element* element =
               DynamicTo<Element>(layout_object->GetNode())) {
         if (const AtomicString& id = element->GetIdAttribute())
@@ -51,6 +65,83 @@
                          NGInlineCursorTest,
                          testing::Bool());
 
+TEST_P(NGInlineCursorTest, ContainingLine) {
+  // TDOO(yosin): Remove <style> once NGFragmentItem don't do culled inline.
+  InsertStyleElement("a, b { background: gray; }");
+  NGInlineCursor cursor =
+      SetupCursor("<div id=root>abc<a id=target>def</a>ghi<br>xyz</div>");
+  const LayoutBlockFlow& block_flow = *cursor.GetLayoutBlockFlow();
+  NGInlineCursor line1(cursor);
+  ASSERT_TRUE(line1.IsLineBox());
+
+  NGInlineCursor line2(line1);
+  line2.MoveToNextSibling();
+  ASSERT_TRUE(line2.IsLineBox());
+
+  cursor.MoveTo(*block_flow.FirstChild());
+  cursor.MoveToContainingLine();
+  EXPECT_EQ(line1, cursor);
+
+  const LayoutObject& target = *GetLayoutObjectByElementId("target");
+  cursor.MoveTo(target);
+  cursor.MoveToContainingLine();
+  EXPECT_EQ(line1, cursor);
+
+  cursor.MoveTo(*target.SlowFirstChild());
+  cursor.MoveToContainingLine();
+  EXPECT_EQ(line1, cursor);
+
+  cursor.MoveTo(*block_flow.LastChild());
+  cursor.MoveToContainingLine();
+  EXPECT_EQ(line2, cursor);
+}
+
+TEST_P(NGInlineCursorTest, FirstChild) {
+  // TDOO(yosin): Remove <style> once NGFragmentItem don't do culled inline.
+  InsertStyleElement("a, b { background: gray; }");
+  NGInlineCursor cursor =
+      SetupCursor("<div id=root>abc<a>DEF<b>GHI</b></a>xyz</div>");
+  cursor.MoveToFirstChild();
+  EXPECT_EQ("abc", ToDebugString(cursor));
+  EXPECT_FALSE(cursor.TryToMoveToFirstChild());
+}
+
+TEST_P(NGInlineCursorTest, FirstChild2) {
+  // TDOO(yosin): Remove <style> once NGFragmentItem don't do culled inline.
+  InsertStyleElement("a, b { background: gray; }");
+  NGInlineCursor cursor = SetupCursor(
+      "<div id=root><b id=first>abc</b><a>DEF<b>GHI</b></a><a "
+      "id=last>xyz</a></div>");
+  cursor.MoveToFirstChild();
+  EXPECT_EQ("#first", ToDebugString(cursor));
+  cursor.MoveToFirstChild();
+  EXPECT_EQ("abc", ToDebugString(cursor));
+  EXPECT_FALSE(cursor.TryToMoveToFirstChild());
+}
+
+TEST_P(NGInlineCursorTest, LastChild) {
+  // TDOO(yosin): Remove <style> once NGFragmentItem don't do culled inline.
+  InsertStyleElement("a, b { background: gray; }");
+  NGInlineCursor cursor =
+      SetupCursor("<div id=root>abc<a>DEF<b>GHI</b></a>xyz</div>");
+  cursor.MoveToLastChild();
+  EXPECT_EQ("xyz", ToDebugString(cursor));
+  EXPECT_FALSE(cursor.TryToMoveToLastChild());
+}
+
+TEST_P(NGInlineCursorTest, LastChild2) {
+  // TDOO(yosin): Remove <style> once NGFragmentItem don't do culled inline.
+  InsertStyleElement("a, b { background: gray; }");
+  NGInlineCursor cursor = SetupCursor(
+      "<div id=root><b id=first>abc</b><a>DEF<b>GHI</b></a>"
+      "<a id=last>xyz</a></div>");
+  cursor.MoveToLastChild();
+  EXPECT_EQ("#last", ToDebugString(cursor));
+  cursor.MoveToLastChild();
+  EXPECT_EQ("xyz", ToDebugString(cursor));
+  EXPECT_FALSE(cursor.TryToMoveToLastChild());
+}
+
 TEST_P(NGInlineCursorTest, Next) {
   SetBodyInnerHTML(R"HTML(
     <style>
@@ -72,16 +163,69 @@
   LayoutBlockFlow* block_flow =
       To<LayoutBlockFlow>(GetLayoutObjectByElementId("root"));
   NGInlineCursor cursor(*block_flow);
-  Vector<String> list = ToDebugStringList(&cursor);
+  Vector<String> list = ToDebugStringList(cursor);
   EXPECT_THAT(list, ElementsAre("#linebox", "text1", "#span1", "text2",
                                 "#span2", "text3", "text4", "text5"));
 }
 
+TEST_P(NGInlineCursorTest, NextWithImage) {
+  NGInlineCursor cursor = SetupCursor("<div id=root>abc<img id=img>xyz</div>");
+  Vector<String> list = ToDebugStringList(cursor);
+  EXPECT_THAT(list, ElementsAre("#linebox", "abc", "#img", "xyz"));
+}
+
+TEST_P(NGInlineCursorTest, NextWithInlineBox) {
+  InsertStyleElement("b { display: inline-block; }");
+  NGInlineCursor cursor =
+      SetupCursor("<div id=root>abc<b id=ib>def</b>xyz</div>");
+  Vector<String> list = ToDebugStringList(cursor);
+  EXPECT_THAT(list, ElementsAre("#linebox", "abc", "#ib", "xyz"));
+}
+
+TEST_P(NGInlineCursorTest, NextForSameLayoutObject) {
+  NGInlineCursor cursor = SetupCursor("<pre id=root>abc\ndef\nghi</pre>");
+  cursor.MoveTo(*GetLayoutObjectByElementId("root")->SlowFirstChild());
+  Vector<String> list;
+  while (cursor) {
+    list.push_back(ToDebugString(cursor));
+    cursor.MoveToNextForSameLayoutObject();
+  }
+  EXPECT_THAT(list, ElementsAre("abc", "", "def", "", "ghi"));
+}
+
+TEST_P(NGInlineCursorTest, NextSibling) {
+  // TDOO(yosin): Remove <style> once NGFragmentItem don't do culled inline.
+  InsertStyleElement("a, b { background: gray; }");
+  NGInlineCursor cursor =
+      SetupCursor("<div id=root>abc<a>DEF<b>GHI</b></a>xyz</div>");
+  cursor.MoveToFirstChild();  // go to "abc"
+  Vector<String> list;
+  while (cursor) {
+    list.push_back(ToDebugString(cursor));
+    cursor.MoveToNextSibling();
+  }
+  EXPECT_THAT(list, ElementsAre("abc", "LayoutInline A", "xyz"));
+}
+
+TEST_P(NGInlineCursorTest, NextSibling2) {
+  // TDOO(yosin): Remove <style> once NGFragmentItem don't do culled inline.
+  InsertStyleElement("a, b { background: gray; }");
+  NGInlineCursor cursor =
+      SetupCursor("<div id=root><a>abc<b>def</b>xyz</a></div>");
+  cursor.MoveToFirstChild();  // go to <a>abc</a>
+  cursor.MoveToFirstChild();  // go to "abc"
+  Vector<String> list;
+  while (cursor) {
+    list.push_back(ToDebugString(cursor));
+    cursor.MoveToNextSibling();
+  }
+  EXPECT_THAT(list, ElementsAre("abc", "LayoutInline B", "xyz"));
+}
+
 TEST_P(NGInlineCursorTest, NextSkippingChildren) {
+  // TDOO(yosin): Remove <style> once NGFragmentItem don't do culled inline.
+  InsertStyleElement("span { background: gray; }");
   SetBodyInnerHTML(R"HTML(
-    <style>
-    span { background: gray; }
-    </style>
     <div id=root>
       text1
       <span id="span1">
@@ -121,7 +265,7 @@
   LayoutBlockFlow* block_flow =
       To<LayoutBlockFlow>(GetLayoutObjectByElementId("root"));
   NGInlineCursor cursor(*block_flow);
-  Vector<String> list = ToDebugStringList(&cursor);
+  Vector<String> list = ToDebugStringList(cursor);
   EXPECT_THAT(list, ElementsAre());
 }
 
diff --git a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc
index 60052f7..a7d551b 100644
--- a/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc
+++ b/third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.cc
@@ -53,7 +53,10 @@
 
   UpdateMarker();
 
-  if (old_style && old_style->ListStyleType() != StyleRef().ListStyleType())
+  if (old_style && (old_style->ListStyleType() != StyleRef().ListStyleType() ||
+                    (StyleRef().ListStyleType() == EListStyleType::kString &&
+                     old_style->ListStyleStringValue() !=
+                         StyleRef().ListStyleStringValue())))
     ListStyleTypeChanged();
 }
 
@@ -152,6 +155,11 @@
         LayoutListMarker::InlineMarginsForInside(style, IsMarkerImage());
     marker_style->SetMarginStart(Length::Fixed(margins.first));
     marker_style->SetMarginEnd(Length::Fixed(margins.second));
+    // Markers should have unicode-bidi:isolate according to the spec
+    // (https://drafts.csswg.org/css-lists/#ua-stylesheet).
+    // Note this is only relevant for inside markers with arbitrary strings.
+    if (style.ListStyleType() == EListStyleType::kString)
+      marker_style->SetUnicodeBidi(UnicodeBidi::kIsolate);
   } else {
     if (marker_ && !marker_->IsLayoutBlockFlow())
       DestroyMarker();
@@ -212,11 +220,15 @@
   switch (style.ListStyleType()) {
     case EListStyleType::kNone:
       return kStatic;
+    case EListStyleType::kString: {
+      text->Append(style.ListStyleStringValue());
+      return kStatic;
+    }
     case EListStyleType::kDisc:
     case EListStyleType::kCircle:
     case EListStyleType::kSquare:
       // value is ignored for these types
-      text->Append(list_marker_text::GetText(Style()->ListStyleType(), 0));
+      text->Append(list_marker_text::GetText(style.ListStyleType(), 0));
       if (format == kWithSuffix)
         text->Append(' ');
       return kSymbolValue;
@@ -273,9 +285,9 @@
     case EListStyleType::kUpperRoman:
     case EListStyleType::kUrdu: {
       int value = Value();
-      text->Append(list_marker_text::GetText(Style()->ListStyleType(), value));
+      text->Append(list_marker_text::GetText(style.ListStyleType(), value));
       if (format == kWithSuffix) {
-        text->Append(list_marker_text::Suffix(Style()->ListStyleType(), value));
+        text->Append(list_marker_text::Suffix(style.ListStyleType(), value));
         text->Append(' ');
       }
       return kOrdinalValue;
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index 8437734..13ee5d8 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -172,6 +172,7 @@
   }
   ip_address_space_ = params_->ip_address_space;
   grant_load_local_resources_ = params_->grant_load_local_resources;
+  force_fetch_cache_mode_ = params_->force_fetch_cache_mode;
 
   WebNavigationTimings& timings = params_->navigation_timings;
   if (!timings.input_start.is_null())
@@ -1104,6 +1105,11 @@
   return unreachable_url_;
 }
 
+const base::Optional<blink::mojom::FetchCacheMode>&
+DocumentLoader::ForceFetchCacheMode() const {
+  return force_fetch_cache_mode_;
+}
+
 bool DocumentLoader::WillLoadUrlAsEmpty(const KURL& url) {
   if (url.IsEmpty())
     return true;
diff --git a/third_party/blink/renderer/core/loader/document_loader.h b/third_party/blink/renderer/core/loader/document_loader.h
index f67f7fe..3810c6f 100644
--- a/third_party/blink/renderer/core/loader/document_loader.h
+++ b/third_party/blink/renderer/core/loader/document_loader.h
@@ -149,6 +149,8 @@
   const AtomicString& HttpMethod() const;
   const Referrer& GetReferrer() const;
   const KURL& UnreachableURL() const;
+  const base::Optional<blink::mojom::FetchCacheMode>& ForceFetchCacheMode()
+      const;
 
   void DidChangePerformanceTiming();
   void DidObserveLoadingBehavior(WebLoadingBehaviorFlag);
@@ -412,6 +414,7 @@
   network::mojom::IPAddressSpace ip_address_space_ =
       network::mojom::IPAddressSpace::kUnknown;
   bool grant_load_local_resources_ = false;
+  base::Optional<blink::mojom::FetchCacheMode> force_fetch_cache_mode_;
 
   // Params are saved in constructor and are cleared after StartLoading().
   // TODO(dgozman): remove once StartLoading is merged with constructor.
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 077c8ca8..0139af4 100644
--- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc
+++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
@@ -424,6 +424,11 @@
 
   if (GetResourceFetcherProperties().IsDetached())
     return;
+
+  DocumentLoader* document_loader = MasterDocumentLoader();
+  if (document_loader->ForceFetchCacheMode())
+    request.SetCacheMode(*document_loader->ForceFetchCacheMode());
+
   GetLocalFrameClient()->DispatchWillSendRequest(request);
   FrameScheduler* frame_scheduler = GetFrame()->GetFrameScheduler();
   if (!for_redirect && frame_scheduler) {
@@ -432,14 +437,13 @@
         WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant);
   }
 
-  probe::PrepareRequest(Probe(), MasterDocumentLoader(), request,
-                        initiator_info, resource_type);
+  probe::PrepareRequest(Probe(), document_loader, request, initiator_info,
+                        resource_type);
 
   // ServiceWorker hook ups.
-  if (MasterDocumentLoader()->GetServiceWorkerNetworkProvider()) {
+  if (document_loader->GetServiceWorkerNetworkProvider()) {
     WrappedResourceRequest webreq(request);
-    MasterDocumentLoader()->GetServiceWorkerNetworkProvider()->WillSendRequest(
-        webreq);
+    document_loader->GetServiceWorkerNetworkProvider()->WillSendRequest(webreq);
   }
 }
 
diff --git a/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h b/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h
index 262c798..35ad62f5 100644
--- a/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h
+++ b/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h
@@ -111,7 +111,8 @@
   }
 
   // CanvasRenderingContextHost implementation.
-  void FinalizeFrame() override {}
+  void PreFinalizeFrame() override {}
+  void PostFinalizeFrame() override {}
   void DetachContext() override { context_ = nullptr; }
   CanvasRenderingContext* RenderingContext() const override { return context_; }
 
diff --git a/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc b/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc
index 607a4f44..dc2531b 100644
--- a/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc
+++ b/third_party/blink/renderer/core/paint/html_canvas_painter_test.cc
@@ -85,7 +85,9 @@
   ASSERT_TRUE(element->IsAccelerated());
 
   // Force the page to paint.
-  element->FinalizeFrame();
+  element->PreFinalizeFrame();
+  context->FinalizeFrame();
+  element->PostFinalizeFrame();
   UpdateAllLifecyclePhasesForTest();
 
   // Fetch the layer associated with the <canvas>, and check that it was
diff --git a/third_party/blink/renderer/core/paint/list_marker_painter.cc b/third_party/blink/renderer/core/paint/list_marker_painter.cc
index 5c2c56f..3d0509e 100644
--- a/third_party/blink/renderer/core/paint/list_marker_painter.cc
+++ b/third_party/blink/renderer/core/paint/list_marker_painter.cc
@@ -155,6 +155,13 @@
     text_run.SetText(reversed_text.ToString());
   }
 
+  if (style_category == LayoutListMarker::ListStyleCategory::kStaticString) {
+    // Don't add a suffix.
+    context.DrawText(font, text_run_paint_info, text_origin, kInvalidDOMNodeId);
+    context.GetPaintController().SetTextPainted();
+    return;
+  }
+
   const UChar suffix =
       list_marker_text::Suffix(layout_list_marker_.StyleRef().ListStyleType(),
                                layout_list_marker_.ListItem()->Value());
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
index 240ea57c..525151f1 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.cc
@@ -407,6 +407,13 @@
   return false;
 }
 
+bool NGPaintFragment::IsEllipsis() const {
+  if (auto* text_fragment =
+          DynamicTo<NGPhysicalTextFragment>(PhysicalFragment()))
+    return text_fragment->IsEllipsis();
+  return false;
+}
+
 bool NGPaintFragment::HasSelfPaintingLayer() const {
   return PhysicalFragment().HasSelfPaintingLayer();
 }
diff --git a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
index 047e1ec..fbfdbe7c 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
+++ b/third_party/blink/renderer/core/paint/ng/ng_paint_fragment.h
@@ -130,13 +130,20 @@
   NGPaintFragment* NextSibling() const {
     return FirstAlive(next_sibling_.get());
   }
+  NGPaintFragment* NextForSameLayoutObject() const {
+    return next_for_same_layout_object_;
+  }
   ChildList Children() const { return ChildList(FirstChild()); }
+  bool IsEllipsis() const;
 
   // Note, as the name implies, |IsDescendantOfNotSelf| returns false for the
   // same object. This is different from |LayoutObject::IsDescendant| but is
   // same as |Node::IsDescendant|.
   bool IsDescendantOfNotSelf(const NGPaintFragment&) const;
 
+  // Returns the root box containing this.
+  const NGPaintFragment* Root() const;
+
   // Returns the first line box for a block-level container.
   NGPaintFragment* FirstLineBox() const;
 
diff --git a/third_party/blink/renderer/core/script/pending_script.cc b/third_party/blink/renderer/core/script/pending_script.cc
index 8af9e8f7..718dbb6 100644
--- a/third_party/blink/renderer/core/script/pending_script.cc
+++ b/third_party/blink/renderer/core/script/pending_script.cc
@@ -153,8 +153,6 @@
     // such scripts. https://crbug.com/721914
     UseCounter::Count(context_document,
                       WebFeature::kEvaluateScriptMovedBetweenElementDocuments);
-    Dispose();
-    return;
   }
 
   Script* script = GetSource(document_url);
diff --git a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5 b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
index 5b1ba87..dec1ac5 100644
--- a/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
+++ b/third_party/blink/renderer/core/style/computed_style_diff_functions.json5
@@ -215,7 +215,11 @@
         methods_to_diff: [
           {
             method: "ListStyleType()",
-            field_dependencies: ["list-style-type"]
+            field_dependencies: ["ListStyleType"]
+          },
+          {
+            method: "ListStyleStringValue()",
+            field_dependencies: ["ListStyleStringValue"]
           },
           {
             method: "ListStylePosition()",
diff --git a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
index 5b8ddb37..d30a5358 100644
--- a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
+++ b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
@@ -989,5 +989,37 @@
       default_value: "false",
       custom_compare: true,
     },
+    {
+      name: "ListStyleType",
+      inherited: true,
+      field_template: "keyword",
+      type_name: "EListStyleType",
+      keywords: [
+        "disc", "circle", "square", "decimal", "decimal-leading-zero",
+        "arabic-indic", "bengali", "cambodian", "khmer", "devanagari",
+        "gujarati", "gurmukhi", "kannada", "lao", "malayalam", "mongolian",
+        "myanmar", "oriya", "persian", "urdu", "telugu", "tibetan", "thai",
+        "lower-roman", "upper-roman", "lower-greek", "lower-alpha",
+        "lower-latin", "upper-alpha", "upper-latin", "cjk-earthly-branch",
+        "cjk-heavenly-stem", "ethiopic-halehame", "ethiopic-halehame-am",
+        "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "hangul",
+        "hangul-consonant", "korean-hangul-formal", "korean-hanja-formal",
+        "korean-hanja-informal", "hebrew", "armenian", "lower-armenian",
+        "upper-armenian", "georgian", "cjk-ideographic", "simp-chinese-formal",
+        "simp-chinese-informal", "trad-chinese-formal", "trad-chinese-informal",
+        "hiragana", "katakana", "hiragana-iroha", "katakana-iroha", "none",
+        "string",
+      ],
+      default_value: "disc",
+    },
+    {
+      name: "ListStyleStringValue",
+      inherited: true,
+      field_template: "external",
+      field_group: "*",
+      type_name: "AtomicString",
+      include_paths: ["third_party/blink/renderer/platform/wtf/text/atomic_string.h"],
+      default_value: "g_null_atom",
+    },
   ],
 }
diff --git a/third_party/blink/renderer/core/style/counter_content.h b/third_party/blink/renderer/core/style/counter_content.h
index 9bd35e96..49f86a5 100644
--- a/third_party/blink/renderer/core/style/counter_content.h
+++ b/third_party/blink/renderer/core/style/counter_content.h
@@ -37,7 +37,9 @@
   CounterContent(const AtomicString& identifier,
                  EListStyleType style,
                  const AtomicString& separator)
-      : identifier_(identifier), list_style_(style), separator_(separator) {}
+      : identifier_(identifier), list_style_(style), separator_(separator) {
+    DCHECK_NE(style, EListStyleType::kString);
+  }
 
   const AtomicString& Identifier() const { return identifier_; }
   EListStyleType ListStyle() const { return list_style_; }
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
index d009512..f903048 100644
--- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
+++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -380,9 +380,9 @@
   }
   String condition_string;
   SMILTime offset;
-  if (pos == kNotFound)
+  if (pos == kNotFound) {
     condition_string = parse_string;
-  else {
+  } else {
     condition_string = parse_string.Left(pos).StripWhiteSpace();
     String offset_string = parse_string.Substring(pos + 1).StripWhiteSpace();
     offset = ParseOffsetValue(offset_string);
@@ -397,9 +397,9 @@
 
   String base_id;
   String name_string;
-  if (pos == kNotFound)
+  if (pos == kNotFound) {
     name_string = condition_string;
-  else {
+  } else {
     base_id = condition_string.Left(pos);
     name_string = condition_string.Substring(pos + 1);
   }
diff --git a/third_party/blink/renderer/core/testing/page_test_base.cc b/third_party/blink/renderer/core/testing/page_test_base.cc
index 8a4a4d8..40d7b51 100644
--- a/third_party/blink/renderer/core/testing/page_test_base.cc
+++ b/third_party/blink/renderer/core/testing/page_test_base.cc
@@ -13,12 +13,27 @@
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/frame/local_frame_view.h"
 #include "third_party/blink/renderer/core/frame/settings.h"
+#include "third_party/blink/renderer/core/html/html_collection.h"
 #include "third_party/blink/renderer/core/html/html_element.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
 #include "third_party/blink/renderer/platform/wtf/shared_buffer.h"
 
 namespace blink {
 
+namespace {
+
+Element* GetOrCreateElement(ContainerNode* parent,
+                            const HTMLQualifiedName& tag_name) {
+  HTMLCollection* elements = parent->getElementsByTagNameNS(
+      tag_name.NamespaceURI(), tag_name.LocalName());
+  if (!elements->IsEmpty())
+    return elements->item(0);
+  return parent->ownerDocument()->CreateRawElement(
+      tag_name, CreateElementFlags::ByCreateElement());
+}
+
+}  // namespace
+
 PageTestBase::PageTestBase() = default;
 
 PageTestBase::~PageTestBase() = default;
@@ -140,6 +155,16 @@
   UpdateAllLifecyclePhasesForTest();
 }
 
+void PageTestBase::InsertStyleElement(const std::string& style_rules) {
+  Element* const head =
+      GetOrCreateElement(&GetDocument(), html_names::kHeadTag);
+  DCHECK_EQ(head, GetOrCreateElement(&GetDocument(), html_names::kHeadTag));
+  Element* const style = GetDocument().CreateRawElement(
+      html_names::kStyleTag, CreateElementFlags::ByCreateElement());
+  style->setTextContent(String(style_rules.data(), style_rules.size()));
+  head->appendChild(style);
+}
+
 void PageTestBase::NavigateTo(const KURL& url,
                               const String& feature_policy_header,
                               const String& csp_header) {
diff --git a/third_party/blink/renderer/core/testing/page_test_base.h b/third_party/blink/renderer/core/testing/page_test_base.h
index b15cbd79..0a76fef 100644
--- a/third_party/blink/renderer/core/testing/page_test_base.h
+++ b/third_party/blink/renderer/core/testing/page_test_base.h
@@ -41,6 +41,10 @@
   void SetBodyInnerHTML(const String&);
   void SetHtmlInnerHTML(const std::string&);
 
+  // Insert STYLE element with |style_rules|, no need to have "<style>", into
+  // HEAD.
+  void InsertStyleElement(const std::string& style_rules);
+
   // Navigate to |url| providing an empty response but
   // URL and security origin of the Document will be set to |url|.
   void NavigateTo(const KURL& url,
diff --git a/third_party/blink/renderer/devtools/BUILD.gn b/third_party/blink/renderer/devtools/BUILD.gn
index 3874d856..c2aaa570 100644
--- a/third_party/blink/renderer/devtools/BUILD.gn
+++ b/third_party/blink/renderer/devtools/BUILD.gn
@@ -156,7 +156,6 @@
     "front_end/console/module.json",
     "front_end/console_counters/errorWarningCounter.css",
     "front_end/console_counters/module.json",
-    "front_end/console_counters/WarningErrorCounter.js",
     "front_end/console_test_runner/ConsoleTestRunner.js",
     "front_end/console_test_runner/module.json",
     "front_end/cookie_table/CookiesTable.js",
@@ -259,11 +258,6 @@
     "front_end/event_listeners/eventListenersView.css",
     "front_end/event_listeners/EventListenersView.js",
     "front_end/event_listeners/module.json",
-    "front_end/extensions/ExtensionAPI.js",
-    "front_end/extensions/ExtensionPanel.js",
-    "front_end/extensions/ExtensionServer.js",
-    "front_end/extensions/ExtensionTraceProvider.js",
-    "front_end/extensions/ExtensionView.js",
     "front_end/extensions/module.json",
     "front_end/extensions_test_runner/ExtensionsNetworkTestRunner.js",
     "front_end/extensions_test_runner/ExtensionsTestRunner.js",
@@ -820,6 +814,14 @@
   all_devtools_files += lighthouse_locale_files
 
   all_devtools_modules = [
+    "front_end/console_counters/console_counters.js",
+    "front_end/console_counters/WarningErrorCounter.js",
+    "front_end/extensions/extensions.js",
+    "front_end/extensions/ExtensionAPI.js",
+    "front_end/extensions/ExtensionPanel.js",
+    "front_end/extensions/ExtensionServer.js",
+    "front_end/extensions/ExtensionTraceProvider.js",
+    "front_end/extensions/ExtensionView.js",
     "front_end/browser_sdk/browser_sdk.js",
     "front_end/browser_sdk/LogManager.js",
     "front_end/persistence/persistence.js",
@@ -1210,6 +1212,14 @@
   ]
 
   copied_devtools_modules = [
+    "$resources_out_dir/console_counters/console_counters.js",
+    "$resources_out_dir/console_counters/WarningErrorCounter.js",
+    "$resources_out_dir/extensions/extensions.js",
+    "$resources_out_dir/extensions/ExtensionAPI.js",
+    "$resources_out_dir/extensions/ExtensionPanel.js",
+    "$resources_out_dir/extensions/ExtensionServer.js",
+    "$resources_out_dir/extensions/ExtensionTraceProvider.js",
+    "$resources_out_dir/extensions/ExtensionView.js",
     "$resources_out_dir/browser_sdk/browser_sdk.js",
     "$resources_out_dir/browser_sdk/LogManager.js",
     "$resources_out_dir/persistence/persistence.js",
diff --git a/third_party/blink/renderer/devtools/front_end/console_counters/WarningErrorCounter.js b/third_party/blink/renderer/devtools/front_end/console_counters/WarningErrorCounter.js
index b218fdc..f515742 100644
--- a/third_party/blink/renderer/devtools/front_end/console_counters/WarningErrorCounter.js
+++ b/third_party/blink/renderer/devtools/front_end/console_counters/WarningErrorCounter.js
@@ -6,9 +6,9 @@
  * @implements {UI.ToolbarItem.Provider}
  * @unrestricted
  */
-ConsoleCounters.WarningErrorCounter = class {
+export default class WarningErrorCounter {
   constructor() {
-    ConsoleCounters.WarningErrorCounter._instanceForTest = this;
+    WarningErrorCounter._instanceForTest = this;
 
     const countersWrapper = createElement('div');
     this._toolbarItem = new UI.ToolbarItem(countersWrapper);
@@ -146,4 +146,13 @@
   item() {
     return this._toolbarItem;
   }
-};
+}
+
+/* Legacy exported object */
+self.ConsoleCounters = self.ConsoleCounters || {};
+
+/* Legacy exported object */
+ConsoleCounters = ConsoleCounters || {};
+
+/** @constructor */
+ConsoleCounters.WarningErrorCounter = WarningErrorCounter;
diff --git a/third_party/blink/renderer/devtools/front_end/console_counters/console_counters.js b/third_party/blink/renderer/devtools/front_end/console_counters/console_counters.js
new file mode 100644
index 0000000..4bfc9441
--- /dev/null
+++ b/third_party/blink/renderer/devtools/front_end/console_counters/console_counters.js
@@ -0,0 +1,9 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import * as WarningErrorCounter from './WarningErrorCounter.js';
+
+export {
+  WarningErrorCounter,
+};
diff --git a/third_party/blink/renderer/devtools/front_end/console_counters/module.json b/third_party/blink/renderer/devtools/front_end/console_counters/module.json
index 420d1af..71b2494 100644
--- a/third_party/blink/renderer/devtools/front_end/console_counters/module.json
+++ b/third_party/blink/renderer/devtools/front_end/console_counters/module.json
@@ -12,7 +12,9 @@
     "ui",
     "sdk"
   ],
-  "scripts": [
+  "scripts": [],
+  "modules": [
+    "console_counters.js",
     "WarningErrorCounter.js"
   ],
   "resources": [
diff --git a/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewCompletedView.js b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewCompletedView.js
index 3053364..4665b54 100644
--- a/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewCompletedView.js
+++ b/third_party/blink/renderer/devtools/front_end/css_overview/CSSOverviewCompletedView.js
@@ -192,17 +192,20 @@
     return blockFragment;
   }
 
-  _getNonTransparentColorStrings(colors) {
-    return Array.from(colors)
-        .map(colorText => {
-          const color = Common.Color.parse(colorText);
-          if (color.rgba()[3] === 0) {
-            return;
-          }
+  _getNonTransparentColorStrings(srcColors) {
+    const colors = [];
+    for (const colorText of Array.from(srcColors)) {
+      const color = Common.Color.parse(colorText);
+      if (color.rgba()[3] === 0) {
+        continue;
+      }
 
-          return color;
-        })
-        .filter(color => !!color);
+      colors.push(color);
+    }
+
+    return colors.sort((colorA, colorB) => {
+      return Common.Color.luminance(colorB.rgba()) - Common.Color.luminance(colorA.rgba());
+    });
   }
 
   setOverviewData(data) {
diff --git a/third_party/blink/renderer/devtools/front_end/extensions/ExtensionAPI.js b/third_party/blink/renderer/devtools/front_end/extensions/ExtensionAPI.js
index 9f02d8ac..f89fd79 100644
--- a/third_party/blink/renderer/devtools/front_end/extensions/ExtensionAPI.js
+++ b/third_party/blink/renderer/devtools/front_end/extensions/ExtensionAPI.js
@@ -28,8 +28,6 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* eslint-disable indent */
-
 function defineCommonExtensionSymbols(apiPrivate) {
   if (!apiPrivate.panels) {
     apiPrivate.panels = {};
@@ -95,7 +93,8 @@
  * @param {function(!Object, !Object)} testHook
  * @suppressGlobalPropertiesCheck
  */
-function injectedExtensionAPI(extensionInfo, inspectedTabId, themeName, keysToForward, testHook, injectedScriptId) {
+self.injectedExtensionAPI = function(
+    extensionInfo, inspectedTabId, themeName, keysToForward, testHook, injectedScriptId) {
   const keysToForwardSet = new Set(keysToForward);
   const chrome = window.chrome || {};
   const devtools_descriptor = Object.getOwnPropertyDescriptor(chrome, 'devtools');
@@ -827,7 +826,7 @@
     window.webInspector = coreAPI;
   }
   testHook(extensionServer, coreAPI);
-}
+};
 
 /**
  * @param {!ExtensionDescriptor} extensionInfo
@@ -843,6 +842,15 @@
     testHook = () => {};
   }
   return '(function(injectedScriptId){ ' + defineCommonExtensionSymbols.toString() + ';' +
-      '(' + injectedExtensionAPI.toString() + ')(' + argumentsJSON + ',' + testHook + ', injectedScriptId);' +
+      '(' + self.injectedExtensionAPI.toString() + ')(' + argumentsJSON + ',' + testHook + ', injectedScriptId);' +
       '})';
 };
+
+/* Legacy exported object */
+self.Extensions = self.Extensions || {};
+
+/* Legacy exported object */
+Extensions = Extensions || {};
+
+Extensions.extensionAPI = {};
+defineCommonExtensionSymbols(Extensions.extensionAPI);
\ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/extensions/ExtensionPanel.js b/third_party/blink/renderer/devtools/front_end/extensions/ExtensionPanel.js
index 90534e4..d849ee1 100644
--- a/third_party/blink/renderer/devtools/front_end/extensions/ExtensionPanel.js
+++ b/third_party/blink/renderer/devtools/front_end/extensions/ExtensionPanel.js
@@ -31,7 +31,7 @@
  * @implements {UI.Searchable}
  * @unrestricted
  */
-Extensions.ExtensionPanel = class extends UI.Panel {
+export default class ExtensionPanel extends UI.Panel {
   /**
    * @param {!Extensions.ExtensionServer} server
    * @param {string} panelName
@@ -116,12 +116,12 @@
   supportsRegexSearch() {
     return false;
   }
-};
+}
 
 /**
  * @unrestricted
  */
-Extensions.ExtensionButton = class {
+export class ExtensionButton {
   /**
    * @param {!Extensions.ExtensionServer} server
    * @param {string} id
@@ -161,12 +161,12 @@
   toolbarButton() {
     return this._toolbarButton;
   }
-};
+}
 
 /**
  * @unrestricted
  */
-Extensions.ExtensionSidebarPane = class extends UI.SimpleView {
+export class ExtensionSidebarPane extends UI.SimpleView {
   /**
    * @param {!Extensions.ExtensionServer} server
    * @param {string} panelName
@@ -296,4 +296,19 @@
       callback();
     });
   }
-};
+}
+
+/* Legacy exported object */
+self.Extensions = self.Extensions || {};
+
+/* Legacy exported object */
+Extensions = Extensions || {};
+
+/** @constructor */
+Extensions.ExtensionPanel = ExtensionPanel;
+
+/** @constructor */
+Extensions.ExtensionButton = ExtensionButton;
+
+/** @constructor */
+Extensions.ExtensionSidebarPane = ExtensionSidebarPane;
\ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js b/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js
index 91e2dc7..fd73648 100644
--- a/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js
+++ b/third_party/blink/renderer/devtools/front_end/extensions/ExtensionServer.js
@@ -31,7 +31,7 @@
 /**
  * @unrestricted
  */
-Extensions.ExtensionServer = class extends Common.Object {
+export default class ExtensionServer extends Common.Object {
   /**
    * @suppressGlobalPropertiesCheck
    */
@@ -46,7 +46,7 @@
     this._requests = {};
     this._lastRequestId = 0;
     this._registeredExtensions = {};
-    this._status = new Extensions.ExtensionStatus();
+    this._status = new ExtensionStatus();
     /** @type {!Array<!Extensions.ExtensionSidebarPane>} */
     this._sidebarPanes = [];
     /** @type {!Array<!Extensions.ExtensionTraceProvider>} */
@@ -263,7 +263,7 @@
     const page = this._expandResourcePath(port._extensionOrigin, message.page);
     let persistentId = port._extensionOrigin + message.title;
     persistentId = persistentId.replace(/\s/g, '');
-    const panelView = new Extensions.ExtensionServerPanelView(
+    const panelView = new ExtensionServerPanelView(
         persistentId, message.title, new Extensions.ExtensionPanel(this, persistentId, id, page));
     this._clientObjects[id] = panelView;
     UI.inspectorView.addPanel(panelView);
@@ -273,7 +273,7 @@
   _onShowPanel(message) {
     let panelViewId = message.id;
     const panelView = this._clientObjects[message.id];
-    if (panelView && panelView instanceof Extensions.ExtensionServerPanelView) {
+    if (panelView && panelView instanceof ExtensionServerPanelView) {
       panelViewId = panelView.viewId();
     }
     UI.inspectorView.showPanel(panelViewId);
@@ -281,7 +281,7 @@
 
   _onCreateToolbarButton(message, port) {
     const panelView = this._clientObjects[message.panel];
-    if (!panelView || !(panelView instanceof Extensions.ExtensionServerPanelView)) {
+    if (!panelView || !(panelView instanceof ExtensionServerPanelView)) {
       return this._status.E_NOTFOUND(message.panel);
     }
     const button = new Extensions.ExtensionButton(
@@ -330,7 +330,7 @@
     const sidebar = new Extensions.ExtensionSidebarPane(this, message.panel, message.title, id);
     this._sidebarPanes.push(sidebar);
     this._clientObjects[id] = sidebar;
-    this.dispatchEventToListeners(Extensions.ExtensionServer.Events.SidebarPaneAdded, sidebar);
+    this.dispatchEventToListeners(Events.SidebarPaneAdded, sidebar);
 
     return this._status.OK();
   }
@@ -358,7 +358,7 @@
     }
 
     /**
-     * @this {Extensions.ExtensionServer}
+     * @this {ExtensionServer}
      */
     function callback(error) {
       const result = error ? this._status.E_FAILED(error) : this._status.OK();
@@ -432,7 +432,7 @@
      * @param {?Protocol.Error} error
      * @param {?SDK.RemoteObject} object
      * @param {boolean} wasThrown
-     * @this {Extensions.ExtensionServer}
+     * @this {ExtensionServer}
      */
     function callback(error, object, wasThrown) {
       let result;
@@ -474,7 +474,7 @@
     const resources = new Map();
 
     /**
-     * @this {Extensions.ExtensionServer}
+     * @this {ExtensionServer}
      */
     function pushResourceData(contentProvider) {
       if (!resources.has(contentProvider.contentURL())) {
@@ -522,7 +522,7 @@
   _onSetResourceContent(message, port) {
     /**
      * @param {?Protocol.Error} error
-     * @this {Extensions.ExtensionServer}
+     * @this {ExtensionServer}
      */
     function callbackWrapper(error) {
       const response = error ? this._status.E_FAILED(error) : this._status.OK();
@@ -566,7 +566,7 @@
         port._extensionOrigin, message.id, message.categoryName, message.categoryTooltip);
     this._clientObjects[message.id] = provider;
     this._traceProviders.push(provider);
-    this.dispatchEventToListeners(Extensions.ExtensionServer.Events.TraceProviderAdded, provider);
+    this.dispatchEventToListeners(Events.TraceProviderAdded, provider);
   }
 
   /**
@@ -627,14 +627,14 @@
         SDK.NetworkManager.Events.RequestFinished, this._notifyRequestFinished);
 
     /**
-     * @this {Extensions.ExtensionServer}
+     * @this {ExtensionServer}
      */
     function onElementsSubscriptionStarted() {
       UI.context.addFlavorChangeListener(SDK.DOMNode, this._notifyElementsSelectionChanged, this);
     }
 
     /**
-     * @this {Extensions.ExtensionServer}
+     * @this {ExtensionServer}
      */
     function onElementsSubscriptionStopped() {
       UI.context.removeFlavorChangeListener(SDK.DOMNode, this._notifyElementsSelectionChanged, this);
@@ -709,9 +709,8 @@
       const extensionOrigin = originMatch[1];
       if (!this._registeredExtensions[extensionOrigin]) {
         // See ExtensionAPI.js for details.
-        const injectedAPI = buildExtensionAPIInjectedScript(
-            extensionInfo, this._inspectedTabId, UI.themeSupport.themeName(),
-            UI.shortcutRegistry.globalShortcutKeys(),
+        const injectedAPI = self.buildExtensionAPIInjectedScript(
+            extensionInfo, this._inspectedTabId, UI.themeSupport.themeName(), UI.shortcutRegistry.globalShortcutKeys(),
             Extensions.extensionServer['_extensionAPITestHook']);
         Host.InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, injectedAPI);
         this._registeredExtensions[extensionOrigin] = {name: name};
@@ -798,7 +797,7 @@
 
   _registerResourceContentCommittedHandler(handler) {
     /**
-     * @this {Extensions.ExtensionServer}
+     * @this {ExtensionServer}
      */
     function addFirstEventListener() {
       Workspace.workspace.addEventListener(Workspace.Workspace.Events.WorkingCopyCommittedByUser, handler, this);
@@ -806,7 +805,7 @@
     }
 
     /**
-     * @this {Extensions.ExtensionServer}
+     * @this {ExtensionServer}
      */
     function removeLastEventListener() {
       Workspace.workspace.setHasResourceContentTrackingExtensions(false);
@@ -947,10 +946,10 @@
       callback(null, result.object || null, !!result.exceptionDetails);
     }
   }
-};
+}
 
 /** @enum {symbol} */
-Extensions.ExtensionServer.Events = {
+export const Events = {
   SidebarPaneAdded: Symbol('SidebarPaneAdded'),
   TraceProviderAdded: Symbol('TraceProviderAdded')
 };
@@ -958,7 +957,7 @@
 /**
  * @unrestricted
  */
-Extensions.ExtensionServerPanelView = class extends UI.SimpleView {
+export class ExtensionServerPanelView extends UI.SimpleView {
   /**
    * @param {string} name
    * @param {string} title
@@ -985,12 +984,12 @@
   widget() {
     return /** @type {!Promise.<!UI.Widget>} */ (Promise.resolve(this._panel));
   }
-};
+}
 
 /**
  * @unrestricted
  */
-Extensions.ExtensionStatus = class {
+export class ExtensionStatus {
   constructor() {
     /**
      * @param {string} code
@@ -1016,15 +1015,30 @@
     this.E_PROTOCOLERROR = makeStatus.bind(null, 'E_PROTOCOLERROR', 'Inspector protocol error: %s');
     this.E_FAILED = makeStatus.bind(null, 'E_FAILED', 'Operation failed: %s');
   }
-};
+}
+
+/* Legacy exported object */
+self.Extensions = self.Extensions || {};
+
+/* Legacy exported object */
+Extensions = Extensions || {};
+
+/** @constructor */
+Extensions.ExtensionServer = ExtensionServer;
+
+/** @enum {symbol} */
+Extensions.ExtensionServer.Events = Events;
+
+/** @constructor */
+Extensions.ExtensionServerPanelView = ExtensionServerPanelView;
+
+/** @constructor */
+Extensions.ExtensionStatus = ExtensionStatus;
 
 /**
  * @typedef {{code: string, description: string, details: !Array.<*>}}
  */
 Extensions.ExtensionStatus.Record;
 
-Extensions.extensionAPI = {};
-defineCommonExtensionSymbols(Extensions.extensionAPI);
-
-/** @type {!Extensions.ExtensionServer} */
+/** @type {!ExtensionServer} */
 Extensions.extensionServer;
diff --git a/third_party/blink/renderer/devtools/front_end/extensions/ExtensionTraceProvider.js b/third_party/blink/renderer/devtools/front_end/extensions/ExtensionTraceProvider.js
index db77fa94..afb42415 100644
--- a/third_party/blink/renderer/devtools/front_end/extensions/ExtensionTraceProvider.js
+++ b/third_party/blink/renderer/devtools/front_end/extensions/ExtensionTraceProvider.js
@@ -5,7 +5,7 @@
 /**
  * @unrestricted
  */
-Extensions.ExtensionTraceProvider = class {
+export default class ExtensionTraceProvider {
   /**
    * @param {string} extensionOrigin
    * @param {string} id
@@ -20,10 +20,10 @@
   }
 
   /**
-   * @param {!Extensions.TracingSession} session
+   * @param {!TracingSession} session
    */
   start(session) {
-    const sessionId = String(++Extensions.ExtensionTraceProvider._lastSessionId);
+    const sessionId = String(++_lastSessionId);
     Extensions.extensionServer.startTraceRecording(this._id, sessionId, session);
   }
 
@@ -51,19 +51,32 @@
   persistentIdentifier() {
     return `${this._extensionOrigin}/${this._categoryName}`;
   }
-};
+}
 
-Extensions.ExtensionTraceProvider._lastSessionId = 0;
+export let _lastSessionId = 0;
 
 /**
  * @interface
  */
-Extensions.TracingSession = function() {};
-
-Extensions.TracingSession.prototype = {
+export class TracingSession {
   /**
    * @param {string} url
    * @param {number} timeOffsetMicroseconds
    */
-  complete: function(url, timeOffsetMicroseconds) {}
-};
+  complete(url, timeOffsetMicroseconds) {
+  }
+}
+
+/* Legacy exported object */
+self.Extensions = self.Extensions || {};
+
+/* Legacy exported object */
+Extensions = Extensions || {};
+
+/** @constructor */
+Extensions.ExtensionTraceProvider = ExtensionTraceProvider;
+
+Extensions.ExtensionTraceProvider._lastSessionId = _lastSessionId;
+
+/** @interface */
+Extensions.TracingSession = TracingSession;
diff --git a/third_party/blink/renderer/devtools/front_end/extensions/ExtensionView.js b/third_party/blink/renderer/devtools/front_end/extensions/ExtensionView.js
index 032585e..d7dc6f0 100644
--- a/third_party/blink/renderer/devtools/front_end/extensions/ExtensionView.js
+++ b/third_party/blink/renderer/devtools/front_end/extensions/ExtensionView.js
@@ -31,7 +31,7 @@
 /**
  * @unrestricted
  */
-Extensions.ExtensionView = class extends UI.Widget {
+export default class ExtensionView extends UI.Widget {
   /**
    * @param {!Extensions.ExtensionServer} server
    * @param {string} id
@@ -84,12 +84,12 @@
       this._server.notifyViewShown(this._id, this._frameIndex);
     }
   }
-};
+}
 
 /**
  * @unrestricted
  */
-Extensions.ExtensionNotifierView = class extends UI.VBox {
+export class ExtensionNotifierView extends UI.VBox {
   /**
    * @param {!Extensions.ExtensionServer} server
    * @param {string} id
@@ -114,4 +114,16 @@
   willHide() {
     this._server.notifyViewHidden(this._id);
   }
-};
+}
+
+/* Legacy exported object */
+self.Extensions = self.Extensions || {};
+
+/* Legacy exported object */
+Extensions = Extensions || {};
+
+/** @constructor */
+Extensions.ExtensionView = ExtensionView;
+
+/** @constructor */
+Extensions.ExtensionNotifierView = ExtensionNotifierView;
\ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/extensions/extensions.js b/third_party/blink/renderer/devtools/front_end/extensions/extensions.js
new file mode 100644
index 0000000..71c229ec
--- /dev/null
+++ b/third_party/blink/renderer/devtools/front_end/extensions/extensions.js
@@ -0,0 +1,16 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import './ExtensionAPI.js';
+import * as ExtensionPanel from './ExtensionPanel.js';
+import * as ExtensionServer from './ExtensionServer.js';
+import * as ExtensionTraceProvider from './ExtensionTraceProvider.js';
+import * as ExtensionView from './ExtensionView.js';
+
+export {
+  ExtensionPanel,
+  ExtensionServer,
+  ExtensionTraceProvider,
+  ExtensionView,
+};
diff --git a/third_party/blink/renderer/devtools/front_end/extensions/module.json b/third_party/blink/renderer/devtools/front_end/extensions/module.json
index 3d825f3..3695a25 100644
--- a/third_party/blink/renderer/devtools/front_end/extensions/module.json
+++ b/third_party/blink/renderer/devtools/front_end/extensions/module.json
@@ -4,7 +4,9 @@
         "browser_sdk",
         "common"
     ],
-    "scripts": [
+    "scripts": [],
+    "modules": [
+        "extensions.js",
         "ExtensionAPI.js",
         "ExtensionTraceProvider.js",
         "ExtensionServer.js",
diff --git a/third_party/blink/renderer/devtools/front_end/formatter/ScriptFormatter.js b/third_party/blink/renderer/devtools/front_end/formatter/ScriptFormatter.js
index 7b02690a..da6b77f 100644
--- a/third_party/blink/renderer/devtools/front_end/formatter/ScriptFormatter.js
+++ b/third_party/blink/renderer/devtools/front_end/formatter/ScriptFormatter.js
@@ -132,13 +132,11 @@
   originalToFormatted(lineNumber, columnNumber) {},
 
   /**
-   * TODO(1005708): Remove the offset parameter once end positions of inline CSS is known.
    * @param {number} lineNumber
    * @param {number=} columnNumber
-   * @param {number=} offset
    * @return {!Array.<number>}
    */
-  formattedToOriginal(lineNumber, columnNumber, offset) {}
+  formattedToOriginal(lineNumber, columnNumber) {}
 };
 
 /**
@@ -157,14 +155,12 @@
   }
 
   /**
-   * TODO(1005708): Remove the offset parameter once end positions of inline CSS is known.
    * @override
    * @param {number} lineNumber
    * @param {number=} columnNumber
-   * @param {number=} offset
    * @return {!Array.<number>}
    */
-  formattedToOriginal(lineNumber, columnNumber, offset) {
+  formattedToOriginal(lineNumber, columnNumber) {
     return [lineNumber, columnNumber || 0];
   }
 };
@@ -200,18 +196,16 @@
   }
 
   /**
-   * TODO(chromium:1005708): Remove the offset parameter once end positions of inline CSS is known.
    * @override
    * @param {number} lineNumber
    * @param {number=} columnNumber
-   * @param {number=} offset
    * @return {!Array.<number>}
    */
-  formattedToOriginal(lineNumber, columnNumber, offset) {
+  formattedToOriginal(lineNumber, columnNumber) {
     const formattedPosition =
         Formatter.Formatter.locationToPosition(this._formattedLineEndings, lineNumber, columnNumber || 0);
     const originalPosition = this._convertPosition(this._mapping.formatted, this._mapping.original, formattedPosition);
-    return Formatter.Formatter.positionToLocation(this._originalLineEndings, (originalPosition || 0) + (offset || 0));
+    return Formatter.Formatter.positionToLocation(this._originalLineEndings, originalPosition || 0);
   }
 
   /**
diff --git a/third_party/blink/renderer/devtools/front_end/root.js b/third_party/blink/renderer/devtools/front_end/root.js
index 2459c51..d0e4750f 100644
--- a/third_party/blink/renderer/devtools/front_end/root.js
+++ b/third_party/blink/renderer/devtools/front_end/root.js
@@ -16,4 +16,6 @@
 import './bindings/bindings.js';
 import './components/components.js';
 import './persistence/persistence.js';
-import './browser_sdk/browser_sdk.js';
\ No newline at end of file
+import './browser_sdk/browser_sdk.js';
+import './extensions/extensions.js';
+import './console_counters/console_counters.js';
\ No newline at end of file
diff --git a/third_party/blink/renderer/devtools/front_end/sdk/CSSModel.js b/third_party/blink/renderer/devtools/front_end/sdk/CSSModel.js
index 67c5305..3fece49 100644
--- a/third_party/blink/renderer/devtools/front_end/sdk/CSSModel.js
+++ b/third_party/blink/renderer/devtools/front_end/sdk/CSSModel.js
@@ -101,7 +101,9 @@
     for (let index = endIndex - 1;
          index >= 0 && headers[index].startLine === last.startLine && headers[index].startColumn === last.startColumn;
          --index) {
-      locations.push(new CSSLocation(headers[index], lineNumber, columnNumber));
+      if (headers[index].containsLocation(lineNumber, columnNumber)) {
+        locations.push(new SDK.CSSLocation(headers[index], lineNumber, columnNumber));
+      }
     }
 
 
@@ -929,4 +931,4 @@
 SDK.CSSModel.RuleUsage;
 
 /** @typedef {{backgroundColors: ?Array<string>, computedFontSize: string, computedFontWeight: string}} */
-SDK.CSSModel.ContrastInfo;
\ No newline at end of file
+SDK.CSSModel.ContrastInfo;
diff --git a/third_party/blink/renderer/devtools/front_end/sdk/CSSStyleSheetHeader.js b/third_party/blink/renderer/devtools/front_end/sdk/CSSStyleSheetHeader.js
index 635b970..023e97b 100644
--- a/third_party/blink/renderer/devtools/front_end/sdk/CSSStyleSheetHeader.js
+++ b/third_party/blink/renderer/devtools/front_end/sdk/CSSStyleSheetHeader.js
@@ -22,6 +22,8 @@
     this.isInline = payload.isInline;
     this.startLine = payload.startLine;
     this.startColumn = payload.startColumn;
+    this.endLine = payload.endLine;
+    this.endColumn = payload.endColumn;
     this.contentLength = payload.length;
     if (payload.ownerNode) {
       this.ownerNode = new SDK.DeferredDOMNode(cssModel.target(), payload.ownerNode);
@@ -104,19 +106,14 @@
   /**
    * Checks whether the position is in this style sheet. Assumes that the
    * position's columnNumber is consistent with line endings.
-   * TODO(chromium:1005708): Ensure that this object knows its end position,
-   * and remove {line,column}NumberOfCSSEnd parameters.
    * @param {number} lineNumber
    * @param {number} columnNumber
-   * @param {number} lineNumberOfCSSEnd
-   * @param {number} columnNumberOfCSSEnd
    * @return {boolean}
    */
-  containsLocation(lineNumber, columnNumber, lineNumberOfCSSEnd, columnNumberOfCSSEnd) {
+  containsLocation(lineNumber, columnNumber) {
     const afterStart =
         (lineNumber === this.startLine && columnNumber >= this.startColumn) || lineNumber > this.startLine;
-    const beforeEnd =
-        lineNumber < lineNumberOfCSSEnd || (lineNumber === lineNumberOfCSSEnd && columnNumber <= columnNumberOfCSSEnd);
+    const beforeEnd = lineNumber < this.endLine || (lineNumber === this.endLine && columnNumber <= this.endColumn);
     return afterStart && beforeEnd;
   }
 
diff --git a/third_party/blink/renderer/devtools/front_end/sources/SourceFormatter.js b/third_party/blink/renderer/devtools/front_end/sources/SourceFormatter.js
index 668b10a..4634c63 100644
--- a/third_party/blink/renderer/devtools/front_end/sources/SourceFormatter.js
+++ b/third_party/blink/renderer/devtools/front_end/sources/SourceFormatter.js
@@ -276,19 +276,9 @@
     }
     const [originalLine, originalColumn] =
         formatData.mapping.formattedToOriginal(uiLocation.lineNumber, uiLocation.columnNumber);
-    const headers = formatData.originalSourceCode[this._headersSymbol];
-    const locations = [];
-    for (const header of headers) {
-      // TODO(chromium:1005708): Remove this computation and use the end location from `header` once the back-end provides it.
-      const [formattedStartLine, formattedStartColumn] =
-          formatData.mapping.originalToFormatted(header.startLine, header.startColumn);
-      const [originalEndLine, originalEndColumn] =
-          formatData.mapping.formattedToOriginal(formattedStartLine, formattedStartColumn, header.contentLength);
-      if (header.containsLocation(originalLine, originalColumn, originalEndLine, originalEndColumn)) {
-        locations.push(new SDK.CSSLocation(header, originalLine, originalColumn));
-      }
-    }
-    return locations;
+    const headers = formatData.originalSourceCode[this._headersSymbol].filter(
+        header => header.containsLocation(originalLine, originalColumn));
+    return headers.map(header => new SDK.CSSLocation(header, originalLine, originalColumn));
   }
 
   /**
diff --git a/third_party/blink/renderer/devtools/scripts/build/generate_devtools_extension_api.py b/third_party/blink/renderer/devtools/scripts/build/generate_devtools_extension_api.py
index 6d5728bf..0eb10bc5c 100755
--- a/third_party/blink/renderer/devtools/scripts/build/generate_devtools_extension_api.py
+++ b/third_party/blink/renderer/devtools/scripts/build/generate_devtools_extension_api.py
@@ -42,7 +42,7 @@
         var tabId;
         var extensionInfo = {};
         var extensionServer;
-        platformExtensionAPI(injectedExtensionAPI("remote-" + window.parent.frames.length));
+        platformExtensionAPI(self.injectedExtensionAPI("remote-" + window.parent.frames.length));
     })();""")
 
 
diff --git a/third_party/blink/renderer/devtools/scripts/migration/refactor-folder-to-es-modules.sh b/third_party/blink/renderer/devtools/scripts/migration/refactor-folder-to-es-modules.sh
index 3fa1f37..562b436 100755
--- a/third_party/blink/renderer/devtools/scripts/migration/refactor-folder-to-es-modules.sh
+++ b/third_party/blink/renderer/devtools/scripts/migration/refactor-folder-to-es-modules.sh
@@ -49,6 +49,10 @@
   echo "import * as $FILE from './$FILE.js';" >> $MODULE_FILE
 done
 
+# Add module entrypoint to GN variables
+sed -i -e "s/all\_devtools\_modules = \[/all\_devtools\_modules = \[ \"front\_end\/$1\/$1.js\"\,/" "$BUILD_GN_PATH"
+sed -i -e "s/copied\_devtools\_modules = \[/copied\_devtools\_modules = \[ \"\$resources\_out\_dir\/$1\/$1.js\"\,/" "$BUILD_GN_PATH"
+
 echo "" >> $MODULE_FILE
 echo "export {" >> $MODULE_FILE
 
diff --git a/third_party/blink/renderer/devtools/tests/front_end/common/ParsedURL.ts b/third_party/blink/renderer/devtools/tests/front_end/common/ParsedURL.ts
new file mode 100644
index 0000000..130db27
--- /dev/null
+++ b/third_party/blink/renderer/devtools/tests/front_end/common/ParsedURL.ts
@@ -0,0 +1,421 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+const {assert} = chai;
+
+import {default as ParsedURL} from '../../../front_end/common/ParsedURL.js';
+
+describe('Parsed URL', () => {
+  it('recognizes valid URLs', () => {
+    const parsedUrl = new ParsedURL('http://www.example.com/');
+    assert.isTrue(parsedUrl.isValid, 'the URL should be valid');
+  });
+
+  it('recognizes the URL elements', () => {
+    const parsedUrl = new ParsedURL('http://username@www.example.com:8080/testing/test?isTest=true#testFragment');
+    assert.isTrue(parsedUrl.isValid, 'the URL should be valid');
+    assert.equal(
+        parsedUrl.url, 'http://username@www.example.com:8080/testing/test?isTest=true#testFragment',
+        'URL value is incorrect');
+    assert.equal(parsedUrl.scheme, 'http', 'URL scheme is incorrect');
+    assert.equal(parsedUrl.user, 'username', 'URL user is incorrect');
+    assert.equal(parsedUrl.host, 'www.example.com', 'URL host is incorrect');
+    assert.equal(parsedUrl.port, '8080', 'URL port is incorrect');
+    assert.equal(parsedUrl.path, '/testing/test', 'URL path is incorrect');
+    assert.equal(parsedUrl.queryParams, 'isTest=true', 'URL query params are incorrect');
+    assert.equal(parsedUrl.fragment, 'testFragment', 'URL fragment is incorrect');
+    assert.equal(parsedUrl.folderPathComponents, '/testing', 'URL folder path components are incorrect');
+    assert.equal(parsedUrl.lastPathComponent, 'test', 'URL last path component is incorrect');
+  });
+
+  it('recognizes a valid blob URL', () => {
+    const parsedUrl = new ParsedURL('blob:http://www.example.com/');
+    assert.isTrue(parsedUrl.isValid, 'the URL should be valid');
+    assert.equal(parsedUrl.scheme, 'blob', 'the URL scheme is not blob');
+    assert.equal(parsedUrl._blobInnerScheme, 'http', 'the URL inner scheme is not http');
+  });
+
+  it('parses a URL with no path', () => {
+    const parsedUrl = new ParsedURL('http://www.example.com');
+    assert.isTrue(parsedUrl.isValid, 'the URL should be valid');
+    assert.equal(parsedUrl.path, '/', 'path is not a single slash ("/")');
+  });
+
+  it('parses a data URL', () => {
+    const parsedUrl = new ParsedURL('data:test');
+    assert.isFalse(parsedUrl.isValid, 'the URL should not be valid');
+    assert.equal(parsedUrl.scheme, 'data', 'the URL scheme is not data');
+  });
+
+  it('recognizes an invalid blob URL', () => {
+    const parsedUrl = new ParsedURL('blob:test');
+    assert.isFalse(parsedUrl.isValid, 'the URL should not be valid');
+    assert.equal(parsedUrl.scheme, 'blob', 'the URL scheme is not blob');
+  });
+
+  it('recognizes an invalid blank URL', () => {
+    const parsedUrl = new ParsedURL('about:blank');
+    assert.isFalse(parsedUrl.isValid, 'the URL should not be valid');
+    assert.equal(parsedUrl.scheme, 'about', 'the URL scheme is not blob');
+  });
+
+  it('recognizes an invalid URL', () => {
+    const parsedUrl = new ParsedURL('abc');
+    assert.isFalse(parsedUrl.isValid, 'the URL should not be valid');
+    assert.equal(parsedUrl.url, 'abc', 'URL value is incorrect');
+  });
+
+  it('converts platform path to a URL that does not start with "file://"', () => {
+    const platformPathTest = 'usr/lib';
+    const convertedUrl = ParsedURL.platformPathToURL(platformPathTest);
+    assert.equal(convertedUrl, 'file:///usr/lib', 'URL was not converted correctly');
+  });
+
+  it('converts platform path to a URL that does not start with "file://" but starts with a slash ("/")', () => {
+    const platformPathTest = '/usr/lib';
+    const convertedUrl = ParsedURL.platformPathToURL(platformPathTest);
+    assert.equal(convertedUrl, 'file:///usr/lib', 'URL was not converted correctly');
+  });
+
+  it('converts platform path to a URL that starts with "file://"', () => {
+    const platformPathTest = 'file://usr/lib';
+    const convertedUrl = ParsedURL.platformPathToURL(platformPathTest);
+    assert.equal(convertedUrl, 'file://usr/lib', 'URL was not converted correctly');
+  });
+
+  it('converts URL to a platform path that starts with "file://"', () => {
+    const urlTest = 'file://usr/lib';
+    const convertedUrl = ParsedURL.urlToPlatformPath(urlTest);
+    assert.equal(convertedUrl, 'usr/lib', 'URL was not converted successfully');
+  });
+
+  it('converts URL to a platform path that starts with "file:///" on Windows', () => {
+    const urlTest = 'file:///usr/lib';
+    const convertedUrl = ParsedURL.urlToPlatformPath(urlTest, true);
+    assert.equal(convertedUrl, 'usr\\lib', 'URL was not converted successfully');
+  });
+
+  it('converts URL with a hash to a URL without a hash', () => {
+    const urlTest = 'http://www.example.com#test';
+    const convertedUrl = ParsedURL.urlWithoutHash(urlTest);
+    assert.equal(convertedUrl, 'http://www.example.com', 'URL was not converted successfully');
+  });
+
+  it('returns URL without a hash as it is', () => {
+    const urlTest = 'http://www.example.com';
+    const convertedUrl = ParsedURL.urlWithoutHash(urlTest);
+    assert.equal(convertedUrl, urlTest, 'URL was changed');
+  });
+
+  it('extracts the path from a valid URL', () => {
+    const urlTest = 'http://www.example.com/test/path';
+    const extractedPath = ParsedURL.extractPath(urlTest);
+    assert.equal(extractedPath, '/test/path', 'path extracted incorrectly');
+  });
+
+  it('returns an empty string as a path if the URL is not valid', () => {
+    const urlTest = 'www.example.com/test/path';
+    const extractedPath = ParsedURL.extractPath(urlTest);
+    assert.equal(extractedPath, '', 'did not return an empty path');
+  });
+
+  it('extracts the origin from a valid URL', () => {
+    const urlTest = 'http://www.example.com/test/path';
+    const extractedOrigin = ParsedURL.extractOrigin(urlTest);
+    assert.equal(extractedOrigin, 'http://www.example.com', 'origin extracted incorrectly');
+  });
+
+  it('returns an empty string as a origin if the URL is not valid', () => {
+    const urlTest = 'www.example.com/test/path';
+    const extractedOrigin = ParsedURL.extractOrigin(urlTest);
+    assert.equal(extractedOrigin, '', 'did not return an empty path');
+  });
+
+  it('extracts the extension from a valid URL with a hash', () => {
+    const urlTest = 'http://www.example.com/test/testFile.html#testHash';
+    const extractedExt = ParsedURL.extractExtension(urlTest);
+    assert.equal(extractedExt, 'html', 'extension extracted incorrectly');
+  });
+
+  it('extracts the extension from a valid URL with a question mark', () => {
+    const urlTest = 'http://www.example.com/test/testFile.html?testParam=t';
+    const extractedExt = ParsedURL.extractExtension(urlTest);
+    assert.equal(extractedExt, 'html', 'extension extracted incorrectly');
+  });
+
+  it('extracts the extension from a valid URL that does not have slashes', () => {
+    const urlTest = 'testFile.html';
+    const extractedExt = ParsedURL.extractExtension(urlTest);
+    assert.equal(extractedExt, 'html', 'extension extracted incorrectly');
+  });
+
+  it('extracts the extension from a valid URL that has a percent sign', () => {
+    const urlTest = 'http://www.example.com/test/path.html%20';
+    const extractedExt = ParsedURL.extractExtension(urlTest);
+    assert.equal(extractedExt, 'html', 'extension extracted incorrectly');
+  });
+
+  it('returns an empty string when trying to extract extension from an invalid URL', () => {
+    const urlTest = 'http://html';
+    const extractedExt = ParsedURL.extractExtension(urlTest);
+    assert.equal(extractedExt, '', 'extension extracted incorrectly');
+  });
+
+  it('is able to extract name from a valid URL', () => {
+    const urlTest = 'http://www.example.com/test/path.html';
+    const extractedName = ParsedURL.extractName(urlTest);
+    assert.equal(extractedName, 'path.html', 'name extracted incorrectly');
+  });
+
+  it('is able to extract name from a string without a slash', () => {
+    const urlTest = 'path.html';
+    const extractedName = ParsedURL.extractName(urlTest);
+    assert.equal(extractedName, 'path.html', 'name extracted incorrectly');
+  });
+
+  it('is able to extract name from a valid URL with a query', () => {
+    const urlTest = 'http://www.example.com/test/path.html?testParam=t';
+    const extractedName = ParsedURL.extractName(urlTest);
+    assert.equal(extractedName, 'path.html', 'name extracted incorrectly');
+  });
+
+  it('is able to extract name from a string without a slash and with a query', () => {
+    const urlTest = 'path.html?testParam=t';
+    const extractedName = ParsedURL.extractName(urlTest);
+    assert.equal(extractedName, 'path.html', 'name extracted incorrectly');
+  });
+
+  it('uses the completeURL function to return a data URL as it is', () => {
+    const hrefTest = 'data:http://www.example.com';
+    const baseUrlTest = 'www.example.com';
+    const completeUrl = ParsedURL.completeURL(baseUrlTest, hrefTest);
+    assert.equal(completeUrl, hrefTest, 'complete URL is not returned correctly');
+  });
+
+  it('uses the completeURL function to return a blob URL as it is', () => {
+    const hrefTest = 'blob:http://www.example.com';
+    const baseUrlTest = 'www.example.com';
+    const completeUrl = ParsedURL.completeURL(baseUrlTest, hrefTest);
+    assert.equal(completeUrl, hrefTest, 'complete URL is not returned correctly');
+  });
+
+  it('uses the completeURL function to return a javascript URL as it is', () => {
+    const hrefTest = 'javascript:http://www.example.com';
+    const baseUrlTest = 'www.example.com';
+    const completeUrl = ParsedURL.completeURL(baseUrlTest, hrefTest);
+    assert.equal(completeUrl, hrefTest, 'complete URL is not returned correctly');
+  });
+
+  it('uses the completeURL function to return a mailto URL as it is', () => {
+    const hrefTest = 'mailto:http://www.example.com';
+    const baseUrlTest = 'www.example.com';
+    const completeUrl = ParsedURL.completeURL(baseUrlTest, hrefTest);
+    assert.equal(completeUrl, hrefTest, 'complete URL is not returned correctly');
+  });
+
+  it('uses the completeURL function to return absolute URLs as-is', () => {
+    const hrefTest = 'http://www.example.com';
+    const baseUrlTest = 'www.example.com';
+    const completeUrl = ParsedURL.completeURL(baseUrlTest, hrefTest);
+    assert.equal(completeUrl, hrefTest, 'complete URL is not returned correctly');
+  });
+
+  it('uses the completeURL function to return null for invalid href and invalid base URL', () => {
+    const hrefTest = 'www.example.com';
+    const baseUrlTest = 'www.example.com';
+    const completeUrl = ParsedURL.completeURL(baseUrlTest, hrefTest);
+    assert.equal(completeUrl, null, 'complete URL is not returned correctly');
+  });
+
+  it('uses the completeURL function to return the href if the base URL is a data URL', () => {
+    const hrefTest = 'www.example.com';
+    const baseUrlTest = 'data://www.example.com';
+    const completeUrl = ParsedURL.completeURL(baseUrlTest, hrefTest);
+    assert.equal(completeUrl, hrefTest, 'complete URL is not returned correctly');
+  });
+
+  it('uses the completeURL function to return the href with scheme if the base URL was valid and the href scheme was dropped',
+     () => {
+       const hrefTest = '//www.example.com';
+       const baseUrlTest = 'http://www.example.com/';
+       const completeUrl = ParsedURL.completeURL(baseUrlTest, hrefTest);
+       assert.equal(completeUrl, 'http:' + hrefTest, 'complete URL is not returned correctly');
+     });
+
+  it('uses the completeURL function to resolve an empty href to a base URL without fragment', () => {
+    const hrefTest = '';
+    const baseUrlTest = 'http://www.example.com/?testParam=t';
+    const completeUrl = ParsedURL.completeURL(baseUrlTest, hrefTest);
+    assert.equal(completeUrl, baseUrlTest, 'complete URL is not returned correctly');
+  });
+
+  it('uses the completeURL function to resolve a fragment href to a base URL with fragment', () => {
+    const hrefTest = '#testFragment';
+    const baseUrlTest = 'http://www.example.com/?testParam=t';
+    const completeUrl = ParsedURL.completeURL(baseUrlTest, hrefTest);
+    assert.equal(completeUrl, baseUrlTest + hrefTest, 'complete URL is not returned correctly');
+  });
+
+  it('uses the completeURL function to resolve a parameters href to a base URL with the parameters from the href while the base URL has parameters',
+     () => {
+       const hrefTest = '?hrefParams=t';
+       const baseUrlTest = 'http://www.example.com/?testParam=t';
+       const completeUrl = ParsedURL.completeURL(baseUrlTest, hrefTest);
+       assert.equal(completeUrl, 'http://www.example.com/' + hrefTest, 'complete URL is not returned correctly');
+     });
+
+  it('uses the completeURL function to resolve a parameters href to a base URL with the parameters from the href while the base URL does not have parameters',
+     () => {
+       const hrefTest = '?hrefParams=t';
+       const baseUrlTest = 'http://www.example.com/';
+       const completeUrl = ParsedURL.completeURL(baseUrlTest, hrefTest);
+       assert.equal(completeUrl, baseUrlTest + hrefTest, 'complete URL is not returned correctly');
+     });
+
+  it('uses the splitLineAndColumn function to return undefined line and column numbers if the URL does not contain any',
+     () => {
+       const stringTest = 'http://www.example.com';
+       const splitResult = ParsedURL.splitLineAndColumn(stringTest);
+       assert.equal(splitResult.url, 'http://www.example.com', 'URL is not correct');
+       assert.isUndefined(splitResult.lineNumber, 'line number is not undefined');
+       assert.isUndefined(splitResult.columnNumber, 'column number is not undefined');
+     });
+
+  it('uses the splitLineAndColumn function to return the line and column numbers if the URL contains them', () => {
+    const stringTest = 'http://www.example.com:15:20';
+    const splitResult = ParsedURL.splitLineAndColumn(stringTest);
+    assert.equal(splitResult.url, 'http://www.example.com', 'URL is not correct');
+    assert.equal(splitResult.lineNumber, 14, 'line number is incorrect');
+    assert.equal(splitResult.columnNumber, 19, 'column number is incorrect');
+  });
+
+  it('uses the splitLineAndColumn function to return the line and column numbers if the URL contains them and has a port number',
+     () => {
+       const stringTest = 'http://www.example.com:8080:15:20';
+       const splitResult = ParsedURL.splitLineAndColumn(stringTest);
+       assert.equal(splitResult.url, 'http://www.example.com:8080', 'URL is not correct');
+       assert.equal(splitResult.lineNumber, 14, 'line number is incorrect');
+       assert.equal(splitResult.columnNumber, 19, 'column number is incorrect');
+     });
+
+  it('uses the isRelativeURL function to return true if the URL is relative', () => {
+    const urlTest = '/test/path';
+    const isRelativeResult = ParsedURL.isRelativeURL(urlTest);
+    assert.isTrue(isRelativeResult);
+  });
+
+  it('uses the isRelativeURL function to return false if the URL is not relative', () => {
+    const urlTest = 'http://www.example.com/test/path';
+    const isRelativeResult = ParsedURL.isRelativeURL(urlTest);
+    assert.isFalse(isRelativeResult);
+  });
+
+  it('uses the displayName function to return the name if it exists for a URL', () => {
+    const parsedUrl = new ParsedURL('http://www.example.com');
+    assert.equal(parsedUrl.displayName, 'www.example.com/', 'name returned is incorrect');
+  });
+
+  it('uses the displayName function to return the name for a data URL', () => {
+    const parsedUrl = new ParsedURL('data:www.example.com');
+    assert.equal(parsedUrl.displayName, 'data:www.example.com', 'name returned is incorrect');
+  });
+
+  it('uses the displayName function to return the name for a blob URL', () => {
+    const parsedUrl = new ParsedURL('blob:www.example.com');
+    assert.equal(parsedUrl.displayName, 'blob:www.example.com', 'name returned is incorrect');
+  });
+
+  it('uses the displayName function to return the name for an about:blank URL', () => {
+    const parsedUrl = new ParsedURL('about:blank');
+    assert.equal(parsedUrl.displayName, 'about:blank', 'name returned is incorrect');
+  });
+
+  it('uses the displayName function to return the name for a URL with a last path component', () => {
+    const parsedUrl = new ParsedURL('http://www.example.com/test');
+    assert.equal(parsedUrl.displayName, 'test', 'name returned is incorrect');
+  });
+
+  it('uses the displayName function to return the name for a a slash', () => {
+    const parsedUrl = new ParsedURL('/');
+    assert.equal(parsedUrl.displayName, '/', 'name returned is incorrect');
+  });
+
+  it('uses the displayName function to return the name for a URL that already has a display name set', () => {
+    const parsedUrl = new ParsedURL('http://www.example.com');
+    assert.equal(parsedUrl.displayName, 'www.example.com/', 'name returned is incorrect');
+    assert.equal(parsedUrl.displayName, 'www.example.com/', 'name returned is incorrect');
+  });
+
+  it('uses the dataURLDisplayName function to return data URL display name if it is not already set', () => {
+    const parsedUrl = new ParsedURL('http://www.example.com');
+    assert.equal(parsedUrl.dataURLDisplayName(), '', 'data URL display name is returned incorrectly');
+  });
+
+  it('uses the dataURLDisplayName function to return data URL display name if it is already set', () => {
+    const parsedUrl = new ParsedURL('data:http://www.example.com');
+    assert.equal(
+        parsedUrl.dataURLDisplayName(), 'data:http://www.exa…', 'data URL display name is returned incorrectly');
+    assert.equal(
+        parsedUrl.dataURLDisplayName(), 'data:http://www.exa…', 'data URL display name is returned incorrectly');
+  });
+
+  it('uses the lastPathComponentWithFragment function to return for a URL without a path', () => {
+    const parsedUrl = new ParsedURL('http://www.example.com');
+    assert.equal(
+        parsedUrl.lastPathComponentWithFragment(), '', 'last path component with fragmen returned is incorrect');
+  });
+
+  it('uses the lastPathComponentWithFragment function to return for a URL with a path', () => {
+    const parsedUrl = new ParsedURL('http://www.example.com/test/path');
+    assert.equal(
+        parsedUrl.lastPathComponentWithFragment(), 'path', 'last path component with fragmen returned is incorrect');
+  });
+
+  it('uses the lastPathComponentWithFragment function to return for a URL with a path and a fragment', () => {
+    const parsedUrl = new ParsedURL('http://www.example.com/test/path#testFragment');
+    assert.equal(
+        parsedUrl.lastPathComponentWithFragment(), 'path#testFragment',
+        'last path component with fragmen returned is incorrect');
+  });
+
+  it('returns the domain for a data URL', () => {
+    const parsedUrl = new ParsedURL('data:http://www.example.com');
+    assert.equal(parsedUrl.domain(), 'data:', 'domain returned was incorrect');
+  });
+
+  it('returns the domain for an http URL without a port', () => {
+    const parsedUrl = new ParsedURL('http://www.example.com');
+    assert.equal(parsedUrl.domain(), 'www.example.com', 'domain returned was incorrect');
+  });
+
+  it('returns the domain for an http URL with a port', () => {
+    const parsedUrl = new ParsedURL('http://www.example.com:8080');
+    assert.equal(parsedUrl.domain(), 'www.example.com:8080', 'domain returned was incorrect');
+  });
+
+  it('returns the security origin for a data URL', () => {
+    const parsedUrl = new ParsedURL('data:http://www.example.com');
+    assert.equal(parsedUrl.securityOrigin(), 'data:', 'security origin returned was incorrect');
+  });
+
+  it('returns the security origin for a blob URL', () => {
+    const parsedUrl = new ParsedURL('blob:http://www.example.com');
+    assert.equal(parsedUrl.securityOrigin(), 'http://www.example.com', 'security origin returned was incorrect');
+  });
+
+  it('returns the security origin for an http URL', () => {
+    const parsedUrl = new ParsedURL('http://www.example.com');
+    assert.equal(parsedUrl.securityOrigin(), 'http://www.example.com', 'security origin returned was incorrect');
+  });
+
+  it('returns the url without scheme for a URL that has a scheme', () => {
+    const parsedUrl = new ParsedURL('http://www.example.com');
+    assert.equal(parsedUrl.urlWithoutScheme(), 'www.example.com', 'URL without scheme returned was incorrect');
+  });
+
+  it('returns the url without scheme for a URL that does not have a scheme', () => {
+    const parsedUrl = new ParsedURL('www.example.com');
+    assert.equal(parsedUrl.urlWithoutScheme(), 'www.example.com', 'URL without scheme returned was incorrect');
+  });
+});
diff --git a/third_party/blink/renderer/modules/DEPS b/third_party/blink/renderer/modules/DEPS
index 01c7bc15..04ac798 100644
--- a/third_party/blink/renderer/modules/DEPS
+++ b/third_party/blink/renderer/modules/DEPS
@@ -5,6 +5,7 @@
     "+mojo/public/cpp/bindings",
     "+services/network/public/cpp/shared_url_loader_factory.h",
     "+services/service_manager/public/mojom/interface_provider.mojom-blink.h",
+    "+services/service_manager/public/mojom/interface_provider.mojom-blink-forward.h",
     "+services/viz/public/mojom/hit_test/hit_test_region_list.mojom-blink.h",
     "+third_party/blink/public/common",
     "+third_party/blink/public/web",
diff --git a/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.h b/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.h
index b75220c..52681c2 100644
--- a/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.h
+++ b/third_party/blink/renderer/modules/cache_storage/inspector_cache_storage_agent.h
@@ -9,7 +9,7 @@
 
 #include "base/macros.h"
 #include "mojo/public/cpp/bindings/remote.h"
-#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
+#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink-forward.h"
 #include "third_party/blink/renderer/core/inspector/inspector_base_agent.h"
 #include "third_party/blink/renderer/core/inspector/protocol/CacheStorage.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
index c620424..9c11f4b 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
@@ -672,6 +672,7 @@
 }
 
 void CanvasRenderingContext2D::FinalizeFrame() {
+  TRACE_EVENT0("blink", "CanvasRenderingContext2D::FinalizeFrame");
   if (canvas() && canvas()->GetCanvas2DLayerBridge())
     canvas()->GetCanvas2DLayerBridge()->FinalizeFrame();
   usage_counters_.num_frames_since_reset++;
diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
index feb9aba..a63454be 100644
--- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
+++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d_test.cc
@@ -116,7 +116,9 @@
   }
   void DrawSomething() {
     CanvasElement().DidDraw();
-    CanvasElement().FinalizeFrame();
+    CanvasElement().PreFinalizeFrame();
+    Context2d()->FinalizeFrame();
+    CanvasElement().PostFinalizeFrame();
     // Grabbing an image forces a flush
     CanvasElement().Snapshot(kBackBuffer, kPreferAcceleration);
   }
diff --git a/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc b/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc
index 89efe0d..7ba7ea2 100644
--- a/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc
+++ b/third_party/blink/renderer/modules/canvas/htmlcanvas/html_canvas_element_module_test.cc
@@ -145,7 +145,9 @@
             EXPECT_NE(shared_quad_state_list.front()->are_contents_opaque,
                       context_alpha);
           })));
-  canvas_element().FinalizeFrame();
+  canvas_element().PreFinalizeFrame();
+  context_->FinalizeFrame();
+  canvas_element().PostFinalizeFrame();
   platform->RunUntilIdle();
 }
 
diff --git a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h
index 79b6cd2..7f6ce85 100644
--- a/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h
+++ b/third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context_base.h
@@ -43,7 +43,7 @@
   void SetIsHidden(bool) override {}
   bool isContextLost() const override { return false; }
   void SetImage(ImageBitmap*);
-  // The acceleration hing here is ignored as GetImage(AccelerationHint) only
+  // The acceleration hint here is ignored as GetImage(AccelerationHint) only
   // calls to image_layer_bridge->GetImage(), without giving it a hint
   scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) final;
   // This function resets the internal image resource to a image of the same
diff --git a/third_party/blink/renderer/modules/compression/BUILD.gn b/third_party/blink/renderer/modules/compression/BUILD.gn
index 0f8e7b1..04b392be 100644
--- a/third_party/blink/renderer/modules/compression/BUILD.gn
+++ b/third_party/blink/renderer/modules/compression/BUILD.gn
@@ -2,8 +2,12 @@
 
 blink_modules_sources("compression") {
   sources = [
+    "compression_stream.cc",
+    "compression_stream.h",
     "decompression_stream.cc",
     "decompression_stream.h",
+    "deflate_transformer.cc",
+    "deflate_transformer.h",
     "inflate_transformer.cc",
     "inflate_transformer.h",
   ]
diff --git a/third_party/blink/renderer/modules/compression/compression_stream.cc b/third_party/blink/renderer/modules/compression/compression_stream.cc
new file mode 100644
index 0000000..5959a7b
--- /dev/null
+++ b/third_party/blink/renderer/modules/compression/compression_stream.cc
@@ -0,0 +1,53 @@
+// Copyright 2019 The Chromium 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/compression/compression_stream.h"
+
+#include "third_party/blink/renderer/modules/compression/deflate_transformer.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+
+namespace blink {
+
+CompressionStream* CompressionStream::Create(ScriptState* script_state,
+                                             const AtomicString& format,
+                                             ExceptionState& exception_state) {
+  return MakeGarbageCollected<CompressionStream>(script_state, format,
+                                                 exception_state);
+}
+
+ReadableStream* CompressionStream::readable() const {
+  return transform_->Readable();
+}
+
+WritableStream* CompressionStream::writable() const {
+  return transform_->Writable();
+}
+
+void CompressionStream::Trace(Visitor* visitor) {
+  visitor->Trace(transform_);
+  ScriptWrappable::Trace(visitor);
+}
+
+CompressionStream::CompressionStream(ScriptState* script_state,
+                                     const AtomicString& format,
+                                     ExceptionState& exception_state)
+    : transform_(MakeGarbageCollected<TransformStream>()) {
+  DeflateTransformer::Format deflate_format =
+      DeflateTransformer::Format::kDeflate;
+  if (format == "gzip") {
+    deflate_format = DeflateTransformer::Format::kGzip;
+  } else if (format != "deflate") {
+    exception_state.ThrowTypeError("Unsupported format");
+    return;
+  }
+
+  // default level is hardcoded for now.
+  // TODO(arenevier): Make level configurable
+  const int deflate_level = 6;
+  transform_->Init(MakeGarbageCollected<DeflateTransformer>(
+                       script_state, deflate_format, deflate_level),
+                   script_state, exception_state);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/compression/compression_stream.h b/third_party/blink/renderer/modules/compression/compression_stream.h
new file mode 100644
index 0000000..4a96737
--- /dev/null
+++ b/third_party/blink/renderer/modules/compression/compression_stream.h
@@ -0,0 +1,36 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_COMPRESSION_STREAM_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_COMPRESSION_STREAM_H_
+
+#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
+#include "third_party/blink/renderer/core/streams/transform_stream.h"
+#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
+
+namespace blink {
+
+class CompressionStream final : public ScriptWrappable {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  static CompressionStream* Create(ScriptState*,
+                                   const AtomicString&,
+                                   ExceptionState&);
+  CompressionStream(ScriptState*, const AtomicString&, ExceptionState&);
+
+  ReadableStream* readable() const;
+  WritableStream* writable() const;
+
+  void Trace(Visitor*) override;
+
+ private:
+  const Member<TransformStream> transform_;
+
+  DISALLOW_COPY_AND_ASSIGN(CompressionStream);
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_COMPRESSION_STREAM_H_
diff --git a/third_party/blink/renderer/modules/compression/compression_stream.idl b/third_party/blink/renderer/modules/compression/compression_stream.idl
new file mode 100644
index 0000000..91e1ee03
--- /dev/null
+++ b/third_party/blink/renderer/modules/compression/compression_stream.idl
@@ -0,0 +1,10 @@
+[
+    Exposed=(Window,Worker),
+    Constructor(DOMString format),
+    ConstructorCallWith=ScriptState,
+    RuntimeEnabled=CompressionStreams,
+    RaisesException=Constructor
+] interface CompressionStream {
+    readonly attribute ReadableStream readable;
+    readonly attribute WritableStream writable;
+};
diff --git a/third_party/blink/renderer/modules/compression/decompression_stream.cc b/third_party/blink/renderer/modules/compression/decompression_stream.cc
index e0b77a2..cb1fbc4b 100644
--- a/third_party/blink/renderer/modules/compression/decompression_stream.cc
+++ b/third_party/blink/renderer/modules/compression/decompression_stream.cc
@@ -29,17 +29,17 @@
                                          const AtomicString& format,
                                          ExceptionState& exception_state)
     : transform_(MakeGarbageCollected<TransformStream>()) {
-  InflateTransformer::Algorithm algorithm =
-      InflateTransformer::Algorithm::kDeflate;
+  InflateTransformer::Format deflate_format =
+      InflateTransformer::Format::kDeflate;
   if (format == "gzip") {
-    algorithm = InflateTransformer::Algorithm::kGzip;
+    deflate_format = InflateTransformer::Format::kGzip;
   } else if (format != "deflate") {
     exception_state.ThrowTypeError("Unsupported format");
     return;
   }
 
   transform_->Init(
-      MakeGarbageCollected<InflateTransformer>(script_state, algorithm),
+      MakeGarbageCollected<InflateTransformer>(script_state, deflate_format),
       script_state, exception_state);
 }
 
diff --git a/third_party/blink/renderer/modules/compression/deflate_transformer.cc b/third_party/blink/renderer/modules/compression/deflate_transformer.cc
new file mode 100644
index 0000000..3abfcc85
--- /dev/null
+++ b/third_party/blink/renderer/modules/compression/deflate_transformer.cc
@@ -0,0 +1,118 @@
+// Copyright 2019 The Chromium 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/compression/deflate_transformer.h"
+
+#include <string.h>
+#include <algorithm>
+#include <limits>
+
+#include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_uint8_array.h"
+#include "third_party/blink/renderer/core/streams/transform_stream_default_controller_interface.h"
+#include "third_party/blink/renderer/core/streams/transform_stream_transformer.h"
+#include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/bindings/to_v8.h"
+#include "v8/include/v8.h"
+
+namespace blink {
+
+DeflateTransformer::DeflateTransformer(ScriptState* script_state,
+                                       Format format,
+                                       int level)
+    : script_state_(script_state), out_buffer_(kBufferSize) {
+  DCHECK(level >= 1 && level <= 9);
+  memset(&stream_, 0, sizeof(z_stream));
+  constexpr int kWindowBits = 15;
+  constexpr int kUseGzip = 16;
+  int err;
+  switch (format) {
+    case Format::kDeflate:
+      err = deflateInit2(&stream_, level, Z_DEFLATED, kWindowBits, 8,
+                         Z_DEFAULT_STRATEGY);
+      break;
+    case Format::kGzip:
+      err = deflateInit2(&stream_, level, Z_DEFLATED, kWindowBits + kUseGzip, 8,
+                         Z_DEFAULT_STRATEGY);
+      break;
+  }
+  DCHECK_EQ(Z_OK, err);
+}
+
+DeflateTransformer::~DeflateTransformer() {
+  if (!was_flush_called_) {
+    deflateEnd(&stream_);
+  }
+}
+
+void DeflateTransformer::Transform(
+    v8::Local<v8::Value> chunk,
+    TransformStreamDefaultControllerInterface* controller,
+    ExceptionState& exception_state) {
+  ArrayBufferOrArrayBufferView buffer_source;
+  V8ArrayBufferOrArrayBufferView::ToImpl(
+      script_state_->GetIsolate(), chunk, buffer_source,
+      UnionTypeConversionMode::kNotNullable, exception_state);
+  if (exception_state.HadException()) {
+    return;
+  }
+  if (buffer_source.IsArrayBufferView()) {
+    const auto* view = buffer_source.GetAsArrayBufferView().View();
+    const uint8_t* start = static_cast<const uint8_t*>(view->BaseAddress());
+    wtf_size_t length = view->byteLength();
+    Deflate(start, length, IsFinished(false), controller, exception_state);
+    return;
+  }
+  DCHECK(buffer_source.IsArrayBuffer());
+  const auto* array_buffer = buffer_source.GetAsArrayBuffer();
+  const uint8_t* start = static_cast<const uint8_t*>(array_buffer->Data());
+  wtf_size_t length = array_buffer->ByteLength();
+  Deflate(start, length, IsFinished(false), controller, exception_state);
+}
+
+void DeflateTransformer::Flush(
+    TransformStreamDefaultControllerInterface* controller,
+    ExceptionState& exception_state) {
+  Deflate(nullptr, 0u, IsFinished(true), controller, exception_state);
+  was_flush_called_ = true;
+  deflateEnd(&stream_);
+}
+
+void DeflateTransformer::Deflate(
+    const uint8_t* start,
+    wtf_size_t length,
+    IsFinished finished,
+    TransformStreamDefaultControllerInterface* controller,
+    ExceptionState& exception_state) {
+  stream_.avail_in = length;
+  // Zlib treats this pointer as const, so this cast is safe.
+  stream_.next_in = const_cast<uint8_t*>(start);
+
+  do {
+    stream_.avail_out = out_buffer_.size();
+    stream_.next_out = out_buffer_.data();
+    int err = deflate(&stream_, finished ? Z_FINISH : Z_NO_FLUSH);
+    DCHECK((finished && err == Z_STREAM_END) || err == Z_OK ||
+           err == Z_BUF_ERROR);
+
+    wtf_size_t bytes = out_buffer_.size() - stream_.avail_out;
+    if (bytes) {
+      controller->Enqueue(
+          ToV8(DOMUint8Array::Create(out_buffer_.data(), bytes), script_state_),
+          exception_state);
+      if (exception_state.HadException()) {
+        return;
+      }
+    }
+  } while (stream_.avail_out == 0);
+}
+
+void DeflateTransformer::Trace(Visitor* visitor) {
+  visitor->Trace(script_state_);
+  TransformStreamTransformer::Trace(visitor);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/compression/deflate_transformer.h b/third_party/blink/renderer/modules/compression/deflate_transformer.h
new file mode 100644
index 0000000..c3b93c0c
--- /dev/null
+++ b/third_party/blink/renderer/modules/compression/deflate_transformer.h
@@ -0,0 +1,60 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_DEFLATE_TRANSFORMER_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_DEFLATE_TRANSFORMER_H_
+
+#include "base/util/type_safety/strong_alias.h"
+
+#include "third_party/blink/renderer/core/streams/transform_stream_transformer.h"
+#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
+#include "third_party/zlib/zlib.h"
+
+namespace blink {
+
+class DeflateTransformer final : public TransformStreamTransformer {
+ public:
+  enum class Format { kGzip, kDeflate };
+
+  DeflateTransformer(ScriptState*, Format, int level);
+  ~DeflateTransformer() override;
+
+  void Transform(v8::Local<v8::Value> chunk,
+                 TransformStreamDefaultControllerInterface*,
+                 ExceptionState&) override;
+
+  void Flush(TransformStreamDefaultControllerInterface*,
+             ExceptionState&) override;
+
+  ScriptState* GetScriptState() override { return script_state_; }
+
+  void Trace(Visitor*) override;
+
+ private:
+  using IsFinished = util::StrongAlias<class IsFinishedTag, bool>;
+
+  void Deflate(const uint8_t*,
+               wtf_size_t,
+               IsFinished,
+               TransformStreamDefaultControllerInterface*,
+               ExceptionState&);
+
+  Member<ScriptState> script_state_;
+
+  Vector<uint8_t> out_buffer_;
+
+  z_stream stream_;
+
+  bool was_flush_called_ = false;
+
+  // This buffer size has been experimentally verified to be optimal.
+  static constexpr wtf_size_t kBufferSize = 16384;
+
+  DISALLOW_COPY_AND_ASSIGN(DeflateTransformer);
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_COMPRESSION_DEFLATE_TRANSFORMER_H_
diff --git a/third_party/blink/renderer/modules/compression/inflate_transformer.cc b/third_party/blink/renderer/modules/compression/inflate_transformer.cc
index 4dc0dce5b..ebab103 100644
--- a/third_party/blink/renderer/modules/compression/inflate_transformer.cc
+++ b/third_party/blink/renderer/modules/compression/inflate_transformer.cc
@@ -16,18 +16,17 @@
 
 namespace blink {
 
-InflateTransformer::InflateTransformer(ScriptState* script_state,
-                                       Algorithm algorithm)
+InflateTransformer::InflateTransformer(ScriptState* script_state, Format format)
     : script_state_(script_state), out_buffer_(kBufferSize) {
   memset(&stream_, 0, sizeof(z_stream));
-  int err;
   constexpr int kWindowBits = 15;
   constexpr int kUseGzip = 16;
-  switch (algorithm) {
-    case Algorithm::kDeflate:
+  int err;
+  switch (format) {
+    case Format::kDeflate:
       err = inflateInit2(&stream_, kWindowBits);
       break;
-    case Algorithm::kGzip:
+    case Format::kGzip:
       err = inflateInit2(&stream_, kWindowBits + kUseGzip);
       break;
   }
@@ -54,14 +53,14 @@
   }
   if (buffer_source.IsArrayBufferView()) {
     const auto* view = buffer_source.GetAsArrayBufferView().View();
-    const Bytef* start = static_cast<const Bytef*>(view->BaseAddress());
+    const uint8_t* start = static_cast<const uint8_t*>(view->BaseAddress());
     wtf_size_t length = view->byteLength();
     Inflate(start, length, IsFinished(false), controller, exception_state);
     return;
   }
   DCHECK(buffer_source.IsArrayBuffer());
   const auto* array_buffer = buffer_source.GetAsArrayBuffer();
-  const uint8_t* start = static_cast<const Bytef*>(array_buffer->Data());
+  const uint8_t* start = static_cast<const uint8_t*>(array_buffer->Data());
   wtf_size_t length = array_buffer->ByteLength();
   Inflate(start, length, IsFinished(false), controller, exception_state);
 }
@@ -76,18 +75,17 @@
 }
 
 void InflateTransformer::Inflate(
-    const Bytef* start,
+    const uint8_t* start,
     wtf_size_t length,
     IsFinished finished,
     TransformStreamDefaultControllerInterface* controller,
     ExceptionState& exception_state) {
-  unsigned int out_buffer_size = static_cast<unsigned int>(kBufferSize);
   stream_.avail_in = length;
   // Zlib treats this pointer as const, so this cast is safe.
-  stream_.next_in = const_cast<Bytef*>(start);
+  stream_.next_in = const_cast<uint8_t*>(start);
 
   do {
-    stream_.avail_out = out_buffer_size;
+    stream_.avail_out = out_buffer_.size();
     stream_.next_out = out_buffer_.data();
     int err = inflate(&stream_, finished ? Z_FINISH : Z_NO_FLUSH);
     if (err != Z_OK && err != Z_STREAM_END && err != Z_BUF_ERROR) {
@@ -95,7 +93,7 @@
       return;
     }
 
-    wtf_size_t bytes = out_buffer_size - stream_.avail_out;
+    wtf_size_t bytes = out_buffer_.size() - stream_.avail_out;
     if (bytes) {
       controller->Enqueue(
           ToV8(DOMUint8Array::Create(out_buffer_.data(), bytes), script_state_),
diff --git a/third_party/blink/renderer/modules/compression/inflate_transformer.h b/third_party/blink/renderer/modules/compression/inflate_transformer.h
index 39535e2c..b76f2c9 100644
--- a/third_party/blink/renderer/modules/compression/inflate_transformer.h
+++ b/third_party/blink/renderer/modules/compression/inflate_transformer.h
@@ -12,9 +12,9 @@
 
 class InflateTransformer final : public TransformStreamTransformer {
  public:
-  enum class Algorithm { kDeflate, kGzip };
+  enum class Format { kDeflate, kGzip };
 
-  InflateTransformer(ScriptState*, Algorithm algorithm);
+  InflateTransformer(ScriptState*, Format format);
   ~InflateTransformer() override;
 
   void Transform(v8::Local<v8::Value> chunk,
@@ -31,7 +31,7 @@
  private:
   using IsFinished = util::StrongAlias<class IsFinishedTag, bool>;
 
-  void Inflate(const Bytef*,
+  void Inflate(const uint8_t*,
                wtf_size_t,
                IsFinished,
                TransformStreamDefaultControllerInterface*,
@@ -41,10 +41,11 @@
 
   z_stream stream_;
 
-  Vector<Bytef> out_buffer_;
+  Vector<uint8_t> out_buffer_;
 
   bool was_flush_called_ = false;
 
+  // This buffer size has been experimentally verified to be optimal.
   static constexpr wtf_size_t kBufferSize = 65536;
 
   DISALLOW_COPY_AND_ASSIGN(InflateTransformer);
diff --git a/third_party/blink/renderer/modules/cookie_store/cookie_store.h b/third_party/blink/renderer/modules/cookie_store/cookie_store.h
index d85631f..692c084 100644
--- a/third_party/blink/renderer/modules/cookie_store/cookie_store.h
+++ b/third_party/blink/renderer/modules/cookie_store/cookie_store.h
@@ -7,7 +7,7 @@
 
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
-#include "services/network/public/mojom/restricted_cookie_manager.mojom-blink.h"
+#include "services/network/public/mojom/restricted_cookie_manager.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/cookie_store/cookie_store.mojom-blink.h"
 #include "third_party/blink/public/platform/web_canonical_cookie.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
diff --git a/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h b/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h
index 55e7e72..31c8c83 100644
--- a/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h
+++ b/third_party/blink/renderer/modules/credentialmanager/authenticator_attestation_response.h
@@ -5,7 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_AUTHENTICATOR_ATTESTATION_RESPONSE_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_CREDENTIALMANAGER_AUTHENTICATOR_ATTESTATION_RESPONSE_H_
 
-#include "third_party/blink/public/mojom/webauthn/authenticator.mojom-blink.h"
+#include "third_party/blink/public/mojom/webauthn/authenticator.mojom-blink-forward.h"
 #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
 #include "third_party/blink/renderer/modules/credentialmanager/authenticator_response.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
diff --git a/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc b/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
index deca23b..29f4235 100644
--- a/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
+++ b/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.cc
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "build/build_config.h"
+#include "third_party/blink/public/mojom/webauthn/authenticator.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/array_buffer_or_array_buffer_view.h"
 #include "third_party/blink/renderer/modules/credentialmanager/authenticator_selection_criteria.h"
 #include "third_party/blink/renderer/modules/credentialmanager/cable_authentication_data.h"
diff --git a/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h b/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h
index d58dfd5..9766db3 100644
--- a/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h
+++ b/third_party/blink/renderer/modules/credentialmanager/credential_manager_type_converters.h
@@ -8,7 +8,7 @@
 #include "base/optional.h"
 
 #include "third_party/blink/public/mojom/credentialmanager/credential_manager.mojom-blink.h"
-#include "third_party/blink/public/mojom/webauthn/authenticator.mojom-blink.h"
+#include "third_party/blink/public/mojom/webauthn/authenticator.mojom-blink-forward.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
diff --git a/third_party/blink/renderer/modules/device_orientation/DEPS b/third_party/blink/renderer/modules/device_orientation/DEPS
index 7c1b789..5538e5b 100644
--- a/third_party/blink/renderer/modules/device_orientation/DEPS
+++ b/third_party/blink/renderer/modules/device_orientation/DEPS
@@ -2,6 +2,7 @@
     "+base/run_loop.h",
     "+mojo/public/cpp/bindings/binding.h",
     "+services/device/public/mojom/sensor.mojom-blink.h",
+    "+services/device/public/mojom/sensor.mojom-blink-forward.h",
     "+services/device/public/mojom/sensor_provider.mojom-blink.h",
     "+services/device/public/cpp/test/fake_sensor_and_provider.h",
     "+services/device/public/cpp/generic_sensor/sensor_reading.h",
diff --git a/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.h b/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.h
index d1954ce..0f24fc5 100644
--- a/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.h
+++ b/third_party/blink/renderer/modules/device_orientation/device_sensor_entry.h
@@ -7,7 +7,7 @@
 
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
-#include "services/device/public/mojom/sensor.mojom-blink.h"
+#include "services/device/public/mojom/sensor.mojom-blink-forward.h"
 #include "services/device/public/mojom/sensor_provider.mojom-blink.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 
diff --git a/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.h b/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.h
index 2f6ec20..ccdd467 100644
--- a/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.h
+++ b/third_party/blink/renderer/modules/document_metadata/copyless_paste_extractor.h
@@ -5,7 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_DOCUMENT_METADATA_COPYLESS_PASTE_EXTRACTOR_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_DOCUMENT_METADATA_COPYLESS_PASTE_EXTRACTOR_H_
 
-#include "third_party/blink/public/mojom/document_metadata/copyless_paste.mojom-blink.h"
+#include "third_party/blink/public/mojom/document_metadata/copyless_paste.mojom-blink-forward.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 
diff --git a/third_party/blink/renderer/modules/exported/web_dom_file_system.cc b/third_party/blink/renderer/modules/exported/web_dom_file_system.cc
index 380710a..7b274f0 100644
--- a/third_party/blink/renderer/modules/exported/web_dom_file_system.cc
+++ b/third_party/blink/renderer/modules/exported/web_dom_file_system.cc
@@ -30,6 +30,7 @@
 
 #include "third_party/blink/public/web/web_dom_file_system.h"
 
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_directory_entry.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_dom_file_system.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_file_entry.h"
diff --git a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
index e293b99..db78584 100644
--- a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
+++ b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.cc
@@ -35,6 +35,7 @@
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/mojom/referrer_policy.mojom-blink.h"
+#include "services/service_manager/public/mojom/interface_provider.mojom-blink.h"
 #include "third_party/blink/public/mojom/browser_interface_broker.mojom-blink.h"
 #include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom-blink.h"
 #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
diff --git a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h
index 42ca0d0..bc33444 100644
--- a/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h
+++ b/third_party/blink/renderer/modules/exported/web_embedded_worker_impl.h
@@ -36,8 +36,8 @@
 #include "base/macros.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
-#include "services/service_manager/public/mojom/interface_provider.mojom-blink.h"
-#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink.h"
+#include "services/service_manager/public/mojom/interface_provider.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-blink-forward.h"
 #include "third_party/blink/public/web/web_embedded_worker.h"
 #include "third_party/blink/public/web/web_embedded_worker_start_data.h"
 #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
diff --git a/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.cc b/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.cc
index 7259ed52..c01ac1a 100644
--- a/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.cc
+++ b/third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/filesystem/dev_tools_host_file_system.h"
 
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/core/inspector/dev_tools_host.h"
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h
index 2035bcf..f6be95c7 100644
--- a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h
+++ b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h
@@ -31,7 +31,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_DOM_FILE_SYSTEM_BASE_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_DOM_FILE_SYSTEM_BASE_H_
 
-#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink-forward.h"
 #include "third_party/blink/renderer/core/fileapi/file_error.h"
 #include "third_party/blink/renderer/modules/filesystem/file_system_callbacks.h"
 #include "third_party/blink/renderer/modules/filesystem/file_system_flags.h"
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc b/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc
index 4b616ae7..d8cdbb6 100644
--- a/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc
+++ b/third_party/blink/renderer/modules/filesystem/dom_file_system_base_test.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/modules/filesystem/dom_file_system_base.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
 #include "third_party/blink/renderer/core/fileapi/file.h"
 #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
 
diff --git a/third_party/blink/renderer/modules/filesystem/entry.cc b/third_party/blink/renderer/modules/filesystem/entry.cc
index b1b371be1..1b3e6eb7 100644
--- a/third_party/blink/renderer/modules/filesystem/entry.cc
+++ b/third_party/blink/renderer/modules/filesystem/entry.cc
@@ -29,6 +29,7 @@
  */
 #include "third_party/blink/renderer/modules/filesystem/entry.h"
 
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/fileapi/file_error.h"
 #include "third_party/blink/renderer/core/frame/web_feature.h"
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h b/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h
index 35f91cab..f671b4b4 100644
--- a/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h
+++ b/third_party/blink/renderer/modules/filesystem/file_system_callbacks.h
@@ -33,7 +33,7 @@
 
 #include <memory>
 
-#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink-forward.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_void_callback.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_entry_callback.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_error_callback.h"
diff --git a/third_party/blink/renderer/modules/filesystem/local_file_system.h b/third_party/blink/renderer/modules/filesystem/local_file_system.h
index 58ba5d2..48d8734 100644
--- a/third_party/blink/renderer/modules/filesystem/local_file_system.h
+++ b/third_party/blink/renderer/modules/filesystem/local_file_system.h
@@ -35,7 +35,7 @@
 
 #include "base/callback.h"
 #include "base/macros.h"
-#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink.h"
+#include "third_party/blink/public/mojom/filesystem/file_system.mojom-blink-forward.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/platform/bindings/name_client.h"
diff --git a/third_party/blink/renderer/modules/gamepad/DEPS b/third_party/blink/renderer/modules/gamepad/DEPS
index 1b7f7f4..856ad767 100644
--- a/third_party/blink/renderer/modules/gamepad/DEPS
+++ b/third_party/blink/renderer/modules/gamepad/DEPS
@@ -6,6 +6,7 @@
     "+device/gamepad/public/cpp/gamepads.h",
 
     "+device/gamepad/public/mojom/gamepad.mojom-blink.h",
+    "+device/gamepad/public/mojom/gamepad.mojom-blink-forward.h",
     "+device/gamepad/public/mojom/gamepad_hardware_buffer.h",
     "+mojo/public/cpp/bindings/binding.h",
     "+mojo/public/cpp/system/buffer.h",
diff --git a/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h b/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h
index 0a15ef4..a0433c3c 100644
--- a/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h
+++ b/third_party/blink/renderer/modules/gamepad/gamepad_haptic_actuator.h
@@ -5,7 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_GAMEPAD_GAMEPAD_HAPTIC_ACTUATOR_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_GAMEPAD_GAMEPAD_HAPTIC_ACTUATOR_H_
 
-#include "device/gamepad/public/mojom/gamepad.mojom-blink.h"
+#include "device/gamepad/public/mojom/gamepad.mojom-blink-forward.h"
 #include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/member.h"
diff --git a/third_party/blink/renderer/modules/installedapp/BUILD.gn b/third_party/blink/renderer/modules/installedapp/BUILD.gn
index a72dfce..5dd66cae 100644
--- a/third_party/blink/renderer/modules/installedapp/BUILD.gn
+++ b/third_party/blink/renderer/modules/installedapp/BUILD.gn
@@ -10,6 +10,5 @@
     "installed_app_controller.h",
     "navigator_installed_app.cc",
     "navigator_installed_app.h",
-    "related_application.h",
   ]
 }
diff --git a/third_party/blink/renderer/modules/installedapp/OWNERS b/third_party/blink/renderer/modules/installedapp/OWNERS
index 065b132..e3383b0 100644
--- a/third_party/blink/renderer/modules/installedapp/OWNERS
+++ b/third_party/blink/renderer/modules/installedapp/OWNERS
@@ -1,3 +1,4 @@
-mgiuca@chromium.org
+peter@chromium.org
+rayankans@chromium.org
 
 # COMPONENT: Platform>Apps>AppLauncher>Install
diff --git a/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc b/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc
index ea97329..28469681 100644
--- a/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc
+++ b/third_party/blink/renderer/modules/installedapp/installed_app_controller.cc
@@ -96,8 +96,10 @@
     Vector<mojom::blink::RelatedApplicationPtr> result) {
   HeapVector<Member<RelatedApplication>> applications;
   for (const auto& res : result) {
-    auto* app = MakeGarbageCollected<RelatedApplication>(res->platform,
-                                                         res->url, res->id);
+    auto* app = MakeGarbageCollected<RelatedApplication>();
+    app->setPlatform(res->platform);
+    app->setURL(res->url);
+    app->setId(res->id);
     applications.push_back(app);
   }
   callbacks->OnSuccess(applications);
diff --git a/third_party/blink/renderer/modules/installedapp/related_application.h b/third_party/blink/renderer/modules/installedapp/related_application.h
deleted file mode 100644
index 16fb773..0000000
--- a/third_party/blink/renderer/modules/installedapp/related_application.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_INSTALLEDAPP_RELATED_APPLICATION_H_
-#define THIRD_PARTY_BLINK_RENDERER_MODULES_INSTALLEDAPP_RELATED_APPLICATION_H_
-
-#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
-#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
-#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
-
-namespace blink {
-
-class RelatedApplication final : public ScriptWrappable {
-  DEFINE_WRAPPERTYPEINFO();
-
- public:
-  RelatedApplication(const String& platform,
-                     const String& url,
-                     const String& id)
-      : platform_(platform), url_(url), id_(id) {}
-  ~RelatedApplication() override = default;
-
-  String platform() const { return platform_; }
-  String url() const { return url_; }
-  String id() const { return id_; }
-
- private:
-  const String platform_;
-  const String url_;
-  const String id_;
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_INSTALLEDAPP_RELATED_APPLICATION_H_
diff --git a/third_party/blink/renderer/modules/installedapp/related_application.idl b/third_party/blink/renderer/modules/installedapp/related_application.idl
index c55b7f6f..a19b4f8 100644
--- a/third_party/blink/renderer/modules/installedapp/related_application.idl
+++ b/third_party/blink/renderer/modules/installedapp/related_application.idl
@@ -5,14 +5,8 @@
 // TODO(mgiuca): Link to full spec, rather than explainer, upon completion.
 // https://github.com/WICG/get-installed-related-apps/blob/master/EXPLAINER.md
 
-// TODO(mgiuca): This should be a dictionary, not an interface.
-// (NoInterfaceObject is basically a makeshift dictionary.)
-// https://crbug.com/687444.
-[
-    NoInterfaceObject,
-    RuntimeEnabled=InstalledApp
-] interface RelatedApplication {
-    readonly attribute DOMString platform;
-    readonly attribute DOMString url;
-    readonly attribute DOMString id;
+dictionary RelatedApplication {
+    required USVString platform;
+    USVString url;
+    DOMString id;
 };
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni
index e3046395..d44dbf0 100644
--- a/third_party/blink/renderer/modules/modules_idl_files.gni
+++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -99,6 +99,7 @@
           "canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl",
           "clipboard/clipboard.idl",
           "clipboard/clipboard_item.idl",
+          "compression/compression_stream.idl",
           "compression/decompression_stream.idl",
           "contacts_picker/contacts_manager.idl",
           "content_index/content_index.idl",
@@ -194,7 +195,6 @@
           "indexeddb/idb_request.idl",
           "indexeddb/idb_transaction.idl",
           "indexeddb/idb_version_change_event.idl",
-          "installedapp/related_application.idl",
           "keyboard/keyboard.idl",
           "keyboard/keyboard_layout_map.idl",
           "locks/lock.idl",
@@ -649,6 +649,7 @@
           "indexeddb/idb_observer_init.idl",
           "indexeddb/idb_transaction_options.idl",
           "indexeddb/idb_version_change_event_init.idl",
+          "installedapp/related_application.idl",
           "locks/lock_info.idl",
           "locks/lock_manager_snapshot.idl",
           "locks/lock_options.idl",
diff --git a/third_party/blink/renderer/modules/notifications/notification.cc b/third_party/blink/renderer/modules/notifications/notification.cc
index 2e71ed3..4337c4e 100644
--- a/third_party/blink/renderer/modules/notifications/notification.cc
+++ b/third_party/blink/renderer/modules/notifications/notification.cc
@@ -35,7 +35,7 @@
 
 #include "base/unguessable_token.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_constants.h"
+#include "third_party/blink/public/common/notifications/notification_constants.h"
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_factory.h"
 #include "third_party/blink/renderer/bindings/core/v8/source_location.h"
@@ -469,7 +469,7 @@
 }
 
 uint32_t Notification::maxActions() {
-  return kWebNotificationMaxActions;
+  return kNotificationMaxActions;
 }
 
 DispatchEventResult Notification::DispatchEventInternal(Event& event) {
diff --git a/third_party/blink/renderer/modules/notifications/notification_data_test.cc b/third_party/blink/renderer/modules/notifications/notification_data_test.cc
index 6a8c94a7..2a9d4cb 100644
--- a/third_party/blink/renderer/modules/notifications/notification_data_test.cc
+++ b/third_party/blink/renderer/modules/notifications/notification_data_test.cc
@@ -38,7 +38,7 @@
 const bool kNotificationSilent = false;
 const bool kNotificationRequireInteraction = true;
 
-const mojom::blink::NotificationActionType kWebNotificationActionType =
+const mojom::blink::NotificationActionType kBlinkNotificationActionType =
     mojom::blink::NotificationActionType::TEXT;
 const char kNotificationActionType[] = "text";
 const char kNotificationActionAction[] = "my_action";
@@ -157,7 +157,7 @@
             notification_data->require_interaction);
   EXPECT_EQ(actions.size(), notification_data->actions->size());
   for (const auto& action : notification_data->actions.value()) {
-    EXPECT_EQ(kWebNotificationActionType, action->type);
+    EXPECT_EQ(kBlinkNotificationActionType, action->type);
     EXPECT_EQ(kNotificationActionAction, action->action);
     EXPECT_EQ(kNotificationActionTitle, action->title);
     EXPECT_EQ(kNotificationActionPlaceholder, action->placeholder);
diff --git a/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc b/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc
index d5f838d..be77a72d 100644
--- a/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc
+++ b/third_party/blink/renderer/modules/notifications/notification_resources_loader.cc
@@ -8,9 +8,9 @@
 
 #include "base/optional.h"
 #include "base/time/time.h"
+#include "third_party/blink/public/common/notifications/notification_constants.h"
 #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
 #include "third_party/blink/public/mojom/notifications/notification.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_constants.h"
 #include "third_party/blink/public/platform/web_size.h"
 #include "third_party/blink/renderer/platform/heap/persistent.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
@@ -28,15 +28,14 @@
 WebSize GetIconDimensions(NotificationIconType type) {
   switch (type) {
     case NotificationIconType::kImage:
-      return {kWebNotificationMaxImageWidthPx,
-              kWebNotificationMaxImageHeightPx};
+      return {kNotificationMaxImageWidthPx, kNotificationMaxImageHeightPx};
     case NotificationIconType::kIcon:
-      return {kWebNotificationMaxIconSizePx, kWebNotificationMaxIconSizePx};
+      return {kNotificationMaxIconSizePx, kNotificationMaxIconSizePx};
     case NotificationIconType::kBadge:
-      return {kWebNotificationMaxBadgeSizePx, kWebNotificationMaxBadgeSizePx};
+      return {kNotificationMaxBadgeSizePx, kNotificationMaxBadgeSizePx};
     case NotificationIconType::kActionIcon:
-      return {kWebNotificationMaxActionIconSizePx,
-              kWebNotificationMaxActionIconSizePx};
+      return {kNotificationMaxActionIconSizePx,
+              kNotificationMaxActionIconSizePx};
   }
 }
 
diff --git a/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc b/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc
index 185e351..e46ec6d 100644
--- a/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc
+++ b/third_party/blink/renderer/modules/notifications/notification_resources_loader_test.cc
@@ -6,8 +6,8 @@
 
 #include <memory>
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/notifications/notification_constants.h"
 #include "third_party/blink/public/mojom/notifications/notification.mojom-blink.h"
-#include "third_party/blink/public/platform/modules/notifications/web_notification_constants.h"
 #include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
 #include "third_party/blink/renderer/core/testing/page_test_base.h"
 #include "third_party/blink/renderer/platform/heap/heap.h"
@@ -149,19 +149,19 @@
   ASSERT_TRUE(Resources());
 
   ASSERT_FALSE(Resources()->icon.drawsNothing());
-  ASSERT_EQ(kWebNotificationMaxIconSizePx, Resources()->icon.width());
-  ASSERT_EQ(kWebNotificationMaxIconSizePx, Resources()->icon.height());
+  ASSERT_EQ(kNotificationMaxIconSizePx, Resources()->icon.width());
+  ASSERT_EQ(kNotificationMaxIconSizePx, Resources()->icon.height());
 
   ASSERT_FALSE(Resources()->badge.drawsNothing());
-  ASSERT_EQ(kWebNotificationMaxBadgeSizePx, Resources()->badge.width());
-  ASSERT_EQ(kWebNotificationMaxBadgeSizePx, Resources()->badge.height());
+  ASSERT_EQ(kNotificationMaxBadgeSizePx, Resources()->badge.width());
+  ASSERT_EQ(kNotificationMaxBadgeSizePx, Resources()->badge.height());
 
   ASSERT_TRUE(Resources()->action_icons.has_value());
   auto& action_icons = Resources()->action_icons.value();
   ASSERT_EQ(1u, action_icons.size());
   ASSERT_FALSE(action_icons[0].drawsNothing());
-  ASSERT_EQ(kWebNotificationMaxActionIconSizePx, action_icons[0].width());
-  ASSERT_EQ(kWebNotificationMaxActionIconSizePx, action_icons[0].height());
+  ASSERT_EQ(kNotificationMaxActionIconSizePx, action_icons[0].width());
+  ASSERT_EQ(kNotificationMaxActionIconSizePx, action_icons[0].height());
 }
 
 TEST_F(NotificationResourcesLoaderTest, DownscalingPreserves3_1AspectRatio) {
@@ -174,8 +174,8 @@
   ASSERT_TRUE(Resources());
 
   ASSERT_FALSE(Resources()->image.drawsNothing());
-  ASSERT_EQ(kWebNotificationMaxImageWidthPx, Resources()->image.width());
-  ASSERT_EQ(kWebNotificationMaxImageWidthPx / 3, Resources()->image.height());
+  ASSERT_EQ(kNotificationMaxImageWidthPx, Resources()->image.width());
+  ASSERT_EQ(kNotificationMaxImageWidthPx / 3, Resources()->image.height());
 }
 
 TEST_F(NotificationResourcesLoaderTest, DownscalingPreserves3_2AspectRatio) {
@@ -188,9 +188,8 @@
   ASSERT_TRUE(Resources());
 
   ASSERT_FALSE(Resources()->image.drawsNothing());
-  ASSERT_EQ(kWebNotificationMaxImageHeightPx * 3 / 2,
-            Resources()->image.width());
-  ASSERT_EQ(kWebNotificationMaxImageHeightPx, Resources()->image.height());
+  ASSERT_EQ(kNotificationMaxImageHeightPx * 3 / 2, Resources()->image.width());
+  ASSERT_EQ(kNotificationMaxImageHeightPx, Resources()->image.height());
 }
 
 TEST_F(NotificationResourcesLoaderTest, EmptyDataYieldsEmptyResources) {
diff --git a/third_party/blink/renderer/modules/peerconnection/BUILD.gn b/third_party/blink/renderer/modules/peerconnection/BUILD.gn
index 0e6bfea..6f02e496 100644
--- a/third_party/blink/renderer/modules/peerconnection/BUILD.gn
+++ b/third_party/blink/renderer/modules/peerconnection/BUILD.gn
@@ -53,9 +53,12 @@
     "call_setup_state_tracker.cc",
     "call_setup_state_tracker.h",
     "media_stream_remote_video_source.cc",
+    "media_stream_video_webrtc_sink.cc",
     "peer_connection_dependency_factory.cc",
     "rtc_certificate.cc",
     "rtc_certificate.h",
+    "rtc_certificate_generator.cc",
+    "rtc_certificate_generator.h",
     "rtc_data_channel.cc",
     "rtc_data_channel.h",
     "rtc_data_channel_event.cc",
@@ -123,6 +126,8 @@
     "rtc_void_request_script_promise_resolver_impl.h",
     "web_rtc_stats_report_callback_resolver.cc",
     "web_rtc_stats_report_callback_resolver.h",
+    "webrtc_media_stream_track_adapter.cc",
+    "webrtc_media_stream_track_adapter_map.cc",
   ]
 
   public_deps = [
diff --git a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc b/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc
similarity index 83%
rename from content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
rename to third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc
index 6d0569f..729d72c 100644
--- a/content/renderer/media/webrtc/media_stream_video_webrtc_sink.cc
+++ b/third_party/blink/renderer/modules/peerconnection/media_stream_video_webrtc_sink.cc
@@ -2,30 +2,27 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/media/webrtc/media_stream_video_webrtc_sink.h"
+#include "third_party/blink/public/web/modules/peerconnection/media_stream_video_webrtc_sink.h"
 
 #include <algorithm>
 #include <memory>
-#include <string>
 
 #include "base/bind.h"
-#include "base/feature_list.h"
 #include "base/location.h"
 #include "base/numerics/safe_conversions.h"
 #include "base/single_thread_task_runner.h"
-#include "base/strings/utf_string_conversions.h"
 #include "base/synchronization/lock.h"
 #include "base/timer/timer.h"
-#include "content/public/common/content_features.h"
 #include "media/base/limits.h"
 #include "third_party/blink/public/platform/modules/peerconnection/webrtc_video_track_source.h"
 #include "third_party/blink/public/web/modules/mediastream/media_stream_constraints_util.h"
 #include "third_party/blink/public/web/modules/mediastream/media_stream_video_track.h"
 #include "third_party/blink/public/web/modules/mediastream/web_media_stream_utils.h"
 #include "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h"
+#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
 #include "third_party/webrtc/api/video_track_source_proxy.h"
 
-namespace content {
+namespace blink {
 
 namespace {
 
@@ -47,19 +44,19 @@
     base::Time::kMicrosecondsPerSecond / media::limits::kMaxFramesPerSecond;
 
 webrtc::VideoTrackInterface::ContentHint ContentHintTypeToWebRtcContentHint(
-    blink::WebMediaStreamTrack::ContentHintType content_hint) {
+    WebMediaStreamTrack::ContentHintType content_hint) {
   switch (content_hint) {
-    case blink::WebMediaStreamTrack::ContentHintType::kNone:
+    case WebMediaStreamTrack::ContentHintType::kNone:
       return webrtc::VideoTrackInterface::ContentHint::kNone;
-    case blink::WebMediaStreamTrack::ContentHintType::kAudioSpeech:
-    case blink::WebMediaStreamTrack::ContentHintType::kAudioMusic:
+    case WebMediaStreamTrack::ContentHintType::kAudioSpeech:
+    case WebMediaStreamTrack::ContentHintType::kAudioMusic:
       NOTREACHED();
       break;
-    case blink::WebMediaStreamTrack::ContentHintType::kVideoMotion:
+    case WebMediaStreamTrack::ContentHintType::kVideoMotion:
       return webrtc::VideoTrackInterface::ContentHint::kFluid;
-    case blink::WebMediaStreamTrack::ContentHintType::kVideoDetail:
+    case WebMediaStreamTrack::ContentHintType::kVideoDetail:
       return webrtc::VideoTrackInterface::ContentHint::kDetailed;
-    case blink::WebMediaStreamTrack::ContentHintType::kVideoText:
+    case WebMediaStreamTrack::ContentHintType::kVideoText:
       return webrtc::VideoTrackInterface::ContentHint::kText;
   }
   NOTREACHED();
@@ -73,12 +70,12 @@
 // on libjingle's worker thread. WebRtcVideoCapturerAdapter implements a video
 // capturer for libjingle.
 class MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter
-    : public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> {
+    : public WTF::ThreadSafeRefCounted<WebRtcVideoSourceAdapter> {
  public:
   WebRtcVideoSourceAdapter(
       const scoped_refptr<base::SingleThreadTaskRunner>&
           libjingle_worker_thread,
-      const scoped_refptr<blink::WebRtcVideoTrackSource>& source,
+      const scoped_refptr<WebRtcVideoTrackSource>& source,
       base::TimeDelta refresh_interval,
       const base::RepeatingClosure& refresh_callback,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
@@ -95,7 +92,7 @@
                         base::TimeTicks estimated_capture_time);
 
  private:
-  friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>;
+  friend class WTF::ThreadSafeRefCounted<WebRtcVideoSourceAdapter>;
 
   void OnVideoFrameOnWorkerThread(scoped_refptr<media::VideoFrame> frame);
 
@@ -109,15 +106,15 @@
   scoped_refptr<base::SingleThreadTaskRunner> render_task_runner_;
 
   // |render_thread_checker_| is bound to the main render thread.
-  base::ThreadChecker render_thread_checker_;
+  THREAD_CHECKER(render_thread_checker_);
   // Used to DCHECK that frames are called on the IO-thread.
-  base::ThreadChecker io_thread_checker_;
+  THREAD_CHECKER(io_thread_checker_);
 
   // Used for posting frames to libjingle's worker thread. Accessed on the
   // IO-thread.
   scoped_refptr<base::SingleThreadTaskRunner> libjingle_worker_thread_;
 
-  scoped_refptr<blink::WebRtcVideoTrackSource> video_source_;
+  scoped_refptr<WebRtcVideoTrackSource> video_source_;
 
   // Used to protect |video_source_|. It is taken by libjingle's worker
   // thread for each video frame that is delivered but only taken on the
@@ -142,7 +139,7 @@
 
 MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter(
     const scoped_refptr<base::SingleThreadTaskRunner>& libjingle_worker_thread,
-    const scoped_refptr<blink::WebRtcVideoTrackSource>& source,
+    const scoped_refptr<WebRtcVideoTrackSource>& source,
     base::TimeDelta refresh_interval,
     const base::RepeatingClosure& refresh_callback,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner)
@@ -150,7 +147,7 @@
       libjingle_worker_thread_(libjingle_worker_thread),
       video_source_(source) {
   DCHECK(render_task_runner_->RunsTasksInCurrentSequence());
-  io_thread_checker_.DetachFromThread();
+  DETACH_FROM_THREAD(io_thread_checker_);
   if (!refresh_interval.is_zero()) {
     VLOG(1) << "Starting frame refresh timer with interval "
             << refresh_interval.InMillisecondsF() << " ms.";
@@ -171,14 +168,14 @@
 
 void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::
     ResetRefreshTimerOnMainThread() {
-  DCHECK(render_thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(render_thread_checker_);
   if (refresh_timer_.IsRunning())
     refresh_timer_.Reset();
 }
 
 void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::
     ReleaseSourceOnMainThread() {
-  DCHECK(render_thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(render_thread_checker_);
   // Since frames are posted to the worker thread, this object might be deleted
   // on that thread. However, since |video_source_| was created on the render
   // thread, it should be released on the render thread.
@@ -189,7 +186,7 @@
 void MediaStreamVideoWebRtcSink::WebRtcVideoSourceAdapter::OnVideoFrameOnIO(
     scoped_refptr<media::VideoFrame> frame,
     base::TimeTicks estimated_capture_time) {
-  DCHECK(io_thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_);
   render_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(&WebRtcVideoSourceAdapter::ResetRefreshTimerOnMainThread,
@@ -209,11 +206,11 @@
 }
 
 MediaStreamVideoWebRtcSink::MediaStreamVideoWebRtcSink(
-    const blink::WebMediaStreamTrack& track,
-    blink::PeerConnectionDependencyFactory* factory,
+    const WebMediaStreamTrack& track,
+    PeerConnectionDependencyFactory* factory,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
-  blink::MediaStreamVideoTrack* video_track =
-      blink::MediaStreamVideoTrack::GetVideoTrack(track);
+  MediaStreamVideoTrack* video_track =
+      MediaStreamVideoTrack::GetVideoTrack(track);
   DCHECK(video_track);
 
   absl::optional<bool> needs_denoising =
@@ -252,9 +249,9 @@
 
   // TODO(pbos): Consolidate WebRtcVideoCapturerAdapter into WebRtcVideoSource
   // by removing the need for and dependency on a cricket::VideoCapturer.
-  video_source_ = scoped_refptr<blink::WebRtcVideoTrackSource>(
-      new rtc::RefCountedObject<blink::WebRtcVideoTrackSource>(
-          is_screencast, needs_denoising));
+  video_source_ = scoped_refptr<WebRtcVideoTrackSource>(
+      new rtc::RefCountedObject<WebRtcVideoTrackSource>(is_screencast,
+                                                        needs_denoising));
 
   // TODO(pbos): Consolidate the local video track with the source proxy and
   // move into PeerConnectionDependencyFactory. This now separately holds on a
@@ -269,13 +266,13 @@
       ContentHintTypeToWebRtcContentHint(track.ContentHint()));
   video_track_->set_enabled(track.IsEnabled());
 
-  source_adapter_ = new WebRtcVideoSourceAdapter(
+  source_adapter_ = base::MakeRefCounted<WebRtcVideoSourceAdapter>(
       factory->GetWebRtcWorkerThread(), video_source_.get(), refresh_interval,
       base::Bind(&MediaStreamVideoWebRtcSink::RequestRefreshFrame,
                  weak_factory_.GetWeakPtr()),
       std::move(task_runner));
 
-  blink::MediaStreamVideoSink::ConnectToTrack(
+  MediaStreamVideoSink::ConnectToTrack(
       track,
       base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnIO, source_adapter_),
       false);
@@ -285,28 +282,28 @@
 }
 
 MediaStreamVideoWebRtcSink::~MediaStreamVideoWebRtcSink() {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   DVLOG(3) << "MediaStreamVideoWebRtcSink dtor().";
   weak_factory_.InvalidateWeakPtrs();
-  blink::MediaStreamVideoSink::DisconnectFromTrack();
+  MediaStreamVideoSink::DisconnectFromTrack();
   source_adapter_->ReleaseSourceOnMainThread();
 }
 
 void MediaStreamVideoWebRtcSink::OnEnabledChanged(bool enabled) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   video_track_->set_enabled(enabled);
 }
 
 void MediaStreamVideoWebRtcSink::OnContentHintChanged(
-    blink::WebMediaStreamTrack::ContentHintType content_hint) {
-  DCHECK(thread_checker_.CalledOnValidThread());
+    WebMediaStreamTrack::ContentHintType content_hint) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
   video_track_->set_content_hint(
       ContentHintTypeToWebRtcContentHint(content_hint));
 }
 
 void MediaStreamVideoWebRtcSink::RequestRefreshFrame() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  blink::RequestRefreshFrameFromVideoTrack(connected_track());
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  RequestRefreshFrameFromVideoTrack(connected_track());
 }
 
 absl::optional<bool>
@@ -314,4 +311,4 @@
   return video_source_->needs_denoising();
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/content/renderer/media/webrtc/rtc_certificate_generator.cc b/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.cc
similarity index 84%
rename from content/renderer/media/webrtc/rtc_certificate_generator.cc
rename to third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.cc
index 27295e85..a0db114 100644
--- a/content/renderer/media/webrtc/rtc_certificate_generator.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.cc
@@ -2,24 +2,21 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/media/webrtc/rtc_certificate_generator.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h"
 
 #include <string>
 #include <utility>
 
 #include "base/bind.h"
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "media/media_buildflags.h"
 #include "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h"
+#include "third_party/blink/renderer/platform/wtf/thread_safe_ref_counted.h"
 #include "third_party/webrtc/api/scoped_refptr.h"
 #include "third_party/webrtc/rtc_base/rtc_certificate.h"
 #include "third_party/webrtc/rtc_base/rtc_certificate_generator.h"
-#include "url/gurl.h"
 
-namespace content {
+namespace blink {
 namespace {
 
 rtc::KeyParams WebRTCKeyParamsToKeyParams(
@@ -42,13 +39,12 @@
 // is handled by a separate class so that reference counting can keep the
 // request alive independently of the |RTCCertificateGenerator| that spawned it.
 class RTCCertificateGeneratorRequest
-    : public base::RefCountedThreadSafe<RTCCertificateGeneratorRequest> {
+    : public WTF::ThreadSafeRefCounted<RTCCertificateGeneratorRequest> {
  public:
   RTCCertificateGeneratorRequest(
       const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
       const scoped_refptr<base::SingleThreadTaskRunner>& worker_thread)
-      : main_thread_(main_thread),
-        worker_thread_(worker_thread) {
+      : main_thread_(main_thread), worker_thread_(worker_thread) {
     DCHECK(main_thread_);
     DCHECK(worker_thread_);
   }
@@ -56,7 +52,7 @@
   void GenerateCertificateAsync(
       const blink::WebRTCKeyParams& key_params,
       const absl::optional<uint64_t>& expires_ms,
-      blink::WebRTCCertificateCallback completion_callback) {
+      blink::RTCCertificateCallback completion_callback) {
     DCHECK(main_thread_->BelongsToCurrentThread());
     DCHECK(completion_callback);
 
@@ -68,13 +64,13 @@
   }
 
  private:
-  friend class base::RefCountedThreadSafe<RTCCertificateGeneratorRequest>;
+  friend class WTF::ThreadSafeRefCounted<RTCCertificateGeneratorRequest>;
   ~RTCCertificateGeneratorRequest() {}
 
   void GenerateCertificateOnWorkerThread(
       const blink::WebRTCKeyParams key_params,
       const absl::optional<uint64_t> expires_ms,
-      blink::WebRTCCertificateCallback completion_callback) {
+      blink::RTCCertificateCallback completion_callback) {
     DCHECK(worker_thread_->BelongsToCurrentThread());
 
     rtc::scoped_refptr<rtc::RTCCertificate> certificate =
@@ -88,7 +84,7 @@
   }
 
   void DoCallbackOnMainThread(
-      blink::WebRTCCertificateCallback completion_callback,
+      blink::RTCCertificateCallback completion_callback,
       rtc::scoped_refptr<rtc::RTCCertificate> certificate) {
     DCHECK(main_thread_->BelongsToCurrentThread());
     DCHECK(completion_callback);
@@ -104,7 +100,7 @@
 void GenerateCertificateWithOptionalExpiration(
     const blink::WebRTCKeyParams& key_params,
     const absl::optional<uint64_t>& expires_ms,
-    blink::WebRTCCertificateCallback completion_callback,
+    blink::RTCCertificateCallback completion_callback,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   DCHECK(WebRTCKeyParamsToKeyParams(key_params).IsValid());
   auto* pc_dependency_factory =
@@ -112,7 +108,7 @@
   pc_dependency_factory->EnsureInitialized();
 
   scoped_refptr<RTCCertificateGeneratorRequest> request =
-      new RTCCertificateGeneratorRequest(
+      base::MakeRefCounted<RTCCertificateGeneratorRequest>(
           task_runner, pc_dependency_factory->GetWebRtcWorkerThread());
   request->GenerateCertificateAsync(key_params, expires_ms,
                                     std::move(completion_callback));
@@ -122,7 +118,7 @@
 
 void RTCCertificateGenerator::GenerateCertificate(
     const blink::WebRTCKeyParams& key_params,
-    blink::WebRTCCertificateCallback completion_callback,
+    blink::RTCCertificateCallback completion_callback,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   GenerateCertificateWithOptionalExpiration(
       key_params, absl::nullopt, std::move(completion_callback), task_runner);
@@ -131,7 +127,7 @@
 void RTCCertificateGenerator::GenerateCertificateWithExpiration(
     const blink::WebRTCKeyParams& key_params,
     uint64_t expires_ms,
-    blink::WebRTCCertificateCallback completion_callback,
+    blink::RTCCertificateCallback completion_callback,
     scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   GenerateCertificateWithOptionalExpiration(
       key_params, expires_ms, std::move(completion_callback), task_runner);
@@ -153,4 +149,4 @@
   return certificate;
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h b/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h
new file mode 100644
index 0000000..726b239
--- /dev/null
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h
@@ -0,0 +1,65 @@
+// Copyright (c) 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_CERTIFICATE_GENERATOR_H_
+#define THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_CERTIFICATE_GENERATOR_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "third_party/blink/public/platform/web_rtc_key_params.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/renderer/modules/modules_export.h"
+#include "third_party/webrtc/api/peer_connection_interface.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace blink {
+
+using RTCCertificateCallback =
+    base::OnceCallback<void(rtc::scoped_refptr<rtc::RTCCertificate>)>;
+
+// Chromium's WebRTCCertificateGenerator implementation; uses the
+// PeerConnectionIdentityStore/SSLIdentity::Generate to generate the identity,
+// rtc::RTCCertificate and blink::RTCCertificate.
+//
+// TODO(crbug.com/787254): Convert use of WebString to WTF::String.
+class MODULES_EXPORT RTCCertificateGenerator {
+ public:
+  RTCCertificateGenerator() {}
+  ~RTCCertificateGenerator() {}
+
+  // Start generating a certificate asynchronously. |observer| is invoked on the
+  // same thread that called generateCertificate when the operation is
+  // completed.
+  void GenerateCertificate(
+      const blink::WebRTCKeyParams& key_params,
+      blink::RTCCertificateCallback completion_callback,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+  void GenerateCertificateWithExpiration(
+      const blink::WebRTCKeyParams& key_params,
+      uint64_t expires_ms,
+      blink::RTCCertificateCallback completion_callback,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+
+  // Determines if the parameters are supported by |GenerateCertificate|.
+  // For example, if the number of bits of some parameter is too small or too
+  // large we may want to reject it for security or performance reasons.
+  bool IsSupportedKeyParams(const blink::WebRTCKeyParams& key_params);
+
+  // Creates a certificate from the PEM strings. See also
+  // |rtc::RTCCertificate::ToPEM|.
+  rtc::scoped_refptr<rtc::RTCCertificate> FromPEM(
+      blink::WebString pem_private_key,
+      blink::WebString pem_certificate);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(RTCCertificateGenerator);
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_PEERCONNECTION_RTC_CERTIFICATE_GENERATOR_H_
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
index c0de493a..26cec8d 100644
--- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
+++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -45,7 +45,6 @@
 #include "third_party/blink/public/platform/web_crypto_algorithm_params.h"
 #include "third_party/blink/public/platform/web_media_stream.h"
 #include "third_party/blink/public/platform/web_rtc_answer_options.h"
-#include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
 #include "third_party/blink/public/platform/web_rtc_data_channel_init.h"
 #include "third_party/blink/public/platform/web_rtc_ice_candidate.h"
 #include "third_party/blink/public/platform/web_rtc_key_params.h"
@@ -79,6 +78,7 @@
 #include "third_party/blink/renderer/modules/mediastream/media_stream_event.h"
 #include "third_party/blink/renderer/modules/mediastream/user_media_controller.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_answer_options.h"
+#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_configuration.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h"
 #include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h"
@@ -1670,8 +1670,7 @@
   }
   DCHECK(key_params.has_value());
 
-  std::unique_ptr<WebRTCCertificateGenerator> certificate_generator =
-      Platform::Current()->CreateRTCCertificateGenerator();
+  auto certificate_generator = std::make_unique<RTCCertificateGenerator>();
 
   // |keyParams| was successfully constructed, but does the certificate
   // generator support these parameters?
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc b/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc
similarity index 96%
rename from content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc
rename to third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc
index 48ee044..c1071210 100644
--- a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter.cc
+++ b/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter.cc
@@ -2,15 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter.h"
 
 #include "base/bind.h"
-#include "content/renderer/media/webrtc/media_stream_video_webrtc_sink.h"
 #include "third_party/blink/public/platform/modules/mediastream/media_stream_audio_track.h"
 #include "third_party/blink/public/web/modules/mediastream/processed_local_audio_source.h"
+#include "third_party/blink/public/web/modules/peerconnection/media_stream_video_webrtc_sink.h"
 #include "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h"
 
-namespace content {
+namespace blink {
 
 // static
 scoped_refptr<WebRtcMediaStreamTrackAdapter>
@@ -193,8 +193,8 @@
   DCHECK_EQ(web_track.Source().GetType(),
             blink::WebMediaStreamSource::kTypeVideo);
   web_track_ = web_track;
-  local_track_video_sink_.reset(
-      new MediaStreamVideoWebRtcSink(web_track_, factory_, main_thread_));
+  local_track_video_sink_.reset(new blink::MediaStreamVideoWebRtcSink(
+      web_track_, factory_, main_thread_));
   webrtc_track_ = local_track_video_sink_->webrtc_video_track();
   DCHECK(webrtc_track_);
   is_initialized_ = true;
@@ -335,4 +335,4 @@
   web_track_.Reset();
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.cc b/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.cc
similarity index 86%
rename from content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.cc
rename to third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.cc
index 53941f18..d4b697d 100644
--- a/content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.cc
+++ b/third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.cc
@@ -2,19 +2,20 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/renderer/media/webrtc/webrtc_media_stream_track_adapter_map.h"
+#include "third_party/blink/public/web/modules/peerconnection/webrtc_media_stream_track_adapter_map.h"
 
 #include <utility>
 
 #include "base/bind.h"
+#include "base/single_thread_task_runner.h"
 #include "third_party/blink/public/web/modules/peerconnection/peer_connection_dependency_factory.h"
 
-namespace content {
+namespace blink {
 
 WebRtcMediaStreamTrackAdapterMap::AdapterRef::AdapterRef(
     scoped_refptr<WebRtcMediaStreamTrackAdapterMap> map,
     Type type,
-    scoped_refptr<WebRtcMediaStreamTrackAdapter> adapter)
+    scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> adapter)
     : map_(std::move(map)), type_(type), adapter_(std::move(adapter)) {
   DCHECK(map_);
   DCHECK(adapter_);
@@ -22,7 +23,7 @@
 
 WebRtcMediaStreamTrackAdapterMap::AdapterRef::~AdapterRef() {
   DCHECK(map_->main_thread_->BelongsToCurrentThread());
-  scoped_refptr<WebRtcMediaStreamTrackAdapter> removed_adapter;
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> removed_adapter;
   {
     base::AutoLock scoped_lock(map_->lock_);
     // The adapter is stored in the track adapter map and we have |adapter_|,
@@ -30,7 +31,7 @@
     DCHECK(!adapter_->HasOneRef());
     // Using a raw pointer instead of |adapter_| allows the reference count to
     // go down to one if this is the last |AdapterRef|.
-    WebRtcMediaStreamTrackAdapter* adapter = adapter_.get();
+    blink::WebRtcMediaStreamTrackAdapter* adapter = adapter_.get();
     adapter_ = nullptr;
     if (adapter->HasOneRef()) {
       removed_adapter = adapter;
@@ -88,7 +89,7 @@
 WebRtcMediaStreamTrackAdapterMap::GetLocalTrackAdapter(
     const blink::WebMediaStreamTrack& web_track) {
   base::AutoLock scoped_lock(lock_);
-  scoped_refptr<WebRtcMediaStreamTrackAdapter>* adapter_ptr =
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr =
       local_track_adapters_.FindByPrimary(web_track.UniqueId());
   if (!adapter_ptr)
     return nullptr;
@@ -100,7 +101,7 @@
 WebRtcMediaStreamTrackAdapterMap::GetLocalTrackAdapter(
     webrtc::MediaStreamTrackInterface* webrtc_track) {
   base::AutoLock scoped_lock(lock_);
-  scoped_refptr<WebRtcMediaStreamTrackAdapter>* adapter_ptr =
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr =
       local_track_adapters_.FindBySecondary(webrtc_track);
   if (!adapter_ptr)
     return nullptr;
@@ -114,19 +115,19 @@
   DCHECK(!web_track.IsNull());
   DCHECK(main_thread_->BelongsToCurrentThread());
   base::AutoLock scoped_lock(lock_);
-  scoped_refptr<WebRtcMediaStreamTrackAdapter>* adapter_ptr =
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr =
       local_track_adapters_.FindByPrimary(web_track.UniqueId());
   if (adapter_ptr) {
     return base::WrapUnique(
         new AdapterRef(this, AdapterRef::Type::kLocal, *adapter_ptr));
   }
-  scoped_refptr<WebRtcMediaStreamTrackAdapter> new_adapter;
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> new_adapter;
   {
     // Do not hold |lock_| while creating the adapter in case that operation
     // synchronizes with the signaling thread. If we do and the signaling thread
     // is blocked waiting for |lock_| we end up in a deadlock.
     base::AutoUnlock scoped_unlock(lock_);
-    new_adapter = WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter(
+    new_adapter = blink::WebRtcMediaStreamTrackAdapter::CreateLocalTrackAdapter(
         factory_, main_thread_, web_track);
   }
   DCHECK(new_adapter->is_initialized());
@@ -146,7 +147,7 @@
 WebRtcMediaStreamTrackAdapterMap::GetRemoteTrackAdapter(
     const blink::WebMediaStreamTrack& web_track) {
   base::AutoLock scoped_lock(lock_);
-  scoped_refptr<WebRtcMediaStreamTrackAdapter>* adapter_ptr =
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr =
       remote_track_adapters_.FindBySecondary(web_track.UniqueId());
   if (!adapter_ptr)
     return nullptr;
@@ -159,7 +160,7 @@
 WebRtcMediaStreamTrackAdapterMap::GetRemoteTrackAdapter(
     webrtc::MediaStreamTrackInterface* webrtc_track) {
   base::AutoLock scoped_lock(lock_);
-  scoped_refptr<WebRtcMediaStreamTrackAdapter>* adapter_ptr =
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr =
       remote_track_adapters_.FindByPrimary(webrtc_track);
   if (!adapter_ptr)
     return nullptr;
@@ -173,20 +174,21 @@
   DCHECK(webrtc_track);
   DCHECK(!main_thread_->BelongsToCurrentThread());
   base::AutoLock scoped_lock(lock_);
-  scoped_refptr<WebRtcMediaStreamTrackAdapter>* adapter_ptr =
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapter>* adapter_ptr =
       remote_track_adapters_.FindByPrimary(webrtc_track.get());
   if (adapter_ptr) {
     return base::WrapUnique(
         new AdapterRef(this, AdapterRef::Type::kRemote, *adapter_ptr));
   }
-  scoped_refptr<WebRtcMediaStreamTrackAdapter> new_adapter;
+  scoped_refptr<blink::WebRtcMediaStreamTrackAdapter> new_adapter;
   {
     // Do not hold |lock_| while creating the adapter in case that operation
     // synchronizes with the main thread. If we do and the main thread is
     // blocked waiting for |lock_| we end up in a deadlock.
     base::AutoUnlock scoped_unlock(lock_);
-    new_adapter = WebRtcMediaStreamTrackAdapter::CreateRemoteTrackAdapter(
-        factory_, main_thread_, webrtc_track);
+    new_adapter =
+        blink::WebRtcMediaStreamTrackAdapter::CreateRemoteTrackAdapter(
+            factory_, main_thread_, webrtc_track);
   }
   remote_track_adapters_.Insert(webrtc_track.get(), new_adapter);
   // The new adapter is initialized in a post to the main thread. As soon as it
@@ -210,4 +212,4 @@
   return remote_track_adapters_.PrimarySize();
 }
 
-}  // namespace content
+}  // namespace blink
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
index 5e1a13c..00632e2 100644
--- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -1410,6 +1410,12 @@
   if (GetDrawingBuffer() && GetDrawingBuffer()->UsingSwapChain())
     GetDrawingBuffer()->PresentSwapChain();
   marked_canvas_dirty_ = false;
+
+  // For low-latency canvases
+  const bool webgl_overlay_enabled =
+      RuntimeEnabledFeatures::WebGLImageChromiumEnabled() || UsingSwapChain();
+  if (canvas() && canvas()->LowLatencyEnabled() && !webgl_overlay_enabled)
+    PaintRenderingResultsToCanvas(kBackBuffer);
 }
 
 void WebGLRenderingContextBase::OnErrorMessage(const char* message,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc
index c23bda3..78def744 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.cc
@@ -91,22 +91,11 @@
                                                offset);
 }
 
-void GPURenderBundleEncoder::setVertexBuffers(
-    uint32_t startSlot,
-    const HeapVector<Member<GPUBuffer>>& buffers,
-    const Vector<uint64_t>& offsets,
-    ExceptionState& exception_state) {
-  if (buffers.size() != offsets.size()) {
-    exception_state.ThrowRangeError(
-        "buffers array and offsets array must be the same length");
-    return;
-  }
-
-  std::unique_ptr<DawnBuffer[]> dawn_buffers = AsDawnType(buffers);
-
-  GetProcs().renderBundleEncoderSetVertexBuffers(
-      GetHandle(), startSlot, buffers.size(), dawn_buffers.get(),
-      offsets.data());
+void GPURenderBundleEncoder::setVertexBuffer(uint32_t slot,
+                                             const GPUBuffer* buffer,
+                                             uint64_t offset) {
+  GetProcs().renderBundleEncoderSetVertexBuffer(GetHandle(), slot,
+                                                buffer->GetHandle(), offset);
 }
 
 void GPURenderBundleEncoder::draw(uint32_t vertexCount,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h b/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h
index 39f8b79..a8015a7 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h
@@ -39,10 +39,7 @@
   void setPipeline(GPURenderPipeline* pipeline);
 
   void setIndexBuffer(GPUBuffer* buffer, uint64_t offset);
-  void setVertexBuffers(uint32_t startSlot,
-                        const HeapVector<Member<GPUBuffer>>& buffers,
-                        const Vector<uint64_t>& offsets,
-                        ExceptionState& exception_state);
+  void setVertexBuffer(uint32_t slot, const GPUBuffer* buffer, uint64_t offset);
   void draw(uint32_t vertexCount,
             uint32_t instanceCount,
             uint32_t firstVertex,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_encoder_base.idl b/third_party/blink/renderer/modules/webgpu/gpu_render_encoder_base.idl
index c862895..f966384 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_render_encoder_base.idl
+++ b/third_party/blink/renderer/modules/webgpu/gpu_render_encoder_base.idl
@@ -10,9 +10,9 @@
     void setPipeline(GPURenderPipeline pipeline);
 
     void setIndexBuffer(GPUBuffer buffer, optional GPUBufferSize offset = 0);
-    [RaisesException] void setVertexBuffers(unsigned long startSlot,
-                                            sequence<GPUBuffer> buffers,
-                                            sequence<GPUBufferSize> offsets);
+    void setVertexBuffer(unsigned long slot,
+                         GPUBuffer buffer,
+                         optional GPUBufferSize offset = 0);
 
     void draw(unsigned long vertexCount, unsigned long instanceCount,
               unsigned long firstVertex,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc
index 8f32e35..6214d674 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.cc
@@ -98,22 +98,11 @@
                                              offset);
 }
 
-void GPURenderPassEncoder::setVertexBuffers(
-    uint32_t startSlot,
-    const HeapVector<Member<GPUBuffer>>& buffers,
-    const Vector<uint64_t>& offsets,
-    ExceptionState& exception_state) {
-  if (buffers.size() != offsets.size()) {
-    exception_state.ThrowRangeError(
-        "buffers array and offsets array must be the same length");
-    return;
-  }
-
-  std::unique_ptr<DawnBuffer[]> dawn_buffers = AsDawnType(buffers);
-
-  GetProcs().renderPassEncoderSetVertexBuffers(
-      GetHandle(), startSlot, buffers.size(), dawn_buffers.get(),
-      offsets.data());
+void GPURenderPassEncoder::setVertexBuffer(uint32_t slot,
+                                           const GPUBuffer* buffer,
+                                           const uint64_t offset) {
+  GetProcs().renderPassEncoderSetVertexBuffer(GetHandle(), slot,
+                                              buffer->GetHandle(), offset);
 }
 
 void GPURenderPassEncoder::draw(uint32_t vertexCount,
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h
index aceb574..0362203 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_render_pass_encoder.h
@@ -47,10 +47,9 @@
                    float maxDepth);
   void setScissorRect(uint32_t x, uint32_t y, uint32_t width, uint32_t height);
   void setIndexBuffer(GPUBuffer* buffer, uint64_t offset);
-  void setVertexBuffers(uint32_t startSlot,
-                        const HeapVector<Member<GPUBuffer>>& buffers,
-                        const Vector<uint64_t>& offsets,
-                        ExceptionState& exception_state);
+  void setVertexBuffer(uint32_t slot,
+                       const GPUBuffer* buffer,
+                       const uint64_t offset);
   void draw(uint32_t vertexCount,
             uint32_t instanceCount,
             uint32_t firstVertex,
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string.cc b/third_party/blink/renderer/platform/bindings/parkable_string.cc
index 20d03c1..310c57ce 100644
--- a/third_party/blink/renderer/platform/bindings/parkable_string.cc
+++ b/third_party/blink/renderer/platform/bindings/parkable_string.cc
@@ -209,12 +209,7 @@
   if (!may_be_parked())
     return;
 
-#if DCHECK_IS_ON()
-  {
-    MutexLocker locker(mutex_);
-    DCHECK_EQ(0, lock_depth_);
-  }
-#endif
+  DCHECK_EQ(0, lock_depth_for_testing());
   AsanUnpoisonString(string_);
   DCHECK(state_ == State::kParked || state_ == State::kUnparked);
 
@@ -362,7 +357,7 @@
   DCHECK(!is_parked());
 
   Status status = CurrentStatus();
-  if (is_young()) {
+  if (is_young_) {
     if (status == Status::kUnreferencedExternally)
       is_young_ = false;
   } else {
@@ -403,7 +398,7 @@
 void ParkableStringImpl::ParkInternal(ParkingMode mode) {
   mutex_.AssertAcquired();
   DCHECK_EQ(State::kUnparked, state_);
-  DCHECK(!is_young());
+  DCHECK(!is_young_);
   DCHECK(CanParkNow());
 
   // Parking can proceed synchronously.
@@ -449,7 +444,7 @@
 }
 
 bool ParkableStringImpl::CanParkNow() const {
-  return CurrentStatus() == Status::kUnreferencedExternally && !is_young();
+  return CurrentStatus() == Status::kUnreferencedExternally && !is_young_;
 }
 
 void ParkableStringImpl::Unpark() {
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string.h b/third_party/blink/renderer/platform/bindings/parkable_string.h
index abc5d42..96fa7f7 100644
--- a/third_party/blink/renderer/platform/bindings/parkable_string.h
+++ b/third_party/blink/renderer/platform/bindings/parkable_string.h
@@ -11,6 +11,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/thread_annotations.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
 #include "third_party/blink/renderer/platform/wtf/ref_counted.h"
@@ -105,12 +106,10 @@
     return compressed_->size();
   }
 
-  // A string can either be "young" or "old". It starts young, and transitions
-  // are:
-  // Young -> Old: By calling |MaybeAgeOrParkString()|.
-  // Old -> Young: When the string is accessed, either by |Lock()|-ing it or
-  //               calling |ToString()|.
-  bool is_young() const { return is_young_; }
+  bool is_young_for_testing() {
+    MutexLocker locker(mutex_);
+    return is_young_;
+  }
 
  private:
   enum class State : uint8_t;
@@ -128,12 +127,12 @@
   // May be called from any thread.
   void LockWithoutMakingYoung();
 #endif  // defined(ADDRESS_SANITIZER)
-  // May be called from any thread. Must acquire |mutex_| first.
-  void MakeYoung();
-  // Whether the string is referenced or locked. Must be called with |mutex_|
-  // held, and the return value is valid as long as |mutex_| is held.
-  Status CurrentStatus() const;
-  bool CanParkNow() const;
+  // May be called from any thread.
+  void MakeYoung() EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+  // Whether the string is referenced or locked. The return value is valid as
+  // long as |mutex_| is held.
+  Status CurrentStatus() const EXCLUSIVE_LOCKS_REQUIRED(mutex_);
+  bool CanParkNow() const EXCLUSIVE_LOCKS_REQUIRED(mutex_);
   void ParkInternal(ParkingMode mode);
   void Unpark();
   String UnparkInternal() const;
@@ -151,14 +150,29 @@
   // Background thread.
   static void CompressInBackground(std::unique_ptr<CompressionTaskParams>);
 
-  Mutex mutex_;  // protects lock_depth_.
-  int lock_depth_;
+  int lock_depth_for_testing() {
+    MutexLocker locker_(mutex_);
+    return lock_depth_;
+  }
+
+  Mutex mutex_;
+  int lock_depth_ GUARDED_BY(mutex_);
 
   // Main thread only.
   State state_;
   String string_;
   std::unique_ptr<Vector<uint8_t>> compressed_;
-  bool is_young_ : 1;
+
+  // A string can either be "young" or "old". It starts young, and transitions
+  // are:
+  // Young -> Old: By calling |MaybeAgeOrParkString()|.
+  // Old -> Young: When the string is accessed, either by |Lock()|-ing it or
+  //               calling |ToString()|.
+  //
+  // Thread safety: it is typically not safe to guard only one part of a
+  // bitfield with a mutex, but this is correct here, as the other members are
+  // const (and never change).
+  bool is_young_ : 1 GUARDED_BY(mutex_);
 
   const bool may_be_parked_ : 1;
   const bool is_8bit_ : 1;
diff --git a/third_party/blink/renderer/platform/bindings/parkable_string_test.cc b/third_party/blink/renderer/platform/bindings/parkable_string_test.cc
index 920ae68c..545633f 100644
--- a/third_party/blink/renderer/platform/bindings/parkable_string_test.cc
+++ b/third_party/blink/renderer/platform/bindings/parkable_string_test.cc
@@ -362,15 +362,15 @@
 TEST_F(ParkableStringTest, LockUnlock) {
   ParkableString parkable(MakeLargeString().Impl());
   ParkableStringImpl* impl = parkable.Impl();
-  EXPECT_EQ(0, impl->lock_depth_);
+  EXPECT_EQ(0, impl->lock_depth_for_testing());
 
   parkable.Lock();
-  EXPECT_EQ(1, impl->lock_depth_);
+  EXPECT_EQ(1, impl->lock_depth_for_testing());
   parkable.Lock();
   parkable.Unlock();
-  EXPECT_EQ(1, impl->lock_depth_);
+  EXPECT_EQ(1, impl->lock_depth_for_testing());
   parkable.Unlock();
-  EXPECT_EQ(0, impl->lock_depth_);
+  EXPECT_EQ(0, impl->lock_depth_for_testing());
 
   parkable.Lock();
   EXPECT_FALSE(ParkAndWait(parkable));
@@ -393,12 +393,12 @@
   EXPECT_TRUE(impl->is_parked());
   parkable.ToString();
   EXPECT_FALSE(impl->is_parked());
-  EXPECT_EQ(1, impl->lock_depth_);
+  EXPECT_EQ(1, impl->lock_depth_for_testing());
 
   EXPECT_FALSE(ParkAndWait(parkable));
 
   parkable.Unlock();
-  EXPECT_EQ(0, impl->lock_depth_);
+  EXPECT_EQ(0, impl->lock_depth_for_testing());
   EXPECT_TRUE(ParkAndWait(parkable));
   EXPECT_TRUE(impl->is_parked());
 }
@@ -675,37 +675,37 @@
 
 TEST_F(ParkableStringTest, Aging) {
   ParkableString parkable(MakeLargeString().ReleaseImpl());
-  EXPECT_TRUE(parkable.Impl()->is_young());
+  EXPECT_TRUE(parkable.Impl()->is_young_for_testing());
   WaitForAging();
-  EXPECT_FALSE(parkable.Impl()->is_young());
+  EXPECT_FALSE(parkable.Impl()->is_young_for_testing());
 
   parkable.Lock();
-  EXPECT_TRUE(parkable.Impl()->is_young());
+  EXPECT_TRUE(parkable.Impl()->is_young_for_testing());
   // Locked strings don't age.
   WaitForAging();
-  EXPECT_TRUE(parkable.Impl()->is_young());
+  EXPECT_TRUE(parkable.Impl()->is_young_for_testing());
   parkable.Unlock();
   WaitForAging();
-  EXPECT_FALSE(parkable.Impl()->is_young());
+  EXPECT_FALSE(parkable.Impl()->is_young_for_testing());
 
   parkable.ToString();
-  EXPECT_TRUE(parkable.Impl()->is_young());
+  EXPECT_TRUE(parkable.Impl()->is_young_for_testing());
   // No external reference, can age again.
   WaitForAging();
-  EXPECT_FALSE(parkable.Impl()->is_young());
+  EXPECT_FALSE(parkable.Impl()->is_young_for_testing());
 
   // External references prevent a string from aging.
   String retained = parkable.ToString();
-  EXPECT_TRUE(parkable.Impl()->is_young());
+  EXPECT_TRUE(parkable.Impl()->is_young_for_testing());
   WaitForAging();
-  EXPECT_TRUE(parkable.Impl()->is_young());
+  EXPECT_TRUE(parkable.Impl()->is_young_for_testing());
 }
 
 TEST_F(ParkableStringTest, OldStringsAreParked) {
   ParkableString parkable(MakeLargeString().ReleaseImpl());
-  EXPECT_TRUE(parkable.Impl()->is_young());
+  EXPECT_TRUE(parkable.Impl()->is_young_for_testing());
   WaitForAging();
-  EXPECT_FALSE(parkable.Impl()->is_young());
+  EXPECT_FALSE(parkable.Impl()->is_young_for_testing());
   WaitForAging();
   EXPECT_TRUE(parkable.Impl()->is_parked());
 
diff --git a/third_party/blink/renderer/platform/blob/testing/fake_blob_url_store.cc b/third_party/blink/renderer/platform/blob/testing/fake_blob_url_store.cc
index 9533966..d70a550 100644
--- a/third_party/blink/renderer/platform/blob/testing/fake_blob_url_store.cc
+++ b/third_party/blink/renderer/platform/blob/testing/fake_blob_url_store.cc
@@ -33,7 +33,7 @@
 
 void FakeBlobURLStore::ResolveAsURLLoaderFactory(
     const KURL&,
-    network::mojom::blink::URLLoaderFactoryRequest) {
+    mojo::PendingReceiver<network::mojom::blink::URLLoaderFactory>) {
   NOTREACHED();
 }
 
diff --git a/third_party/blink/renderer/platform/blob/testing/fake_blob_url_store.h b/third_party/blink/renderer/platform/blob/testing/fake_blob_url_store.h
index f26a0a5c..79e62ac 100644
--- a/third_party/blink/renderer/platform/blob/testing/fake_blob_url_store.h
+++ b/third_party/blink/renderer/platform/blob/testing/fake_blob_url_store.h
@@ -7,6 +7,7 @@
 
 #include "third_party/blink/public/mojom/blob/blob_url_store.mojom-blink.h"
 
+#include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl_hash.h"
@@ -25,7 +26,7 @@
   void Resolve(const KURL&, ResolveCallback) override;
   void ResolveAsURLLoaderFactory(
       const KURL&,
-      network::mojom::blink::URLLoaderFactoryRequest) override;
+      mojo::PendingReceiver<network::mojom::blink::URLLoaderFactory>) override;
   void ResolveForNavigation(
       const KURL&,
       mojo::PendingReceiver<mojom::blink::BlobURLToken>) override;
diff --git a/third_party/blink/renderer/platform/exported/platform.cc b/third_party/blink/renderer/platform/exported/platform.cc
index 2f76e92..c772ef51 100644
--- a/third_party/blink/renderer/platform/exported/platform.cc
+++ b/third_party/blink/renderer/platform/exported/platform.cc
@@ -44,7 +44,6 @@
 #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
 #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h"
 #include "third_party/blink/public/platform/web_prerendering_support.h"
-#include "third_party/blink/public/platform/web_rtc_certificate_generator.h"
 #include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h"
 #include "third_party/blink/public/platform/websocket_handshake_throttle.h"
 #include "third_party/blink/renderer/platform/bindings/parkable_string_manager.h"
@@ -353,11 +352,6 @@
   return nullptr;
 }
 
-std::unique_ptr<WebRTCCertificateGenerator>
-Platform::CreateRTCCertificateGenerator() {
-  return nullptr;
-}
-
 std::unique_ptr<webrtc::RtpCapabilities> Platform::GetRtpSenderCapabilities(
     const WebString& kind) {
   return nullptr;
diff --git a/third_party/blink/renderer/platform/exported/web_url_response.cc b/third_party/blink/renderer/platform/exported/web_url_response.cc
index 9c5957e..5d2e4f4 100644
--- a/third_party/blink/renderer/platform/exported/web_url_response.cc
+++ b/third_party/blink/renderer/platform/exported/web_url_response.cc
@@ -303,6 +303,10 @@
   resource_response_->SetWasCached(value);
 }
 
+bool WebURLResponse::WasFetchedViaSPDY() const {
+  return resource_response_->WasFetchedViaSPDY();
+}
+
 void WebURLResponse::SetWasFetchedViaSPDY(bool value) {
   resource_response_->SetWasFetchedViaSPDY(value);
 }
@@ -405,6 +409,14 @@
   resource_response_->SetRecursivePrefetchToken(token);
 }
 
+bool WebURLResponse::WasAlpnNegotiated() const {
+  return resource_response_->WasAlpnNegotiated();
+}
+
+void WebURLResponse::SetWasAlpnNegotiated(bool was_alpn_negotiated) {
+  resource_response_->SetWasAlpnNegotiated(was_alpn_negotiated);
+}
+
 WebString WebURLResponse::AlpnNegotiatedProtocol() const {
   return resource_response_->AlpnNegotiatedProtocol();
 }
@@ -414,6 +426,16 @@
   resource_response_->SetAlpnNegotiatedProtocol(alpn_negotiated_protocol);
 }
 
+bool WebURLResponse::WasAlternateProtocolAvailable() const {
+  return resource_response_->WasAlternateProtocolAvailable();
+}
+
+void WebURLResponse::SetWasAlternateProtocolAvailable(
+    bool was_alternate_protocol_available) {
+  resource_response_->SetWasAlternateProtocolAvailable(
+      was_alternate_protocol_available);
+}
+
 net::HttpResponseInfo::ConnectionInfo WebURLResponse::ConnectionInfo() const {
   return resource_response_->ConnectionInfo();
 }
diff --git a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
index 1327546..1223290a 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.cc
@@ -732,11 +732,9 @@
   if (!GetOrCreateResourceProvider(kPreferAcceleration))
     return;
 
+  FlushRecording();
   ++frames_since_last_commit_;
   if (frames_since_last_commit_ >= 2) {
-    // TODO(aaronhk) Ideally we'd want to call FlushRecording() here, but this
-    // causes webview to hang for pixel 2. See crbug.com/1002946
-    ResourceProvider()->FlushSkia();
     if (IsAccelerated() && !rate_limiter_) {
       // Make sure the GPU is never more than two animation frames behind.
       constexpr unsigned kMaxCanvasAnimationBacklog = 2;
diff --git a/third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h b/third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h
index 1277de7..417d0bf 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h
+++ b/third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h
@@ -53,6 +53,11 @@
   // underlying GrContext is flushed.
   kMaxDrawsBeforeContextFlush = 50,
 
+  // Canvas resource provider
+  // ========================
+
+  // The maximum number of inflight resources waiting to be used for recycling.
+  kMaxRecycledCanvasResources = 2,
 };  // enum
 
 }  // namespace canvas_heuristic_parameters
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
index b9768c3..576f6781 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -1145,6 +1145,11 @@
 
 void CanvasResourceProvider::RecycleResource(
     scoped_refptr<CanvasResource> resource) {
+  // We don't want to keep an arbitrary large number of canvases.
+  if (canvas_resources_.size() >
+      canvas_heuristic_parameters::kMaxRecycledCanvasResources)
+    return;
+
   // Need to check HasOneRef() because if there are outstanding references to
   // the resource, it cannot be safely recycled.
   if (resource->HasOneRef() && resource_recycling_enabled_ &&
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_response.h b/third_party/blink/renderer/platform/loader/fetch/resource_response.h
index 3c6bc71c..3c200c17 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_response.h
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_response.h
@@ -379,6 +379,11 @@
   uint16_t RemotePort() const { return remote_port_; }
   void SetRemotePort(uint16_t value) { remote_port_ = value; }
 
+  bool WasAlpnNegotiated() const { return was_alpn_negotiated_; }
+  void SetWasAlpnNegotiated(bool was_alpn_negotiated) {
+    was_alpn_negotiated_ = was_alpn_negotiated;
+  }
+
   const AtomicString& AlpnNegotiatedProtocol() const {
     return alpn_negotiated_protocol_;
   }
@@ -435,6 +440,14 @@
 
   void SetFromArchive(bool from_archive) { from_archive_ = from_archive; }
 
+  bool WasAlternateProtocolAvailable() const {
+    return was_alternate_protocol_available_;
+  }
+
+  void SetWasAlternateProtocolAvailable(bool was_alternate_protocol_available) {
+    was_alternate_protocol_available_ = was_alternate_protocol_available;
+  }
+
   bool IsSignedExchangeInnerResponse() const {
     return is_signed_exchange_inner_response_;
   }
@@ -523,6 +536,12 @@
   // True if this resource was loaded from a MHTML archive.
   bool from_archive_ = false;
 
+  // True if response could use alternate protocol.
+  bool was_alternate_protocol_available_ = false;
+
+  // True if the response was delivered after ALPN is negotiated.
+  bool was_alpn_negotiated_ = false;
+
   // https://fetch.spec.whatwg.org/#concept-response-type
   network::mojom::FetchResponseType response_type_;
 
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index e98f1e7f..33a28b7 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -514,7 +514,7 @@
     },
     {
       name: "CustomStatePseudoClass",
-      status: "test",
+      status: "experimental",
     },
     {
       name: "Database",
@@ -547,6 +547,8 @@
     },
     {
       name: "DisplayLocking",
+      origin_trial_feature_name: "DisplayLocking",
+      depends_on: ["CSSContentSize"],
       status: "experimental",
     },
     {
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 3b3a77f..4cf58a8 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
@@ -843,6 +843,7 @@
         ],
         'allowed': ['crypto::.+'],
     },
+
     {
         'paths': [
             'third_party/blink/renderer/modules/p2p',
@@ -856,15 +857,22 @@
     },
     {
         'paths': [
-            'third_party/blink/renderer/modules/peerconnection',
-            'third_party/blink/renderer/bindings/modules/v8/serialization',
+            # TODO(crbug.com/787254): Separate the two paths below and their own
+            # whitelist.
+            'third_party/blink/renderer/modules/peerconnection/',
+            'third_party/blink/renderer/bindings/modules/v8/serialization/',
         ],
         'allowed': [
+            'absl::.+',
+            'base::AutoLock',
+            'base::AutoUnlock',
+            'base::Lock',
             # TODO(crbug.com/787254): Remove base::BindOnce, base::Unretained,
             # base::MessageLoopCurrent.
-            'base::BindOnce',
+            'base::Bind.*',
             "base::MessageLoopCurrent",
             'base::Unretained',
+            'base::WrapRefCounted',
             'cricket::.*',
             'jingle_glue::JingleThreadWrapper',
             # TODO(crbug.com/787254): Remove GURL usage.
@@ -887,7 +895,6 @@
         # AtomicString or HeapVector) are used cross thread. These Blink types
         # are converted to the STL/WebRTC counterparts in the parent directory.
         'allowed': [
-            'absl::.+',
             'base::OnTaskRunnerDeleter',
             'sigslot::.+',
         ],
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/disable-blink-features=LayoutNG
index b95c2633..b45a2ab 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-blink-features=LayoutNG
+++ b/third_party/blink/web_tests/FlagExpectations/disable-blink-features=LayoutNG
@@ -250,6 +250,11 @@
 ### external/wpt/css/filter-effects/
 crbug.com/591099 external/wpt/css/filter-effects/filtered-inline-applies-to-float.html [ Failure ]
 
+### external/wpt/css/css-lists/
+crbug.com/1012294 external/wpt/css/css-lists/list-style-type-string-003.html [ Pass ]
+crbug.com/1012289 external/wpt/css/css-lists/list-style-type-string-005a.html [ Failure ]
+crbug.com/1012289 external/wpt/css/css-lists/list-style-type-string-006.html [ Failure ]
+
 ### external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/
 crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002.xhtml [ Failure ]
 
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 9389cec..90e981d8 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -705,6 +705,7 @@
 crbug.com/591099 external/wpt/css/css-text/shaping/shaping-011.html [ Failure ]
 crbug.com/591099 external/wpt/css/css-text/word-break/word-break-break-all-inline-006.html [ Failure ]
 crbug.com/1002815 external/wpt/css/cssom-view/offsetTopLeft-trailing-space-inline.html [ Failure ]
+crbug.com/1012294 external/wpt/css/css-lists/list-style-type-string-003.html [ Failure ]
 crbug.com/591099 fast/backgrounds/quirks-mode-line-box-backgrounds.html [ Failure ]
 crbug.com/591099 fast/borders/inline-mask-overlay-image-outset-vertical-rl.html [ Failure ]
 crbug.com/835484 fast/css/outline-narrowLine.html [ Failure ]
@@ -1802,6 +1803,7 @@
 crbug.com/995106 external/wpt/css/css-lists/inline-list.html [ Failure ]
 crbug.com/995106 external/wpt/css/css-lists/inline-list-marker.html [ Failure ]
 crbug.com/995106 external/wpt/css/css-lists/inline-list-with-table-child.html [ Failure ]
+crbug.com/1012289 external/wpt/css/css-lists/list-style-type-string-005b.html [ Failure ]
 
 # ====== Style team owned tests to here ======
 
@@ -2949,12 +2951,6 @@
 crbug.com/1012627 [ Win7 ] external/wpt/css/css-text/line-breaking/line-breaking-021.html [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
-crbug.com/626703 [ Linux ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/lists-3/list-style-type-string-001a.html [ Failure ]
-crbug.com/626703 [ Mac ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/lists-3/list-style-type-string-001a.html [ Failure ]
-crbug.com/626703 [ Win ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/lists-3/list-style-type-string-001a.html [ Failure ]
-crbug.com/626703 [ Linux ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/lists-3/list-style-type-string-001b.html [ Failure ]
-crbug.com/626703 [ Mac ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/lists-3/list-style-type-string-001b.html [ Failure ]
-crbug.com/626703 [ Win ] external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/lists-3/list-style-type-string-001b.html [ Failure ]
 crbug.com/626703 [ Linux ] external/wpt/clear-site-data/storage.https.html [ Timeout ]
 crbug.com/626703 [ Mac ] external/wpt/clear-site-data/storage.https.html [ Timeout ]
 crbug.com/626703 [ Win ] external/wpt/clear-site-data/storage.https.html [ Timeout ]
@@ -4066,6 +4062,11 @@
 crbug.com/792446 external/wpt/css/css-multicol/multicol-span-float-001.xht [ Failure ]
 crbug.com/964183 external/wpt/css/css-multicol/multicol-width-005.html [ Failure ]
 
+crbug.com/457718 external/wpt/css/css-pseudo/marker-content-002.html [ Failure ]
+crbug.com/457718 external/wpt/css/css-pseudo/marker-content-003.html [ Failure ]
+crbug.com/457718 external/wpt/css/css-pseudo/marker-content-003b.html [ Failure ]
+crbug.com/457718 external/wpt/css/css-pseudo/marker-content-004.html [ Failure ]
+crbug.com/457718 external/wpt/css/css-pseudo/marker-content-005.html [ Failure ]
 crbug.com/457718 external/wpt/css/css-pseudo/marker-content-006.html [ Failure ]
 crbug.com/457718 external/wpt/css/css-pseudo/marker-content-007.html [ Failure ]
 crbug.com/457718 external/wpt/css/css-pseudo/marker-content-008.html [ Failure ]
@@ -4214,7 +4215,7 @@
 # Needs investigation. These are timing out.
 crbug.com/835717 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/sandboxed-iframe-fetch-event.https.html [ Skip ]
 crbug.com/835717 virtual/omt-worker-fetch/external/wpt/service-workers/service-worker/worker-in-sandboxed-iframe-by-csp-fetch-event.https.html [ Skip ]
-crbug.com/1002377 [ Win7 ] virtual/omt-service-worker-startup/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ]
+crbug.com/1002377 [ Win ] virtual/omt-service-worker-startup/external/wpt/service-workers/service-worker/update-bytecheck.https.html [ Timeout ]
 
 crbug.com/435547 http/tests/cachestorage/serviceworker/ignore-search-with-credentials.html [ Skip ]
 
@@ -5698,7 +5699,6 @@
 # Sheriff 2019-06-14
 
 # Sheriff 2019-06-20
-crbug.com/977153 [ Mac ] fast/forms/validation-bubble-appearance-wrap.html [ Pass Failure ]
 crbug.com/976045 fast/scrolling/unscrollable-layer-subpixel-size-with-negative-overflow.html [ Pass Failure ]
 crbug.com/976045 virtual/scroll_customization/fast/scrolling/unscrollable-layer-subpixel-size-with-negative-overflow.html [ Pass Failure ]
 crbug.com/976045 virtual/threaded/fast/scrolling/unscrollable-layer-subpixel-size-with-negative-overflow.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/custom-elements/state/state-pseudo-class.html b/third_party/blink/web_tests/custom-elements/state/state-pseudo-class.html
new file mode 100644
index 0000000..d14a5e6e
--- /dev/null
+++ b/third_party/blink/web_tests/custom-elements/state/state-pseudo-class.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<style>
+#state-and-part::part(inner) {
+  opacity: 0;
+}
+#state-and-part::part(inner):state(innerFoo) {
+  opacity: 0.5;
+}
+#state-and-part:state(outerFoo)::part(inner) {
+  opacity: 0.25;
+}
+</style>
+<body>
+<script>
+class TestElement extends HTMLElement {
+  constructor() {
+    super();
+    this._internals = this.attachInternals();
+  }
+
+  get internals() {
+    return this._internals;
+  }
+}
+customElements.define('test-element', TestElement);
+
+class ContainerElement extends HTMLElement {
+  constructor() {
+    super();
+    this._internals = this.attachInternals();
+    this._shadow = this.attachShadow({mode:'open'});
+    this._shadow.innerHTML = `
+<style>
+:host {
+  border-style: solid;
+}
+:host(:state(dotted)) {
+  border-style: dotted;
+}
+</style>
+<test-element part="inner"></test-element>`;
+  }
+
+  get internals() {
+    return this._internals;
+  }
+  get innerElement() {
+    return this._shadow.querySelector('test-element');
+  }
+}
+customElements.define('container-element', ContainerElement);
+
+test(() => {
+  assert_throws(new SyntaxError(), () => { document.querySelector(':state'); });
+  assert_throws(new SyntaxError(), () => { document.querySelector(':state('); });
+  assert_throws(new SyntaxError(), () => { document.querySelector(':state()'); });
+  assert_throws(new SyntaxError(), () => { document.querySelector(':state(=)'); });
+  assert_throws(new SyntaxError(), () => { document.querySelector(':state(name=value)'); });
+  assert_throws(new SyntaxError(), () => { document.querySelector(':state( foo bar)'); });
+  assert_throws(new SyntaxError(), () => { document.querySelector(':state(16px)'); });
+}, ':state() parsing failures');
+
+test(() => {
+  assert_equals(document.styleSheets[0].cssRules[1].cssText,
+      '#state-and-part::part(inner):state(innerFoo) { opacity: 0.5; }');
+}, ':state() serialization');
+
+test(() => {
+  let element = new TestElement();
+  let states = element.internals.states;
+
+  assert_false(element.matches(':state(foo)'));
+  assert_true(element.matches(':not(:state(foo))'));
+  states.add('foo');
+  assert_true(element.matches(':state(foo)'));
+  assert_true(element.matches(':is(:state(foo))'));
+  element.classList.add('c1', 'c2');
+  assert_true(element.matches('.c1:state(foo)'));
+  assert_true(element.matches(':state(foo).c1'));
+  assert_true(element.matches('.c2:state(foo).c1'));
+}, ':state() in simple cases');
+
+test(() => {
+  let element = new TestElement();
+  element.tabIndex = 0;
+  document.body.appendChild(element);
+  element.focus();
+  let states = element.internals.states;
+
+  states.value = 'foo';
+  assert_true(element.matches(':focus:state(foo)'));
+  assert_true(element.matches(':state(foo):focus'));
+}, ':state() and other pseudo classes');
+
+test(() => {
+  let outer = new ContainerElement();
+  outer.id = 'state-and-part';
+  document.body.appendChild(outer);
+  let inner = outer.innerElement;
+  let innerStates = inner.internals.states;
+
+  innerStates.add('innerFoo');
+  assert_equals(getComputedStyle(inner).opacity, '0.5',
+      '::part() followed by :state()');
+  innerStates.replace('innerFoo', 'innerfoo');
+  assert_equals(getComputedStyle(inner).opacity, '0',
+      ':state() matching should be case-sensitive');
+  innerStates.remove('innerfoo');
+
+  outer.internals.states.add('outerFoo');
+  assert_equals(getComputedStyle(inner).opacity, '0.25',
+      ':state() followed by ::part()');
+}, ':state() and ::part()');
+
+test(() => {
+  let outer = new ContainerElement();
+  document.body.appendChild(outer);
+
+  assert_equals(getComputedStyle(outer).borderStyle, 'solid');
+  outer.internals.states.toggle('dotted');
+  assert_equals(getComputedStyle(outer).borderStyle, 'dotted');
+}, ':state() and :host()');
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
index cbd0312..756b84a 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -124957,9 +124957,6 @@
    "common/echo.py": [
     []
    ],
-   "common/entities.json": [
-    []
-   ],
    "common/form-submission.py": [
     []
    ],
@@ -125191,6 +125188,15 @@
    "compat/webkit-text-fill-color-property-006-ref.html": [
     []
    ],
+   "compression/pako/LICENSE": [
+    []
+   ],
+   "compression/pako/README": [
+    []
+   ],
+   "compression/pako/pako_inflate.min.js": [
+    []
+   ],
    "console/META.yml": [
     []
    ],
@@ -140608,9 +140614,6 @@
    "css/css-scroll-anchoring/scroll-padding-affects-anchoring-expected.txt": [
     []
    ],
-   "css/css-scroll-anchoring/text-anchor-in-vertical-rl-expected.txt": [
-    []
-   ],
    "css/css-scroll-snap/META.yml": [
     []
    ],
@@ -147871,27 +147874,12 @@
    "css/cssom-view/resources/iframe2.html": [
     []
    ],
-   "css/cssom-view/scrollIntoView-horizontal-tb-writing-mode-and-rtl-direction-expected.txt": [
-    []
-   ],
-   "css/cssom-view/scrollIntoView-sideways-lr-writing-mode-and-rtl-direction-expected.txt": [
-    []
-   ],
    "css/cssom-view/scrollIntoView-sideways-lr-writing-mode-expected.txt": [
     []
    ],
-   "css/cssom-view/scrollIntoView-sideways-rl-writing-mode-and-rtl-direction-expected.txt": [
-    []
-   ],
    "css/cssom-view/scrollIntoView-sideways-rl-writing-mode-expected.txt": [
     []
    ],
-   "css/cssom-view/scrollIntoView-vertical-lr-writing-mode-and-rtl-direction-expected.txt": [
-    []
-   ],
-   "css/cssom-view/scrollLeftTop-expected.txt": [
-    []
-   ],
    "css/cssom-view/scrollTop-display-change-ref.html": [
     []
    ],
@@ -161371,6 +161359,9 @@
    "html/the-xhtml-syntax/parsing-xhtml-documents/data-xhtml-with-dtd-ref.html": [
     []
    ],
+   "html/the-xhtml-syntax/parsing-xhtml-documents/support/entities.json": [
+    []
+   ],
    "html/the-xhtml-syntax/parsing-xhtml-documents/support/xhtml-mathml-dtd-entity.htm": [
     []
    ],
@@ -198375,6 +198366,88 @@
      {}
     ]
    ],
+   "compression/compression-stream.any.js": [
+    [
+     "compression/compression-stream.any.html",
+     {
+      "script_metadata": [
+       [
+        "global",
+        "worker"
+       ],
+       [
+        "script",
+        "pako/pako_inflate.min.js"
+       ],
+       [
+        "timeout",
+        "long"
+       ]
+      ],
+      "timeout": "long"
+     }
+    ],
+    [
+     "compression/compression-stream.any.serviceworker.html",
+     {
+      "script_metadata": [
+       [
+        "global",
+        "worker"
+       ],
+       [
+        "script",
+        "pako/pako_inflate.min.js"
+       ],
+       [
+        "timeout",
+        "long"
+       ]
+      ],
+      "timeout": "long"
+     }
+    ],
+    [
+     "compression/compression-stream.any.sharedworker.html",
+     {
+      "script_metadata": [
+       [
+        "global",
+        "worker"
+       ],
+       [
+        "script",
+        "pako/pako_inflate.min.js"
+       ],
+       [
+        "timeout",
+        "long"
+       ]
+      ],
+      "timeout": "long"
+     }
+    ],
+    [
+     "compression/compression-stream.any.worker.html",
+     {
+      "script_metadata": [
+       [
+        "global",
+        "worker"
+       ],
+       [
+        "script",
+        "pako/pako_inflate.min.js"
+       ],
+       [
+        "timeout",
+        "long"
+       ]
+      ],
+      "timeout": "long"
+     }
+    ]
+   ],
    "compression/decompression-bad-chunks.any.js": [
     [
      "compression/decompression-bad-chunks.any.html",
@@ -336789,7 +336862,7 @@
    "support"
   ],
   "animation-worklet/scroll-timeline-writing-modes.https.html": [
-   "189bb9f091665718c11be01779ad0390fe0f7437",
+   "eb8e6fdb948d0996e80ede3a206ee61abd47f0ea",
    "testharness"
   ],
   "animation-worklet/stateful-animator.https.html": [
@@ -338477,7 +338550,7 @@
    "support"
   ],
   "common/README.md": [
-   "43bec9eb0af2d648969c9f32983963f09548f73d",
+   "9aef19cb73fa10c2962c489f43a4517e7f215116",
    "support"
   ],
   "common/arrays.js": [
@@ -338544,10 +338617,6 @@
    "2ee403645b1bb27cdb27bcea716e166729b81af8",
    "support"
   ],
-  "common/entities.json": [
-   "8a1f590a6abe4872d3b8b4c665d9b165d7dce84d",
-   "support"
-  ],
   "common/form-submission.py": [
    "467875453c9dc64aac51add3f4a617d941820972",
    "support"
@@ -338944,6 +339013,10 @@
    "1d3965fca6769c70bc02308a4c70b4e58c8990e5",
    "reftest"
   ],
+  "compression/compression-stream.any.js": [
+   "47df70f7cd3979c1a3eab45581376fd38a6b2367",
+   "testharness"
+  ],
   "compression/decompression-bad-chunks.any.js": [
    "b8954905cbfce79893152e32200cc16e6c3f815b",
    "testharness"
@@ -338972,6 +339045,18 @@
    "06c421a82071651429e831daaa20e945e8011efb",
    "testharness"
   ],
+  "compression/pako/LICENSE": [
+   "a934ef8db478453e38b2f29af67610916fa9fc99",
+   "support"
+  ],
+  "compression/pako/README": [
+   "96028388ebb9d556db918bbe234e8b971734824a",
+   "support"
+  ],
+  "compression/pako/pako_inflate.min.js": [
+   "a191a78a8956cddf28adaf7542631123014a04bf",
+   "support"
+  ],
   "console/META.yml": [
    "60c95d0d579c57eee3c2c0b47004b371c24d2e56",
    "support"
@@ -370573,7 +370658,7 @@
    "support"
   ],
   "css/css-flexbox/scrollbars-auto-ref.html": [
-   "e83ba524eac185ef122e0e05a336d9a8c43089c5",
+   "590b533d8d25ac45dbeb1e7eab7cd02f3c1e8b5b",
    "support"
   ],
   "css/css-flexbox/scrollbars-auto.html": [
@@ -370581,7 +370666,7 @@
    "reftest"
   ],
   "css/css-flexbox/scrollbars-ref.html": [
-   "32bb6105f19009e11e95b7cee86659125917516f",
+   "911e7acba88333d4e2ddf0d0fec36fbcc4975825",
    "support"
   ],
   "css/css-flexbox/scrollbars.html": [
@@ -389109,11 +389194,11 @@
    "testharness"
   ],
   "css/css-position/position-sticky-writing-modes-ref.html": [
-   "39800866a18323a5bf89e7208889184f191571bd",
+   "b9771acf248e1cfaad4ff93c59f63811ee3f6abb",
    "support"
   ],
   "css/css-position/position-sticky-writing-modes.html": [
-   "ee2dbc05a9cfca121596f6694f74f6fc76f748a0",
+   "da27f50c7fba29d40d408240369da6947d0b9b0c",
    "reftest"
   ],
   "css/css-position/resources/sticky-util.js": [
@@ -390268,10 +390353,6 @@
    "25961b366424b1f3686e27fc8eab677cc2f95de8",
    "testharness"
   ],
-  "css/css-scroll-anchoring/text-anchor-in-vertical-rl-expected.txt": [
-   "f2c8c5ac27744a47eb9dcae04ba3f84de3aa2fa5",
-   "support"
-  ],
   "css/css-scroll-anchoring/text-anchor-in-vertical-rl.html": [
    "0edf950936b2739aec9bded7c221d250e43c223a",
    "testharness"
@@ -390477,7 +390558,7 @@
    "manual"
   ],
   "css/css-scroll-snap/snap-inline-block-expected.txt": [
-   "4819c39d75fa15b3e4cd7e9f2faadbf259d85362",
+   "49f8a89dec51fcb24564aa896b98747938b329b5",
    "support"
   ],
   "css/css-scroll-snap/snap-inline-block.html": [
@@ -419292,10 +419373,6 @@
    "cc67ce76ed9d432656b37c9c81a20e86d1bafc8d",
    "testharness"
   ],
-  "css/cssom-view/scrollIntoView-horizontal-tb-writing-mode-and-rtl-direction-expected.txt": [
-   "e6c667c584c1847913ee81a0c1bddcc2bf41f773",
-   "support"
-  ],
   "css/cssom-view/scrollIntoView-horizontal-tb-writing-mode-and-rtl-direction.html": [
    "3ef9d62a3654c5ab2dd061e34799053daeefc3a4",
    "testharness"
@@ -419316,10 +419393,6 @@
    "eb1bce37d2cdc09640eb1aa20951f75d2a8aa36f",
    "testharness"
   ],
-  "css/cssom-view/scrollIntoView-sideways-lr-writing-mode-and-rtl-direction-expected.txt": [
-   "8ed2baa631ddcbe568cd5fb32505c2e61b2b3c6c",
-   "support"
-  ],
   "css/cssom-view/scrollIntoView-sideways-lr-writing-mode-and-rtl-direction.html": [
    "8d435407f68e42e026c22b563f639e885d1feb84",
    "testharness"
@@ -419332,10 +419405,6 @@
    "0659dec8c1a7e226e2e22c7ae16119f204c5d892",
    "testharness"
   ],
-  "css/cssom-view/scrollIntoView-sideways-rl-writing-mode-and-rtl-direction-expected.txt": [
-   "410a1757236c986cfa8141c17653d3ed13dd3d37",
-   "support"
-  ],
   "css/cssom-view/scrollIntoView-sideways-rl-writing-mode-and-rtl-direction.html": [
    "82e43eb4859d9cbd5cea64e105adfae9df629f21",
    "testharness"
@@ -419356,10 +419425,6 @@
    "7af5de5ff8aceb96867815354571314afd4cb07c",
    "testharness"
   ],
-  "css/cssom-view/scrollIntoView-vertical-lr-writing-mode-and-rtl-direction-expected.txt": [
-   "9c4115c5977f0a98f10cc19f6dc34240348204ec",
-   "support"
-  ],
   "css/cssom-view/scrollIntoView-vertical-lr-writing-mode-and-rtl-direction.html": [
    "3301141ee0115fc941240dc76b27d988032273ae",
    "testharness"
@@ -419369,17 +419434,13 @@
    "testharness"
   ],
   "css/cssom-view/scrollIntoView-vertical-rl-writing-mode.html": [
-   "cec27f412c926ab087f2cd736e4c6a7d4efb4c99",
+   "dc5f3e2cdb2fa6c4b0c59ded80b7e19df2db274c",
    "testharness"
   ],
   "css/cssom-view/scrollLeft-of-scroller-with-wider-scrollbar.html": [
    "e308c7c004f8415a5bf1ee886b681fb84780717c",
    "testharness"
   ],
-  "css/cssom-view/scrollLeftTop-expected.txt": [
-   "a0ecd95107eab1d8a403a948f58213a84a0214da",
-   "support"
-  ],
   "css/cssom-view/scrollLeftTop.html": [
    "55b4013600727a3dcae0ab2c286a38801cdd8426",
    "testharness"
@@ -458632,8 +458693,12 @@
    "fd29905ea30ed987c8d634c7f6df2e9e5e517e96",
    "reftest"
   ],
+  "html/the-xhtml-syntax/parsing-xhtml-documents/support/entities.json": [
+   "8a1f590a6abe4872d3b8b4c665d9b165d7dce84d",
+   "support"
+  ],
   "html/the-xhtml-syntax/parsing-xhtml-documents/support/xhtml-mathml-dtd-entity.htm": [
-   "761655094599be5451e231b30c81241550bee3a5",
+   "af3fe90284f213961679d1996d17766ccfc30621",
    "support"
   ],
   "html/the-xhtml-syntax/parsing-xhtml-documents/xhtml-mathml-dtd-entity-1.htm": [
@@ -475693,15 +475758,15 @@
    "testharness"
   ],
   "payment-request/PaymentValidationErrors/retry-shows-error-member-manual.https.html": [
-   "9d25e9e1524663fb6520d8c6bf41aca4e1b14e4e",
+   "9135520cd762f3e6286b5f3ba572f88cae920fa1",
    "manual"
   ],
   "payment-request/PaymentValidationErrors/retry-shows-payer-member-manual.https.html": [
-   "ad5ad72fbb64aa85b56062fedd9a7f596d0bdb0f",
+   "f8115e69ec5d7c3172a6e42d4e446898d04f9a8b",
    "manual"
   ],
   "payment-request/PaymentValidationErrors/retry-shows-shippingAddress-member-manual.https.html": [
-   "837ab79cbefa9eebd358f72a227014d5c71af72f",
+   "dc9294534b664b925ec59d69292a71609c9fe1c8",
    "manual"
   ],
   "payment-request/algorithms-manual.https.html": [
@@ -475961,7 +476026,7 @@
    "manual"
   ],
   "payment-request/payment-response/retry-method-manual.https.html": [
-   "0af894500dae7fe74597315956db43fdf15ad2ee",
+   "fc0a0427f4c3ed8cb1728eec2353c54faa18db44",
    "manual"
   ],
   "payment-request/payment-response/retry-method-warnings-manual.https.html": [
@@ -491009,7 +491074,7 @@
    "testharness"
   ],
   "scroll-animations/current-time-writing-modes.html": [
-   "89b78fcccfe4e18b79d1f0f63eac90606fc81703",
+   "083c4cf594d80bf331b6c4243b9e2e32af46f531",
    "testharness"
   ],
   "scroll-animations/current-time.html": [
diff --git a/third_party/blink/web_tests/external/wpt/common/README.md b/third_party/blink/web_tests/external/wpt/common/README.md
index 43bec9e..9aef19cb 100644
--- a/third_party/blink/web_tests/external/wpt/common/README.md
+++ b/third_party/blink/web_tests/external/wpt/common/README.md
@@ -4,7 +4,6 @@
 * `domain-setter.sub.html` - An HTML document that sets `document.domain`.
 * `dummy.xhtml` - An XHTML document.
 * `dummy.xml` - An XML document.
-* `entities.json` - All named character references in HTML.
 * `text-plain.txt` - A text/plain document.
 * `*.js` - Utility scripts. These are documented in the source.
 * `*.py` - wptserve [Python Handlers](https://web-platform-tests.org/writing-tests/python-handlers/). These are documented in the source.
diff --git a/third_party/blink/web_tests/external/wpt/compression/compression-stream.any.js b/third_party/blink/web_tests/external/wpt/compression/compression-stream.any.js
new file mode 100644
index 0000000..47df70f7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/compression/compression-stream.any.js
@@ -0,0 +1,91 @@
+// META: global=worker
+// META: script=pako/pako_inflate.min.js
+// META: timeout=long
+
+'use strict';
+
+const SMALL_FILE = "/media/foo.vtt";
+const LARGE_FILE = "/media/test-av-384k-44100Hz-1ch-320x240-30fps-10kfr.webm";
+
+async function compressArrayBuffer(input, format) {
+  const cs = new CompressionStream(format);
+  const writer = cs.writable.getWriter();
+  writer.write(input);
+  const closePromise = writer.close();
+  const out = [];
+  const reader = cs.readable.getReader();
+  let totalSize = 0;
+  while (true) {
+    const { value, done } = await reader.read();
+    if (done)
+      break;
+    out.push(value);
+    totalSize += value.byteLength;
+  }
+  await closePromise;
+  const concatenated = new Uint8Array(totalSize);
+  let offset = 0;
+  for (const array of out) {
+    concatenated.set(array, offset);
+    offset += array.byteLength;
+  }
+  return concatenated;
+}
+
+test(() => {
+  assert_throws(new TypeError(), () => {
+    const transformer = new CompressionStream("nonvalid");
+  }, "non supported format should throw");
+}, "CompressionStream constructor should throw on invalid format");
+
+promise_test(async () => {
+  const buffer = new ArrayBuffer(0);
+  const bufferView = new Uint8Array(buffer);
+  const compressedData = await compressArrayBuffer(bufferView, "deflate");
+  // decompress with pako, and check that we got the same result as our original string
+  assert_array_equals(bufferView, pako.inflate(compressedData));
+}, "deflated empty data should be reinflated back to its origin");
+
+promise_test(async () => {
+  const response = await fetch(SMALL_FILE)
+  const buffer = await response.arrayBuffer();
+  const bufferView = new Uint8Array(buffer);
+  const compressedData = await compressArrayBuffer(bufferView, "deflate");
+  // decompress with pako, and check that we got the same result as our original string
+  assert_array_equals(bufferView, pako.inflate(compressedData));
+}, "deflated small amount data should be reinflated back to its origin");
+
+promise_test(async () => {
+  const response = await fetch(LARGE_FILE)
+  const buffer = await response.arrayBuffer();
+  const bufferView = new Uint8Array(buffer);
+  const compressedData = await compressArrayBuffer(bufferView, "deflate");
+  // decompress with pako, and check that we got the same result as our original string
+  assert_array_equals(bufferView, pako.inflate(compressedData));
+}, "deflated large amount data should be reinflated back to its origin");
+
+promise_test(async () => {
+  const buffer = new ArrayBuffer(0);
+  const bufferView = new Uint8Array(buffer);
+  const compressedData = await compressArrayBuffer(bufferView, "gzip");
+  // decompress with pako, and check that we got the same result as our original string
+  assert_array_equals(bufferView, pako.inflate(compressedData));
+}, "gzipped empty data should be reinflated back to its origin");
+
+promise_test(async () => {
+  const response = await fetch(SMALL_FILE)
+  const buffer = await response.arrayBuffer();
+  const bufferView = new Uint8Array(buffer);
+  const compressedData = await compressArrayBuffer(bufferView, "gzip");
+  // decompress with pako, and check that we got the same result as our original string
+  assert_array_equals(bufferView, pako.inflate(compressedData));
+}, "gzipped small amount data should be reinflated back to its origin");
+
+promise_test(async () => {
+  const response = await fetch(LARGE_FILE)
+  const buffer = await response.arrayBuffer();
+  const bufferView = new Uint8Array(buffer);
+  const compressedData = await compressArrayBuffer(bufferView, "gzip");
+  // decompress with pako, and check that we got the same result as our original string
+  assert_array_equals(bufferView, pako.inflate(compressedData));
+}, "gzipped large amount data should be reinflated back to its origin");
diff --git a/third_party/blink/web_tests/external/wpt/compression/pako/LICENSE b/third_party/blink/web_tests/external/wpt/compression/pako/LICENSE
new file mode 100644
index 0000000..a934ef8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/compression/pako/LICENSE
@@ -0,0 +1,21 @@
+(The MIT License)
+
+Copyright (C) 2014-2017 by Vitaly Puzrin and Andrei Tuputcyn
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/third_party/blink/web_tests/external/wpt/compression/pako/README b/third_party/blink/web_tests/external/wpt/compression/pako/README
new file mode 100644
index 0000000..96028388
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/compression/pako/README
@@ -0,0 +1,2 @@
+original repository:
+https://github.com/nodeca/pako
diff --git a/third_party/blink/web_tests/external/wpt/compression/pako/pako_inflate.min.js b/third_party/blink/web_tests/external/wpt/compression/pako/pako_inflate.min.js
new file mode 100644
index 0000000..a191a78
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/compression/pako/pako_inflate.min.js
@@ -0,0 +1 @@
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).pako=e()}}(function(){return function r(o,s,f){function l(t,e){if(!s[t]){if(!o[t]){var i="function"==typeof require&&require;if(!e&&i)return i(t,!0);if(d)return d(t,!0);var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}var a=s[t]={exports:{}};o[t][0].call(a.exports,function(e){return l(o[t][1][e]||e)},a,a.exports,r,o,s,f)}return s[t].exports}for(var d="function"==typeof require&&require,e=0;e<f.length;e++)l(f[e]);return l}({1:[function(e,t,i){"use strict";var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;i.assign=function(e){for(var t,i,n=Array.prototype.slice.call(arguments,1);n.length;){var a=n.shift();if(a){if("object"!=typeof a)throw new TypeError(a+"must be non-object");for(var r in a)t=a,i=r,Object.prototype.hasOwnProperty.call(t,i)&&(e[r]=a[r])}}return e},i.shrinkBuf=function(e,t){return e.length===t?e:e.subarray?e.subarray(0,t):(e.length=t,e)};var a={arraySet:function(e,t,i,n,a){if(t.subarray&&e.subarray)e.set(t.subarray(i,i+n),a);else for(var r=0;r<n;r++)e[a+r]=t[i+r]},flattenChunks:function(e){var t,i,n,a,r,o;for(t=n=0,i=e.length;t<i;t++)n+=e[t].length;for(o=new Uint8Array(n),t=a=0,i=e.length;t<i;t++)r=e[t],o.set(r,a),a+=r.length;return o}},r={arraySet:function(e,t,i,n,a){for(var r=0;r<n;r++)e[a+r]=t[i+r]},flattenChunks:function(e){return[].concat.apply([],e)}};i.setTyped=function(e){e?(i.Buf8=Uint8Array,i.Buf16=Uint16Array,i.Buf32=Int32Array,i.assign(i,a)):(i.Buf8=Array,i.Buf16=Array,i.Buf32=Array,i.assign(i,r))},i.setTyped(n)},{}],2:[function(e,t,i){"use strict";var f=e("./common"),a=!0,r=!0;try{String.fromCharCode.apply(null,[0])}catch(e){a=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(e){r=!1}for(var l=new f.Buf8(256),n=0;n<256;n++)l[n]=252<=n?6:248<=n?5:240<=n?4:224<=n?3:192<=n?2:1;function d(e,t){if(t<65534&&(e.subarray&&r||!e.subarray&&a))return String.fromCharCode.apply(null,f.shrinkBuf(e,t));for(var i="",n=0;n<t;n++)i+=String.fromCharCode(e[n]);return i}l[254]=l[254]=1,i.string2buf=function(e){var t,i,n,a,r,o=e.length,s=0;for(a=0;a<o;a++)55296==(64512&(i=e.charCodeAt(a)))&&a+1<o&&56320==(64512&(n=e.charCodeAt(a+1)))&&(i=65536+(i-55296<<10)+(n-56320),a++),s+=i<128?1:i<2048?2:i<65536?3:4;for(t=new f.Buf8(s),a=r=0;r<s;a++)55296==(64512&(i=e.charCodeAt(a)))&&a+1<o&&56320==(64512&(n=e.charCodeAt(a+1)))&&(i=65536+(i-55296<<10)+(n-56320),a++),i<128?t[r++]=i:(i<2048?t[r++]=192|i>>>6:(i<65536?t[r++]=224|i>>>12:(t[r++]=240|i>>>18,t[r++]=128|i>>>12&63),t[r++]=128|i>>>6&63),t[r++]=128|63&i);return t},i.buf2binstring=function(e){return d(e,e.length)},i.binstring2buf=function(e){for(var t=new f.Buf8(e.length),i=0,n=t.length;i<n;i++)t[i]=e.charCodeAt(i);return t},i.buf2string=function(e,t){var i,n,a,r,o=t||e.length,s=new Array(2*o);for(i=n=0;i<o;)if((a=e[i++])<128)s[n++]=a;else if(4<(r=l[a]))s[n++]=65533,i+=r-1;else{for(a&=2===r?31:3===r?15:7;1<r&&i<o;)a=a<<6|63&e[i++],r--;1<r?s[n++]=65533:a<65536?s[n++]=a:(a-=65536,s[n++]=55296|a>>10&1023,s[n++]=56320|1023&a)}return d(s,n)},i.utf8border=function(e,t){var i;for((t=t||e.length)>e.length&&(t=e.length),i=t-1;0<=i&&128==(192&e[i]);)i--;return i<0?t:0===i?t:i+l[e[i]]>t?i:t}},{"./common":1}],3:[function(e,t,i){"use strict";t.exports=function(e,t,i,n){for(var a=65535&e|0,r=e>>>16&65535|0,o=0;0!==i;){for(i-=o=2e3<i?2e3:i;r=r+(a=a+t[n++]|0)|0,--o;);a%=65521,r%=65521}return a|r<<16|0}},{}],4:[function(e,t,i){"use strict";t.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],5:[function(e,t,i){"use strict";var s=function(){for(var e,t=[],i=0;i<256;i++){e=i;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[i]=e}return t}();t.exports=function(e,t,i,n){var a=s,r=n+i;e^=-1;for(var o=n;o<r;o++)e=e>>>8^a[255&(e^t[o])];return-1^e}},{}],6:[function(e,t,i){"use strict";t.exports=function(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}},{}],7:[function(e,t,i){"use strict";t.exports=function(e,t){var i,n,a,r,o,s,f,l,d,c,u,h,b,m,w,k,_,g,v,p,x,y,S,E,Z;i=e.state,n=e.next_in,E=e.input,a=n+(e.avail_in-5),r=e.next_out,Z=e.output,o=r-(t-e.avail_out),s=r+(e.avail_out-257),f=i.dmax,l=i.wsize,d=i.whave,c=i.wnext,u=i.window,h=i.hold,b=i.bits,m=i.lencode,w=i.distcode,k=(1<<i.lenbits)-1,_=(1<<i.distbits)-1;e:do{b<15&&(h+=E[n++]<<b,b+=8,h+=E[n++]<<b,b+=8),g=m[h&k];t:for(;;){if(h>>>=v=g>>>24,b-=v,0===(v=g>>>16&255))Z[r++]=65535&g;else{if(!(16&v)){if(0==(64&v)){g=m[(65535&g)+(h&(1<<v)-1)];continue t}if(32&v){i.mode=12;break e}e.msg="invalid literal/length code",i.mode=30;break e}p=65535&g,(v&=15)&&(b<v&&(h+=E[n++]<<b,b+=8),p+=h&(1<<v)-1,h>>>=v,b-=v),b<15&&(h+=E[n++]<<b,b+=8,h+=E[n++]<<b,b+=8),g=w[h&_];i:for(;;){if(h>>>=v=g>>>24,b-=v,!(16&(v=g>>>16&255))){if(0==(64&v)){g=w[(65535&g)+(h&(1<<v)-1)];continue i}e.msg="invalid distance code",i.mode=30;break e}if(x=65535&g,b<(v&=15)&&(h+=E[n++]<<b,(b+=8)<v&&(h+=E[n++]<<b,b+=8)),f<(x+=h&(1<<v)-1)){e.msg="invalid distance too far back",i.mode=30;break e}if(h>>>=v,b-=v,(v=r-o)<x){if(d<(v=x-v)&&i.sane){e.msg="invalid distance too far back",i.mode=30;break e}if(S=u,(y=0)===c){if(y+=l-v,v<p){for(p-=v;Z[r++]=u[y++],--v;);y=r-x,S=Z}}else if(c<v){if(y+=l+c-v,(v-=c)<p){for(p-=v;Z[r++]=u[y++],--v;);if(y=0,c<p){for(p-=v=c;Z[r++]=u[y++],--v;);y=r-x,S=Z}}}else if(y+=c-v,v<p){for(p-=v;Z[r++]=u[y++],--v;);y=r-x,S=Z}for(;2<p;)Z[r++]=S[y++],Z[r++]=S[y++],Z[r++]=S[y++],p-=3;p&&(Z[r++]=S[y++],1<p&&(Z[r++]=S[y++]))}else{for(y=r-x;Z[r++]=Z[y++],Z[r++]=Z[y++],Z[r++]=Z[y++],2<(p-=3););p&&(Z[r++]=Z[y++],1<p&&(Z[r++]=Z[y++]))}break}}break}}while(n<a&&r<s);n-=p=b>>3,h&=(1<<(b-=p<<3))-1,e.next_in=n,e.next_out=r,e.avail_in=n<a?a-n+5:5-(n-a),e.avail_out=r<s?s-r+257:257-(r-s),i.hold=h,i.bits=b}},{}],8:[function(e,t,i){"use strict";var z=e("../utils/common"),R=e("./adler32"),N=e("./crc32"),O=e("./inffast"),C=e("./inftrees"),I=1,D=2,T=0,U=-2,F=1,n=852,a=592;function L(e){return(e>>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function r(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new z.Buf16(320),this.work=new z.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function o(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=F,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new z.Buf32(n),t.distcode=t.distdyn=new z.Buf32(a),t.sane=1,t.back=-1,T):U}function s(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,o(e)):U}function f(e,t){var i,n;return e&&e.state?(n=e.state,t<0?(i=0,t=-t):(i=1+(t>>4),t<48&&(t&=15)),t&&(t<8||15<t)?U:(null!==n.window&&n.wbits!==t&&(n.window=null),n.wrap=i,n.wbits=t,s(e))):U}function l(e,t){var i,n;return e?(n=new r,(e.state=n).window=null,(i=f(e,t))!==T&&(e.state=null),i):U}var d,c,u=!0;function H(e){if(u){var t;for(d=new z.Buf32(512),c=new z.Buf32(32),t=0;t<144;)e.lens[t++]=8;for(;t<256;)e.lens[t++]=9;for(;t<280;)e.lens[t++]=7;for(;t<288;)e.lens[t++]=8;for(C(I,e.lens,0,288,d,0,e.work,{bits:9}),t=0;t<32;)e.lens[t++]=5;C(D,e.lens,0,32,c,0,e.work,{bits:5}),u=!1}e.lencode=d,e.lenbits=9,e.distcode=c,e.distbits=5}function j(e,t,i,n){var a,r=e.state;return null===r.window&&(r.wsize=1<<r.wbits,r.wnext=0,r.whave=0,r.window=new z.Buf8(r.wsize)),n>=r.wsize?(z.arraySet(r.window,t,i-r.wsize,r.wsize,0),r.wnext=0,r.whave=r.wsize):(n<(a=r.wsize-r.wnext)&&(a=n),z.arraySet(r.window,t,i-n,a,r.wnext),(n-=a)?(z.arraySet(r.window,t,i-n,n,0),r.wnext=n,r.whave=r.wsize):(r.wnext+=a,r.wnext===r.wsize&&(r.wnext=0),r.whave<r.wsize&&(r.whave+=a))),0}i.inflateReset=s,i.inflateReset2=f,i.inflateResetKeep=o,i.inflateInit=function(e){return l(e,15)},i.inflateInit2=l,i.inflate=function(e,t){var i,n,a,r,o,s,f,l,d,c,u,h,b,m,w,k,_,g,v,p,x,y,S,E,Z=0,B=new z.Buf8(4),A=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!e||!e.state||!e.output||!e.input&&0!==e.avail_in)return U;12===(i=e.state).mode&&(i.mode=13),o=e.next_out,a=e.output,f=e.avail_out,r=e.next_in,n=e.input,s=e.avail_in,l=i.hold,d=i.bits,c=s,u=f,y=T;e:for(;;)switch(i.mode){case F:if(0===i.wrap){i.mode=13;break}for(;d<16;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}if(2&i.wrap&&35615===l){B[i.check=0]=255&l,B[1]=l>>>8&255,i.check=N(i.check,B,2,0),d=l=0,i.mode=2;break}if(i.flags=0,i.head&&(i.head.done=!1),!(1&i.wrap)||(((255&l)<<8)+(l>>8))%31){e.msg="incorrect header check",i.mode=30;break}if(8!=(15&l)){e.msg="unknown compression method",i.mode=30;break}if(d-=4,x=8+(15&(l>>>=4)),0===i.wbits)i.wbits=x;else if(x>i.wbits){e.msg="invalid window size",i.mode=30;break}i.dmax=1<<x,e.adler=i.check=1,i.mode=512&l?10:12,d=l=0;break;case 2:for(;d<16;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}if(i.flags=l,8!=(255&i.flags)){e.msg="unknown compression method",i.mode=30;break}if(57344&i.flags){e.msg="unknown header flags set",i.mode=30;break}i.head&&(i.head.text=l>>8&1),512&i.flags&&(B[0]=255&l,B[1]=l>>>8&255,i.check=N(i.check,B,2,0)),d=l=0,i.mode=3;case 3:for(;d<32;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}i.head&&(i.head.time=l),512&i.flags&&(B[0]=255&l,B[1]=l>>>8&255,B[2]=l>>>16&255,B[3]=l>>>24&255,i.check=N(i.check,B,4,0)),d=l=0,i.mode=4;case 4:for(;d<16;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}i.head&&(i.head.xflags=255&l,i.head.os=l>>8),512&i.flags&&(B[0]=255&l,B[1]=l>>>8&255,i.check=N(i.check,B,2,0)),d=l=0,i.mode=5;case 5:if(1024&i.flags){for(;d<16;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}i.length=l,i.head&&(i.head.extra_len=l),512&i.flags&&(B[0]=255&l,B[1]=l>>>8&255,i.check=N(i.check,B,2,0)),d=l=0}else i.head&&(i.head.extra=null);i.mode=6;case 6:if(1024&i.flags&&(s<(h=i.length)&&(h=s),h&&(i.head&&(x=i.head.extra_len-i.length,i.head.extra||(i.head.extra=new Array(i.head.extra_len)),z.arraySet(i.head.extra,n,r,h,x)),512&i.flags&&(i.check=N(i.check,n,h,r)),s-=h,r+=h,i.length-=h),i.length))break e;i.length=0,i.mode=7;case 7:if(2048&i.flags){if(0===s)break e;for(h=0;x=n[r+h++],i.head&&x&&i.length<65536&&(i.head.name+=String.fromCharCode(x)),x&&h<s;);if(512&i.flags&&(i.check=N(i.check,n,h,r)),s-=h,r+=h,x)break e}else i.head&&(i.head.name=null);i.length=0,i.mode=8;case 8:if(4096&i.flags){if(0===s)break e;for(h=0;x=n[r+h++],i.head&&x&&i.length<65536&&(i.head.comment+=String.fromCharCode(x)),x&&h<s;);if(512&i.flags&&(i.check=N(i.check,n,h,r)),s-=h,r+=h,x)break e}else i.head&&(i.head.comment=null);i.mode=9;case 9:if(512&i.flags){for(;d<16;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}if(l!==(65535&i.check)){e.msg="header crc mismatch",i.mode=30;break}d=l=0}i.head&&(i.head.hcrc=i.flags>>9&1,i.head.done=!0),e.adler=i.check=0,i.mode=12;break;case 10:for(;d<32;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}e.adler=i.check=L(l),d=l=0,i.mode=11;case 11:if(0===i.havedict)return e.next_out=o,e.avail_out=f,e.next_in=r,e.avail_in=s,i.hold=l,i.bits=d,2;e.adler=i.check=1,i.mode=12;case 12:if(5===t||6===t)break e;case 13:if(i.last){l>>>=7&d,d-=7&d,i.mode=27;break}for(;d<3;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}switch(i.last=1&l,d-=1,3&(l>>>=1)){case 0:i.mode=14;break;case 1:if(H(i),i.mode=20,6!==t)break;l>>>=2,d-=2;break e;case 2:i.mode=17;break;case 3:e.msg="invalid block type",i.mode=30}l>>>=2,d-=2;break;case 14:for(l>>>=7&d,d-=7&d;d<32;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}if((65535&l)!=(l>>>16^65535)){e.msg="invalid stored block lengths",i.mode=30;break}if(i.length=65535&l,d=l=0,i.mode=15,6===t)break e;case 15:i.mode=16;case 16:if(h=i.length){if(s<h&&(h=s),f<h&&(h=f),0===h)break e;z.arraySet(a,n,r,h,o),s-=h,r+=h,f-=h,o+=h,i.length-=h;break}i.mode=12;break;case 17:for(;d<14;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}if(i.nlen=257+(31&l),l>>>=5,d-=5,i.ndist=1+(31&l),l>>>=5,d-=5,i.ncode=4+(15&l),l>>>=4,d-=4,286<i.nlen||30<i.ndist){e.msg="too many length or distance symbols",i.mode=30;break}i.have=0,i.mode=18;case 18:for(;i.have<i.ncode;){for(;d<3;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}i.lens[A[i.have++]]=7&l,l>>>=3,d-=3}for(;i.have<19;)i.lens[A[i.have++]]=0;if(i.lencode=i.lendyn,i.lenbits=7,S={bits:i.lenbits},y=C(0,i.lens,0,19,i.lencode,0,i.work,S),i.lenbits=S.bits,y){e.msg="invalid code lengths set",i.mode=30;break}i.have=0,i.mode=19;case 19:for(;i.have<i.nlen+i.ndist;){for(;k=(Z=i.lencode[l&(1<<i.lenbits)-1])>>>16&255,_=65535&Z,!((w=Z>>>24)<=d);){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}if(_<16)l>>>=w,d-=w,i.lens[i.have++]=_;else{if(16===_){for(E=w+2;d<E;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}if(l>>>=w,d-=w,0===i.have){e.msg="invalid bit length repeat",i.mode=30;break}x=i.lens[i.have-1],h=3+(3&l),l>>>=2,d-=2}else if(17===_){for(E=w+3;d<E;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}d-=w,x=0,h=3+(7&(l>>>=w)),l>>>=3,d-=3}else{for(E=w+7;d<E;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}d-=w,x=0,h=11+(127&(l>>>=w)),l>>>=7,d-=7}if(i.have+h>i.nlen+i.ndist){e.msg="invalid bit length repeat",i.mode=30;break}for(;h--;)i.lens[i.have++]=x}}if(30===i.mode)break;if(0===i.lens[256]){e.msg="invalid code -- missing end-of-block",i.mode=30;break}if(i.lenbits=9,S={bits:i.lenbits},y=C(I,i.lens,0,i.nlen,i.lencode,0,i.work,S),i.lenbits=S.bits,y){e.msg="invalid literal/lengths set",i.mode=30;break}if(i.distbits=6,i.distcode=i.distdyn,S={bits:i.distbits},y=C(D,i.lens,i.nlen,i.ndist,i.distcode,0,i.work,S),i.distbits=S.bits,y){e.msg="invalid distances set",i.mode=30;break}if(i.mode=20,6===t)break e;case 20:i.mode=21;case 21:if(6<=s&&258<=f){e.next_out=o,e.avail_out=f,e.next_in=r,e.avail_in=s,i.hold=l,i.bits=d,O(e,u),o=e.next_out,a=e.output,f=e.avail_out,r=e.next_in,n=e.input,s=e.avail_in,l=i.hold,d=i.bits,12===i.mode&&(i.back=-1);break}for(i.back=0;k=(Z=i.lencode[l&(1<<i.lenbits)-1])>>>16&255,_=65535&Z,!((w=Z>>>24)<=d);){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}if(k&&0==(240&k)){for(g=w,v=k,p=_;k=(Z=i.lencode[p+((l&(1<<g+v)-1)>>g)])>>>16&255,_=65535&Z,!(g+(w=Z>>>24)<=d);){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}l>>>=g,d-=g,i.back+=g}if(l>>>=w,d-=w,i.back+=w,i.length=_,0===k){i.mode=26;break}if(32&k){i.back=-1,i.mode=12;break}if(64&k){e.msg="invalid literal/length code",i.mode=30;break}i.extra=15&k,i.mode=22;case 22:if(i.extra){for(E=i.extra;d<E;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}i.length+=l&(1<<i.extra)-1,l>>>=i.extra,d-=i.extra,i.back+=i.extra}i.was=i.length,i.mode=23;case 23:for(;k=(Z=i.distcode[l&(1<<i.distbits)-1])>>>16&255,_=65535&Z,!((w=Z>>>24)<=d);){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}if(0==(240&k)){for(g=w,v=k,p=_;k=(Z=i.distcode[p+((l&(1<<g+v)-1)>>g)])>>>16&255,_=65535&Z,!(g+(w=Z>>>24)<=d);){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}l>>>=g,d-=g,i.back+=g}if(l>>>=w,d-=w,i.back+=w,64&k){e.msg="invalid distance code",i.mode=30;break}i.offset=_,i.extra=15&k,i.mode=24;case 24:if(i.extra){for(E=i.extra;d<E;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}i.offset+=l&(1<<i.extra)-1,l>>>=i.extra,d-=i.extra,i.back+=i.extra}if(i.offset>i.dmax){e.msg="invalid distance too far back",i.mode=30;break}i.mode=25;case 25:if(0===f)break e;if(h=u-f,i.offset>h){if((h=i.offset-h)>i.whave&&i.sane){e.msg="invalid distance too far back",i.mode=30;break}h>i.wnext?(h-=i.wnext,b=i.wsize-h):b=i.wnext-h,h>i.length&&(h=i.length),m=i.window}else m=a,b=o-i.offset,h=i.length;for(f<h&&(h=f),f-=h,i.length-=h;a[o++]=m[b++],--h;);0===i.length&&(i.mode=21);break;case 26:if(0===f)break e;a[o++]=i.length,f--,i.mode=21;break;case 27:if(i.wrap){for(;d<32;){if(0===s)break e;s--,l|=n[r++]<<d,d+=8}if(u-=f,e.total_out+=u,i.total+=u,u&&(e.adler=i.check=i.flags?N(i.check,a,u,o-u):R(i.check,a,u,o-u)),u=f,(i.flags?l:L(l))!==i.check){e.msg="incorrect data check",i.mode=30;break}d=l=0}i.mode=28;case 28:if(i.wrap&&i.flags){for(;d<32;){if(0===s)break e;s--,l+=n[r++]<<d,d+=8}if(l!==(4294967295&i.total)){e.msg="incorrect length check",i.mode=30;break}d=l=0}i.mode=29;case 29:y=1;break e;case 30:y=-3;break e;case 31:return-4;case 32:default:return U}return e.next_out=o,e.avail_out=f,e.next_in=r,e.avail_in=s,i.hold=l,i.bits=d,(i.wsize||u!==e.avail_out&&i.mode<30&&(i.mode<27||4!==t))&&j(e,e.output,e.next_out,u-e.avail_out)?(i.mode=31,-4):(c-=e.avail_in,u-=e.avail_out,e.total_in+=c,e.total_out+=u,i.total+=u,i.wrap&&u&&(e.adler=i.check=i.flags?N(i.check,a,u,e.next_out-u):R(i.check,a,u,e.next_out-u)),e.data_type=i.bits+(i.last?64:0)+(12===i.mode?128:0)+(20===i.mode||15===i.mode?256:0),(0===c&&0===u||4===t)&&y===T&&(y=-5),y)},i.inflateEnd=function(e){if(!e||!e.state)return U;var t=e.state;return t.window&&(t.window=null),e.state=null,T},i.inflateGetHeader=function(e,t){var i;return e&&e.state?0==(2&(i=e.state).wrap)?U:((i.head=t).done=!1,T):U},i.inflateSetDictionary=function(e,t){var i,n=t.length;return e&&e.state?0!==(i=e.state).wrap&&11!==i.mode?U:11===i.mode&&R(1,t,n,0)!==i.check?-3:j(e,t,n,n)?(i.mode=31,-4):(i.havedict=1,T):U},i.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":1,"./adler32":3,"./crc32":5,"./inffast":7,"./inftrees":9}],9:[function(e,t,i){"use strict";var I=e("../utils/common"),D=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],T=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],U=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],F=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];t.exports=function(e,t,i,n,a,r,o,s){var f,l,d,c,u,h,b,m,w,k=s.bits,_=0,g=0,v=0,p=0,x=0,y=0,S=0,E=0,Z=0,B=0,A=null,z=0,R=new I.Buf16(16),N=new I.Buf16(16),O=null,C=0;for(_=0;_<=15;_++)R[_]=0;for(g=0;g<n;g++)R[t[i+g]]++;for(x=k,p=15;1<=p&&0===R[p];p--);if(p<x&&(x=p),0===p)return a[r++]=20971520,a[r++]=20971520,s.bits=1,0;for(v=1;v<p&&0===R[v];v++);for(x<v&&(x=v),_=E=1;_<=15;_++)if(E<<=1,(E-=R[_])<0)return-1;if(0<E&&(0===e||1!==p))return-1;for(N[1]=0,_=1;_<15;_++)N[_+1]=N[_]+R[_];for(g=0;g<n;g++)0!==t[i+g]&&(o[N[t[i+g]]++]=g);if(0===e?(A=O=o,h=19):1===e?(A=D,z-=257,O=T,C-=257,h=256):(A=U,O=F,h=-1),_=v,u=r,S=g=B=0,d=-1,c=(Z=1<<(y=x))-1,1===e&&852<Z||2===e&&592<Z)return 1;for(;;){for(b=_-S,o[g]<h?(m=0,w=o[g]):o[g]>h?(m=O[C+o[g]],w=A[z+o[g]]):(m=96,w=0),f=1<<_-S,v=l=1<<y;a[u+(B>>S)+(l-=f)]=b<<24|m<<16|w|0,0!==l;);for(f=1<<_-1;B&f;)f>>=1;if(0!==f?(B&=f-1,B+=f):B=0,g++,0==--R[_]){if(_===p)break;_=t[i+o[g]]}if(x<_&&(B&c)!==d){for(0===S&&(S=x),u+=v,E=1<<(y=_-S);y+S<p&&!((E-=R[y+S])<=0);)y++,E<<=1;if(Z+=1<<y,1===e&&852<Z||2===e&&592<Z)return 1;a[d=B&c]=x<<24|y<<16|u-r|0}}return 0!==B&&(a[u+B]=_-S<<24|64<<16|0),s.bits=x,0}},{"../utils/common":1}],10:[function(e,t,i){"use strict";t.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],11:[function(e,t,i){"use strict";t.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},{}],"/lib/inflate.js":[function(e,t,i){"use strict";var c=e("./zlib/inflate"),u=e("./utils/common"),h=e("./utils/strings"),b=e("./zlib/constants"),n=e("./zlib/messages"),a=e("./zlib/zstream"),r=e("./zlib/gzheader"),m=Object.prototype.toString;function o(e){if(!(this instanceof o))return new o(e);this.options=u.assign({chunkSize:16384,windowBits:0,to:""},e||{});var t=this.options;t.raw&&0<=t.windowBits&&t.windowBits<16&&(t.windowBits=-t.windowBits,0===t.windowBits&&(t.windowBits=-15)),!(0<=t.windowBits&&t.windowBits<16)||e&&e.windowBits||(t.windowBits+=32),15<t.windowBits&&t.windowBits<48&&0==(15&t.windowBits)&&(t.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new a,this.strm.avail_out=0;var i=c.inflateInit2(this.strm,t.windowBits);if(i!==b.Z_OK)throw new Error(n[i]);if(this.header=new r,c.inflateGetHeader(this.strm,this.header),t.dictionary&&("string"==typeof t.dictionary?t.dictionary=h.string2buf(t.dictionary):"[object ArrayBuffer]"===m.call(t.dictionary)&&(t.dictionary=new Uint8Array(t.dictionary)),t.raw&&(i=c.inflateSetDictionary(this.strm,t.dictionary))!==b.Z_OK))throw new Error(n[i])}function s(e,t){var i=new o(t);if(i.push(e,!0),i.err)throw i.msg||n[i.err];return i.result}o.prototype.push=function(e,t){var i,n,a,r,o,s=this.strm,f=this.options.chunkSize,l=this.options.dictionary,d=!1;if(this.ended)return!1;n=t===~~t?t:!0===t?b.Z_FINISH:b.Z_NO_FLUSH,"string"==typeof e?s.input=h.binstring2buf(e):"[object ArrayBuffer]"===m.call(e)?s.input=new Uint8Array(e):s.input=e,s.next_in=0,s.avail_in=s.input.length;do{if(0===s.avail_out&&(s.output=new u.Buf8(f),s.next_out=0,s.avail_out=f),(i=c.inflate(s,b.Z_NO_FLUSH))===b.Z_NEED_DICT&&l&&(i=c.inflateSetDictionary(this.strm,l)),i===b.Z_BUF_ERROR&&!0===d&&(i=b.Z_OK,d=!1),i!==b.Z_STREAM_END&&i!==b.Z_OK)return this.onEnd(i),!(this.ended=!0);s.next_out&&(0!==s.avail_out&&i!==b.Z_STREAM_END&&(0!==s.avail_in||n!==b.Z_FINISH&&n!==b.Z_SYNC_FLUSH)||("string"===this.options.to?(a=h.utf8border(s.output,s.next_out),r=s.next_out-a,o=h.buf2string(s.output,a),s.next_out=r,s.avail_out=f-r,r&&u.arraySet(s.output,s.output,a,r,0),this.onData(o)):this.onData(u.shrinkBuf(s.output,s.next_out)))),0===s.avail_in&&0===s.avail_out&&(d=!0)}while((0<s.avail_in||0===s.avail_out)&&i!==b.Z_STREAM_END);return i===b.Z_STREAM_END&&(n=b.Z_FINISH),n===b.Z_FINISH?(i=c.inflateEnd(this.strm),this.onEnd(i),this.ended=!0,i===b.Z_OK):n!==b.Z_SYNC_FLUSH||(this.onEnd(b.Z_OK),!(s.avail_out=0))},o.prototype.onData=function(e){this.chunks.push(e)},o.prototype.onEnd=function(e){e===b.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=u.flattenChunks(this.chunks)),this.chunks=[],this.err=e,this.msg=this.strm.msg},i.Inflate=o,i.inflate=s,i.inflateRaw=function(e,t){return(t=t||{}).raw=!0,s(e,t)},i.ungzip=s},{"./utils/common":1,"./utils/strings":2,"./zlib/constants":4,"./zlib/gzheader":6,"./zlib/inflate":8,"./zlib/messages":10,"./zlib/zstream":11}]},{},[])("/lib/inflate.js")});
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-002-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-002-ref.html
new file mode 100644
index 0000000..8694b5f54
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-002-ref.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>CSS Reference: String value of list-style-type with outside position</title>
+  <link rel="author" title="Oriol Brufau" href="mailto:obrufau@gmail.com">
+  <style>
+    .list { list-style: none }
+    .list > ::before {
+      content: "";
+      display: inline-block;
+      width: 0px;
+      direction: rtl;
+      white-space: pre;
+    }
+    .list > :nth-child(2)::before { content: "foo" }
+    .list > :nth-child(3)::before { content: "foobar"; }
+    .list > :nth-child(4)::before { content: "some very long text that is not going to fit and will overflow"; }
+  </style>
+</head>
+<body>
+  <ol class="list">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+  </ol>
+  <ul class="list">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+  </ul>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-002.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-002.html
new file mode 100644
index 0000000..6f00d8a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-002.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>String value of list-style-type with outside position</title>
+  <link rel="author" title="Oriol Brufau" href="mailto:obrufau@gmail.com">
+  <link rel="help" href="https://drafts.csswg.org/css-lists-3/#valdef-list-style-type-string">
+  <link rel="match" href="list-style-type-string-002-ref.html">
+  <meta name="assert" content="This test checks that list-style-type can set the marker string when the marker is positioned outside.">
+  <style>
+    .list { list-style-type: "" }
+    .list > :nth-child(2) { list-style-type: "foo" }
+    .list > :nth-child(3) { list-style-type: "foobar"; }
+    .list > :nth-child(4) { list-style-type: "some very long text that is not going to fit and will overflow"; }
+  </style>
+</head>
+<body>
+  <ol class="list">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+  </ol>
+  <ul class="list">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+  </ul>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-003-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-003-ref.html
new file mode 100644
index 0000000..ea3601b9
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-003-ref.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>CSS Reference: String value of list-style-type with RTL direction</title>
+  <link rel="author" title="Oriol Brufau" href="mailto:obrufau@gmail.com">
+  <style>
+    .list {
+      list-style: none;
+      direction: rtl;
+    }
+    .list > ::before {
+      content: "";
+      display: inline-block;
+      width: 0px;
+      direction: ltr;
+      white-space: pre;
+    }
+    .list > :nth-child(2)::before { content: "foo" }
+    .list > :nth-child(3)::before { content: "foobar"; }
+    .list > :nth-child(4)::before { content: "some very long text that is not going to fit and will overflow"; }
+  </style>
+</head>
+<body>
+  <ol class="list">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+  </ol>
+  <ul class="list">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+  </ul>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-003.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-003.html
new file mode 100644
index 0000000..94467ca1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-003.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>String value of list-style-type with RTL direction</title>
+  <link rel="author" title="Oriol Brufau" href="mailto:obrufau@gmail.com">
+  <link rel="help" href="https://drafts.csswg.org/css-lists-3/#valdef-list-style-type-string">
+  <link rel="match" href="list-style-type-string-003-ref.html">
+  <meta name="assert" content="This test checks that list-style-type can set the marker string when the direction is RTL.">
+  <style>
+    .list {
+      list-style-type: "";
+      direction: rtl;
+    }
+    .list > :nth-child(2) { list-style-type: "foo" }
+    .list > :nth-child(3) { list-style-type: "foobar"; }
+    .list > :nth-child(4) { list-style-type: "some very long text that is not going to fit and will overflow"; }
+  </style>
+</head>
+<body>
+  <ol class="list">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+  </ol>
+  <ul class="list">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+  </ul>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-004-ref.html
new file mode 100644
index 0000000..3a828b2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-004-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>CSS Test: String value of list-style-type changing dynamically</title>
+  <link rel="author" title="Oriol Brufau" href="mailto:obrufau@gmail.com">
+  <style>
+    .list { list-style-type: "bar" }
+  </style>
+</head>
+<body>
+  <ol class="list">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+  </ol>
+  <ul class="list">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+  </ul>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-004.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-004.html
new file mode 100644
index 0000000..922a4ece
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-004.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html lang="en" class="reftest-wait">
+<head>
+  <meta charset="UTF-8">
+  <title>CSS Test: String value of list-style-type changing dynamically</title>
+  <link rel="author" title="Oriol Brufau" href="mailto:obrufau@gmail.com">
+  <link rel="help" href="https://drafts.csswg.org/css-lists-3/#valdef-list-style-type-string">
+  <link rel="match" href="list-style-type-string-004-ref.html">
+  <meta name="assert" content="This test checks that the marker text is updated when list-style-type changes.">
+  <style>
+    .list { list-style-type: "foo" }
+  </style>
+</head>
+<body>
+  <ol class="list">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+  </ol>
+  <ul class="list">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+  </ul>
+  <script src="/common/reftest-wait.js"></script>
+  <script>
+    "use strict";
+    addEventListener("load", function() {
+      requestAnimationFrame(() => {
+        for (const list of document.querySelectorAll(".list")) {
+          list.style.listStyleType = '"bar"';
+        }
+        takeScreenshot();
+      });
+    }, {once: true});
+  </script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-005-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-005-ref.html
new file mode 100644
index 0000000..703ceff
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-005-ref.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>CSS Reference: String value of list-style-type with bidi text</title>
+  <link rel="author" title="Oriol Brufau" href="mailto:obrufau@gmail.com">
+  <style>
+    .list {
+      width: 50%;
+      box-sizing: border-box;
+      float: left;
+      padding-inline-start: 14ch;
+      margin: 0;
+      line-height: 1.6;
+      list-style: none;
+    }
+    .rtl { direction: rtl }
+    .list > ::before {
+      unicode-bidi: isolate;
+      display: inline-flex;
+      flex-direction: row-reverse;
+      width: 0px;
+      white-space: pre;
+    }
+    .list > :nth-child(1)::before { content: "\627 \644 " }
+    .list > :nth-child(2)::before { content: "\61 \627 \644 " }
+    .list > :nth-child(3)::before { content: "\627 \644 \62 " }
+    .list > :nth-child(4)::before { content: "\61 \627 \644 \62 " }
+    .list > :nth-child(5)::before { content: "\61 \62 \627 \644 " }
+    .list > :nth-child(6)::before { content: "\627 \644 \61 \62 " }
+    .list > :nth-child(7)::before { content: "\31 \627 \644 " }
+    .list > :nth-child(8)::before { content: "\627 \644 \32 " }
+    .list > :nth-child(9)::before { content: "\31 \627 \644 \32 " }
+    .list > :nth-child(10)::before { content: "\31 \32 \627 \644 " }
+    .list > :nth-child(11)::before { content: "\627 \644 \31 \32 " }
+  </style>
+</head>
+<body>
+  <ol class="list ltr">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+    <li>item 5</li>
+    <li>item 6</li>
+    <li>item 7</li>
+    <li>item 8</li>
+    <li>item 9</li>
+    <li>item 10</li>
+    <li>item 11</li>
+  </ol>
+  <ul class="list rtl">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+    <li>item 5</li>
+    <li>item 6</li>
+    <li>item 7</li>
+    <li>item 8</li>
+    <li>item 9</li>
+    <li>item 10</li>
+    <li>item 11</li>
+  </ul>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-005a.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-005a.html
new file mode 100644
index 0000000..725cdee
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-005a.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>String value of list-style-type with bidi text</title>
+  <link rel="author" title="Oriol Brufau" href="mailto:obrufau@gmail.com">
+  <link rel="help" href="https://drafts.csswg.org/css-lists-3/#valdef-list-style-type-string">
+  <link rel="match" href="list-style-type-string-005-ref.html">
+  <meta name="assert" content="This test checks that the bidi algorithm runs for markers.">
+  <style>
+    .list {
+      width: 50%;
+      box-sizing: border-box;
+      float: left;
+      padding-inline-start: 14ch;
+      margin: 0;
+      line-height: 1.6;
+    }
+    .rtl { direction: rtl }
+    .list > :nth-child(1) { list-style-type: "\627 \644 " }
+    .list > :nth-child(2) { list-style-type: "\61 \627 \644 " }
+    .list > :nth-child(3) { list-style-type: "\627 \644 \62 " }
+    .list > :nth-child(4) { list-style-type: "\61 \627 \644 \62 " }
+    .list > :nth-child(5) { list-style-type: "\61 \62 \627 \644 " }
+    .list > :nth-child(6) { list-style-type: "\627 \644 \61 \62 " }
+    .list > :nth-child(7) { list-style-type: "\31 \627 \644 " }
+    .list > :nth-child(8) { list-style-type: "\627 \644 \32 " }
+    .list > :nth-child(9) { list-style-type: "\31 \627 \644 \32 " }
+    .list > :nth-child(10) { list-style-type: "\31 \32 \627 \644 " }
+    .list > :nth-child(11) { list-style-type: "\627 \644 \31 \32 " }
+  </style>
+</head>
+<body>
+  <ol class="list ltr">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+    <li>item 5</li>
+    <li>item 6</li>
+    <li>item 7</li>
+    <li>item 8</li>
+    <li>item 9</li>
+    <li>item 10</li>
+    <li>item 11</li>
+  </ol>
+  <ul class="list rtl">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+    <li>item 5</li>
+    <li>item 6</li>
+    <li>item 7</li>
+    <li>item 8</li>
+    <li>item 9</li>
+    <li>item 10</li>
+    <li>item 11</li>
+  </ul>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-005b.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-005b.html
new file mode 100644
index 0000000..ca984b6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-005b.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>String value of list-style-type with bidi text in multicol</title>
+  <link rel="author" title="Oriol Brufau" href="mailto:obrufau@gmail.com">
+  <link rel="help" href="https://drafts.csswg.org/css-lists-3/#valdef-list-style-type-string">
+  <link rel="match" href="list-style-type-string-005-ref.html">
+  <meta name="assert" content="This test checks that the bidi algorithm runs for markers in multicol.">
+  <style>
+    body { column-count: 2 }
+    .list {
+      padding-inline-start: 14ch;
+      margin: 0;
+      line-height: 1.6;
+    }
+    .rtl { direction: rtl }
+    .list > :nth-child(1) { list-style-type: "\627 \644 " }
+    .list > :nth-child(2) { list-style-type: "\61 \627 \644 " }
+    .list > :nth-child(3) { list-style-type: "\627 \644 \62 " }
+    .list > :nth-child(4) { list-style-type: "\61 \627 \644 \62 " }
+    .list > :nth-child(5) { list-style-type: "\61 \62 \627 \644 " }
+    .list > :nth-child(6) { list-style-type: "\627 \644 \61 \62 " }
+    .list > :nth-child(7) { list-style-type: "\31 \627 \644 " }
+    .list > :nth-child(8) { list-style-type: "\627 \644 \32 " }
+    .list > :nth-child(9) { list-style-type: "\31 \627 \644 \32 " }
+    .list > :nth-child(10) { list-style-type: "\31 \32 \627 \644 " }
+    .list > :nth-child(11) { list-style-type: "\627 \644 \31 \32 " }
+  </style>
+</head>
+<body>
+  <ol class="list ltr">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+    <li>item 5</li>
+    <li>item 6</li>
+    <li>item 7</li>
+    <li>item 8</li>
+    <li>item 9</li>
+    <li>item 10</li>
+    <li>item 11</li>
+  </ol>
+  <ul class="list rtl">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+    <li>item 5</li>
+    <li>item 6</li>
+    <li>item 7</li>
+    <li>item 8</li>
+    <li>item 9</li>
+    <li>item 10</li>
+    <li>item 11</li>
+  </ul>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-006-ref.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-006-ref.html
new file mode 100644
index 0000000..5c0a5132
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-006-ref.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>CSS Reference: String value of list-style-type with bidi text inside</title>
+  <link rel="author" title="Oriol Brufau" href="mailto:obrufau@gmail.com">
+  <style>
+    .list {
+      width: 50%;
+      box-sizing: border-box;
+      float: left;
+      padding-inline-start: 14ch;
+      margin: 0;
+      line-height: 1.6;
+      list-style: none;
+    }
+    .rtl { direction: rtl }
+    .list > ::before { unicode-bidi: isolate }
+    .list > :nth-child(1)::before { content: "\627 \644 " }
+    .list > :nth-child(2)::before { content: "\61 \627 \644 " }
+    .list > :nth-child(3)::before { content: "\627 \644 \62 " }
+    .list > :nth-child(4)::before { content: "\61 \627 \644 \62 " }
+    .list > :nth-child(5)::before { content: "\61 \62 \627 \644 " }
+    .list > :nth-child(6)::before { content: "\627 \644 \61 \62 " }
+    .list > :nth-child(7)::before { content: "\31 \627 \644 " }
+    .list > :nth-child(8)::before { content: "\627 \644 \32 " }
+    .list > :nth-child(9)::before { content: "\31 \627 \644 \32 " }
+    .list > :nth-child(10)::before { content: "\31 \32 \627 \644 " }
+    .list > :nth-child(11)::before { content: "\627 \644 \31 \32 " }
+  </style>
+</head>
+<body>
+  <ol class="list ltr">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+    <li>item 5</li>
+    <li>item 6</li>
+    <li>item 7</li>
+    <li>item 8</li>
+    <li>item 9</li>
+    <li>item 10</li>
+    <li>item 11</li>
+  </ol>
+  <ul class="list rtl">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+    <li>item 5</li>
+    <li>item 6</li>
+    <li>item 7</li>
+    <li>item 8</li>
+    <li>item 9</li>
+    <li>item 10</li>
+    <li>item 11</li>
+  </ul>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-006.html b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-006.html
new file mode 100644
index 0000000..7f6904b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-style-type-string-006.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <title>String value of list-style-type with bidi text inside</title>
+  <link rel="author" title="Oriol Brufau" href="mailto:obrufau@gmail.com">
+  <link rel="help" href="https://drafts.csswg.org/css-lists-3/#valdef-list-style-type-string">
+  <link rel="match" href="list-style-type-string-006-ref.html">
+  <meta name="assert" content="This test checks that the bidi algorithm runs for markers with unicode-bidi:isolate, so that the text inside the marker is isolated from the text outside. This is only relevant when the marker is positioned inside.">
+  <style>
+    .list {
+      list-style-position: inside;
+      width: 50%;
+      box-sizing: border-box;
+      float: left;
+      padding-inline-start: 14ch;
+      margin: 0;
+      line-height: 1.6;
+    }
+    .rtl { direction: rtl }
+    .list > :nth-child(1) { list-style-type: "\627 \644 " }
+    .list > :nth-child(2) { list-style-type: "\61 \627 \644 " }
+    .list > :nth-child(3) { list-style-type: "\627 \644 \62 " }
+    .list > :nth-child(4) { list-style-type: "\61 \627 \644 \62 " }
+    .list > :nth-child(5) { list-style-type: "\61 \62 \627 \644 " }
+    .list > :nth-child(6) { list-style-type: "\627 \644 \61 \62 " }
+    .list > :nth-child(7) { list-style-type: "\31 \627 \644 " }
+    .list > :nth-child(8) { list-style-type: "\627 \644 \32 " }
+    .list > :nth-child(9) { list-style-type: "\31 \627 \644 \32 " }
+    .list > :nth-child(10) { list-style-type: "\31 \32 \627 \644 " }
+    .list > :nth-child(11) { list-style-type: "\627 \644 \31 \32 " }
+  </style>
+</head>
+<body>
+  <ol class="list ltr">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+    <li>item 5</li>
+    <li>item 6</li>
+    <li>item 7</li>
+    <li>item 8</li>
+    <li>item 9</li>
+    <li>item 10</li>
+    <li>item 11</li>
+  </ol>
+  <ul class="list rtl">
+    <li>item 1</li>
+    <li>item 2</li>
+    <li>item 3</li>
+    <li>item 4</li>
+    <li>item 5</li>
+    <li>item 6</li>
+    <li>item 7</li>
+    <li>item 8</li>
+    <li>item 9</li>
+    <li>item 10</li>
+    <li>item 11</li>
+  </ul>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/list-style-type-computed-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/list-style-type-computed-expected.txt
index eabf33a..2ee6f4c9 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/list-style-type-computed-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/list-style-type-computed-expected.txt
@@ -14,8 +14,8 @@
 PASS Property list-style-type value 'georgian' computes to 'georgian'
 PASS Property list-style-type value 'lower-alpha' computes to 'lower-alpha'
 PASS Property list-style-type value 'upper-alpha' computes to 'upper-alpha'
-FAIL Property list-style-type value '"marker string"' computes to '"marker string"' assert_equals: expected "\"marker string\"" but got "disc"
-FAIL Property list-style-type value '"Note: "' computes to '"Note: "' assert_equals: expected "\"Note: \"" but got "disc"
+PASS Property list-style-type value '"marker string"' computes to '"marker string"'
+PASS Property list-style-type value '"Note: "' computes to '"Note: "'
 FAIL Property list-style-type value 'counter-Style-Name' computes to 'counter-Style-Name' assert_equals: expected "counter-Style-Name" but got "disc"
 FAIL Property list-style-type value 'CounterStyleName' computes to 'CounterStyleName' assert_equals: expected "CounterStyleName" but got "disc"
 FAIL Property list-style-type value 'symbols(cyclic "string")' computes to 'symbols(cyclic "string")' assert_equals: expected "symbols(cyclic \"string\")" but got "disc"
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/list-style-type-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/list-style-type-valid-expected.txt
index b19f911..1687a52 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/list-style-type-valid-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-lists/parsing/list-style-type-valid-expected.txt
@@ -14,8 +14,8 @@
 PASS e.style['list-style-type'] = "georgian" should set the property value
 PASS e.style['list-style-type'] = "lower-alpha" should set the property value
 PASS e.style['list-style-type'] = "upper-alpha" should set the property value
-FAIL e.style['list-style-type'] = "\"marker string\"" should set the property value assert_not_equals: property should be set got disallowed value ""
-FAIL e.style['list-style-type'] = "\"Note: \"" should set the property value assert_not_equals: property should be set got disallowed value ""
+PASS e.style['list-style-type'] = "\"marker string\"" should set the property value
+PASS e.style['list-style-type'] = "\"Note: \"" should set the property value
 FAIL e.style['list-style-type'] = "counter-Style-Name" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['list-style-type'] = "CounterStyleName" should set the property value assert_not_equals: property should be set got disallowed value ""
 FAIL e.style['list-style-type'] = "symbols(cyclic \"string\")" should set the property value assert_not_equals: property should be set got disallowed value ""
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/list-style-type-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/list-style-type-expected.txt
index af42e021..59617c5d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/list-style-type-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/list-style-type-expected.txt
@@ -12,7 +12,7 @@
 PASS Setting 'list-style-type' to a position throws TypeError
 PASS Setting 'list-style-type' to a URL throws TypeError
 PASS Setting 'list-style-type' to a transform throws TypeError
-FAIL 'list-style-type' does not supported '"Note: "' assert_not_equals: Unsupported value must not be null got disallowed value null
+PASS 'list-style-type' does not supported '"Note: "'
 FAIL 'list-style-type' does not supported 'symbols("*" "A" "B" "C")' assert_not_equals: Unsupported value must not be null got disallowed value null
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/common/entities.json b/third_party/blink/web_tests/external/wpt/html/the-xhtml-syntax/parsing-xhtml-documents/support/entities.json
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/common/entities.json
rename to third_party/blink/web_tests/external/wpt/html/the-xhtml-syntax/parsing-xhtml-documents/support/entities.json
diff --git a/third_party/blink/web_tests/external/wpt/html/the-xhtml-syntax/parsing-xhtml-documents/support/xhtml-mathml-dtd-entity.htm b/third_party/blink/web_tests/external/wpt/html/the-xhtml-syntax/parsing-xhtml-documents/support/xhtml-mathml-dtd-entity.htm
index 76165509..af3fe90 100644
--- a/third_party/blink/web_tests/external/wpt/html/the-xhtml-syntax/parsing-xhtml-documents/support/xhtml-mathml-dtd-entity.htm
+++ b/third_party/blink/web_tests/external/wpt/html/the-xhtml-syntax/parsing-xhtml-documents/support/xhtml-mathml-dtd-entity.htm
@@ -38,7 +38,7 @@
 
   function run(row) {
     var xhr = new XMLHttpRequest();
-    xhr.open("GET", "/common/entities.json");
+    xhr.open("GET", "entities.json");
     xhr.onload = function () {
       var entitiesJSON = JSON.parse(xhr.response);
       setupTests(entitiesJSON, row[1], row[2], row[0], row[3]);
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/PaymentValidationErrors/retry-shows-error-member-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/PaymentValidationErrors/retry-shows-error-member-manual.https.html
index 9d25e9e..9135520 100644
--- a/third_party/blink/web_tests/external/wpt/payment-request/PaymentValidationErrors/retry-shows-error-member-manual.https.html
+++ b/third_party/blink/web_tests/external/wpt/payment-request/PaymentValidationErrors/retry-shows-error-member-manual.https.html
@@ -45,6 +45,6 @@
   </li>
 </ol>
 <small>
-  If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a>
+  If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
   and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">owners</a>.
 </small>
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/PaymentValidationErrors/retry-shows-payer-member-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/PaymentValidationErrors/retry-shows-payer-member-manual.https.html
index ad5ad72..f8115e6 100644
--- a/third_party/blink/web_tests/external/wpt/payment-request/PaymentValidationErrors/retry-shows-payer-member-manual.https.html
+++ b/third_party/blink/web_tests/external/wpt/payment-request/PaymentValidationErrors/retry-shows-payer-member-manual.https.html
@@ -60,6 +60,6 @@
   </li>
 </ol>
 <small>
-  If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a>
+  If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
   and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">owners</a>.
 </small>
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/PaymentValidationErrors/retry-shows-shippingAddress-member-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/PaymentValidationErrors/retry-shows-shippingAddress-member-manual.https.html
index 837ab79..dc92945 100644
--- a/third_party/blink/web_tests/external/wpt/payment-request/PaymentValidationErrors/retry-shows-shippingAddress-member-manual.https.html
+++ b/third_party/blink/web_tests/external/wpt/payment-request/PaymentValidationErrors/retry-shows-shippingAddress-member-manual.https.html
@@ -93,6 +93,6 @@
   </li>
 </ol>
 <small>
-  If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a>
+  If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
   and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">owners</a>.
 </small>
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-response/retry-method-manual.https.html b/third_party/blink/web_tests/external/wpt/payment-request/payment-response/retry-method-manual.https.html
index 0af89450..fc0a0427 100644
--- a/third_party/blink/web_tests/external/wpt/payment-request/payment-response/retry-method-manual.https.html
+++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-response/retry-method-manual.https.html
@@ -291,6 +291,6 @@
   </li>
 </ol>
 <small>
-  If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a>
-  and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>.
+  If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
+  and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">owners</a>.
 </small>
diff --git a/third_party/blink/web_tests/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..cfcbb9d
--- /dev/null
+++ b/third_party/blink/web_tests/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance.html b/third_party/blink/web_tests/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance.html
new file mode 100644
index 0000000..4d69fd4
--- /dev/null
+++ b/third_party/blink/web_tests/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+testRunner.waitUntilDone();
+</script>
+<script src="../../forms/resources/picker-common.js"></script>
+</head>
+<body style="background-color: #eeffff;">
+<input type=date id=date value="10000-12-31" list="suggestions" style="width: 200px;">
+<datalist id=suggestions>
+    <option>2012-01-00</option> <!--invalid-->
+    <option>foo</option> <!--invalid-->
+    <option label="Today">2012-01-01</option>
+    <option label="Tomorrow">2012-01-02</option>
+    <option>2012-01-03</option>
+    <option>2012-01-04</option>
+    <option>2012-01-05</option>
+    <option>2012-01-06</option>
+    <option>2012-01-07</option>
+    <option>2012-01-08</option>
+    <option>2012-01-09</option>
+    <option>2012-01-10</option>
+    <option>2012-01-11</option>
+    <option>2012-01-12</option>
+    <option>2012-01-13</option>
+    <option>2012-01-14</option>
+    <option>2012-01-15</option>
+    <option>2012-01-16</option>
+</datalist>
+
+<script>
+openPicker(document.getElementById('date'), finishTest);
+
+function finishTest() {
+  popupWindow.focus();
+  eventSender.keyDown('ArrowDown');
+  testRunner.notifyDone();
+}
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/basic-a11y-test.js b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/basic-a11y-test.js
index c9f853b..59cbeba 100644
--- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/basic-a11y-test.js
+++ b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/basic-a11y-test.js
@@ -14,6 +14,10 @@
       'sensors',
     ];
 
+  //TODO(crbug.com/1004940): exclude scrollable-region-focusable for performance.monitor only
+  const NO_SCROLLABLE_REGION_FOCUSABLE_RULESET = {
+    'scrollable-region-focusable': { enabled: false, },
+  };
 
   for (const location of locationsToTest)
     await loadViewAndTestElementViolations(location);
@@ -24,6 +28,7 @@
     TestRunner.addResult(`Tests accessibility in the ${view} view using the axe-core linter.`);
     await UI.viewManager.showView(view);
     const widget = await UI.viewManager.view(view).widget();
-    await AxeCoreTestRunner.runValidation(widget.element);
+    const ruleset = view === 'performance.monitor' ? NO_SCROLLABLE_REGION_FOCUSABLE_RULESET : {};
+    await AxeCoreTestRunner.runValidation(widget.element, ruleset);
   }
 })();
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console-a11y-test-expected.txt b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console-a11y-test-expected.txt
index 41fdf3b..af66fb6 100644
--- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console-a11y-test-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console-a11y-test-expected.txt
@@ -1,4 +1,23 @@
 Tests accessibility in the console using the axe-core linter.
-aXe violations: []
+aXe violations: [
+  {
+    "ruleDescription": "Ensures every ARIA input field has an accessible name",
+    "helpUrl": "https://dequeuniversity.com/rules/axe/3.3/aria-input-field-name?application=axeAPI",
+    "ruleId": "aria-input-field-name",
+    "impact": "serious",
+    "failedNodes": [
+      {
+        "target": [
+          [
+            ".console-main-toolbar",
+            ".toolbar-input-prompt"
+          ]
+        ],
+        "html": "<div class=\"toolbar-input-prompt text-prompt\" role=\"textbox\" contenteditable=\"plaintext-only\" data-placeholder=\"Filter\" aria-placeholder=\"Filter\"></div>",
+        "failureSummary": "Fix any of the following:\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute or the title attribute is empty"
+      }
+    ]
+  }
+]
 
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console-a11y-test.js b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console-a11y-test.js
index 38ebeeb..ab76399 100644
--- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console-a11y-test.js
+++ b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/console-a11y-test.js
@@ -10,6 +10,7 @@
   await UI.viewManager.showView('console');
   const widget = await UI.viewManager.view('console').widget();
 
+  //TODO(crbug.com/1004940): expected.txt file has 'aria-input-field-name' exceptions
   await AxeCoreTestRunner.runValidation(widget.element);
   TestRunner.completeTest();
 })();
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/memory/heap-profiler-a11y-test-expected.txt b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/memory/heap-profiler-a11y-test-expected.txt
index f7b1929..8e34d0c6 100644
--- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/memory/heap-profiler-a11y-test-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/memory/heap-profiler-a11y-test-expected.txt
@@ -1,4 +1,20 @@
 Tests accessibility in heap profiler using the axe-core linter.
-aXe violations: []
+aXe violations: [
+  {
+    "ruleDescription": "Ensures role attribute has an appropriate value for the element",
+    "helpUrl": "https://dequeuniversity.com/rules/axe/3.3/aria-allowed-role?application=axeAPI",
+    "ruleId": "aria-allowed-role",
+    "impact": "minor",
+    "failedNodes": [
+      {
+        "target": [
+          "form"
+        ],
+        "html": "<form role=\"radiogroup\" aria-label=\"Select profiling type\">",
+        "failureSummary": "Fix any of the following:\n  ARIA role radiogroup  is not allowed for given element"
+      }
+    ]
+  }
+]
 
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/memory/heap-profiler-a11y-test.js b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/memory/heap-profiler-a11y-test.js
index 33175c6..1a5116d 100644
--- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/memory/heap-profiler-a11y-test.js
+++ b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/memory/heap-profiler-a11y-test.js
@@ -37,6 +37,7 @@
 
   await UI.viewManager.showView('heap_profiler');
   const widget = await UI.viewManager.view('heap_profiler').widget();
+  //TODO(crbug.com/1004940): expected.txt file has 'aria-allowed-role' exceptions
   await AxeCoreTestRunner.runValidation(widget.element);
   TestRunner.completeTest();
 })();
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/performance/performance-pane-a11y-test-expected.txt b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/performance/performance-pane-a11y-test-expected.txt
index 8864297..609c327 100644
--- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/performance/performance-pane-a11y-test-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/performance/performance-pane-a11y-test-expected.txt
@@ -6,11 +6,49 @@
 
 Running: testBottomUpView
 Tests accessibility in performance BottomUp view using the axe-core linter
-aXe violations: []
+aXe violations: [
+  {
+    "ruleDescription": "Ensures every ARIA input field has an accessible name",
+    "helpUrl": "https://dequeuniversity.com/rules/axe/3.3/aria-input-field-name?application=axeAPI",
+    "ruleId": "aria-input-field-name",
+    "impact": "serious",
+    "failedNodes": [
+      {
+        "target": [
+          [
+            ".widget.vbox[slot=\"insertion-point-main\"] > .toolbar",
+            ".toolbar-input-prompt"
+          ]
+        ],
+        "html": "<div class=\"toolbar-input-prompt text-prompt\" role=\"textbox\" contenteditable=\"plaintext-only\" data-placeholder=\"Filter\" aria-placeholder=\"Filter bottom-up\"></div>",
+        "failureSummary": "Fix any of the following:\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute or the title attribute is empty"
+      }
+    ]
+  }
+]
 
 
 Running: testCallTreeView
 Tests accessibility in performance CallTree view using the axe-core linter
-aXe violations: []
+aXe violations: [
+  {
+    "ruleDescription": "Ensures every ARIA input field has an accessible name",
+    "helpUrl": "https://dequeuniversity.com/rules/axe/3.3/aria-input-field-name?application=axeAPI",
+    "ruleId": "aria-input-field-name",
+    "impact": "serious",
+    "failedNodes": [
+      {
+        "target": [
+          [
+            ".widget.vbox[slot=\"insertion-point-main\"] > .toolbar",
+            "div[aria-placeholder=\"Filter\\ call\\ tree\"]"
+          ]
+        ],
+        "html": "<div class=\"toolbar-input-prompt text-prompt\" role=\"textbox\" contenteditable=\"plaintext-only\" data-placeholder=\"Filter\" aria-placeholder=\"Filter call tree\"></div>",
+        "failureSummary": "Fix any of the following:\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute or the title attribute is empty"
+      }
+    ]
+  }
+]
 
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/performance/performance-pane-a11y-test.js b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/performance/performance-pane-a11y-test.js
index c266c9c..659b8bec 100644
--- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/performance/performance-pane-a11y-test.js
+++ b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/performance/performance-pane-a11y-test.js
@@ -66,6 +66,7 @@
         model.timelineModel().minimumRecordTime(),
         model.timelineModel().maximumRecordTime()));
 
+    //TODO(crbug.com/1004940): expected.txt file has 'aria-input-field-name' exceptions
     await AxeCoreTestRunner.runValidation(detailsTab.element);
   }
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/dom-breakpoints-pane-a11y-test-expected.txt b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/dom-breakpoints-pane-a11y-test-expected.txt
index ac3e8bce..65648a9 100644
--- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/dom-breakpoints-pane-a11y-test-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/dom-breakpoints-pane-a11y-test-expected.txt
@@ -6,31 +6,31 @@
 aXe violations: [
   {
     "ruleDescription": "Ensures every form element has a label",
-    "helpUrl": "https://dequeuniversity.com/rules/axe/3.0/label?application=axeAPI",
+    "helpUrl": "https://dequeuniversity.com/rules/axe/3.3/label?application=axeAPI",
     "ruleId": "label",
     "impact": "critical",
     "failedNodes": [
       {
         "target": [
           [
-            "div:nth-child(7) > div.vbox.flex-auto",
-            ".widget.vbox > .breakpoint-list > div:nth-child(1) > span",
+            ".flex-none.flex-auto.vbox:nth-child(7) > .flex-auto.vbox",
+            ".breakpoint-entry:nth-child(1) > span[is=\"dt-checkbox\"]",
             "#ui-checkbox-label9"
           ]
         ],
-        "html": "<input type=\"checkbox\" id=\"ui-checkbox-label9\" aria-label=\"Subtree modified: div#rootElement\">",
-        "failureSummary": "Fix any of the following:\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty or not visible\n  Form element does not have an implicit (wrapped) <label>\n  Form element does not have an explicit <label>\n  Element has no title attribute or the title attribute is empty"
+        "html": "<input type=\"checkbox\" id=\"ui-checkbox-label9\">",
+        "failureSummary": "Fix any of the following:\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Form element does not have an implicit (wrapped) <label>\n  Form element does not have an explicit <label>\n  Element has no title attribute or the title attribute is empty"
       },
       {
         "target": [
           [
-            "div:nth-child(7) > div.vbox.flex-auto",
-            ".widget.vbox > .breakpoint-list > div:nth-child(2) > span",
+            ".flex-none.flex-auto.vbox:nth-child(7) > .flex-auto.vbox",
+            ".breakpoint-entry:nth-child(2) > span[is=\"dt-checkbox\"]",
             "#ui-checkbox-label10"
           ]
         ],
-        "html": "<input type=\"checkbox\" id=\"ui-checkbox-label10\" aria-label=\"Node removed: div#hostElement\">",
-        "failureSummary": "Fix any of the following:\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty or not visible\n  Form element does not have an implicit (wrapped) <label>\n  Form element does not have an explicit <label>\n  Element has no title attribute or the title attribute is empty"
+        "html": "<input type=\"checkbox\" id=\"ui-checkbox-label10\">",
+        "failureSummary": "Fix any of the following:\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Form element does not have an implicit (wrapped) <label>\n  Form element does not have an explicit <label>\n  Element has no title attribute or the title attribute is empty"
       }
     ]
   }
diff --git a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/dom-breakpoints-pane-a11y-test.js b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/dom-breakpoints-pane-a11y-test.js
index 886b6db..10ae74fa 100644
--- a/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/dom-breakpoints-pane-a11y-test.js
+++ b/third_party/blink/web_tests/http/tests/devtools/a11y-axe-core/sources/dom-breakpoints-pane-a11y-test.js
@@ -36,6 +36,7 @@
   TestRunner.addResult(
       'Running the axe-core linter on the DOM breakpoints pane.');
 
+  //TODO(crbug.com/1004940): expected.txt file has 'label' exceptions
   await AxeCoreTestRunner.runValidation(domBreakpointContainer.element);
   TestRunner.completeTest();
 })();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/inline-styles-scripts-locations-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/inline-styles-scripts-locations-expected.txt
index d42bbd0..4fdc34ab 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/inline-styles-scripts-locations-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/inline-styles-scripts-locations-expected.txt
@@ -22,21 +22,11 @@
 </body>
 </html>
 
-The following output for css locations on the unformatted source is currently wrong due to BUG(1005708).
 Scanning 21 lines for css locations. Note that location line/column numbers are zero-based.
 uiLocation 8:0 resolves to: 8:0 (css)
 uiLocation 9:0 resolves to: 9:0 (css)
 uiLocation 10:0 resolves to: 10:0 (css)
 uiLocation 11:0 resolves to: 11:0 (css)
-uiLocation 12:0 resolves to: 12:0 (not in css range 7:11-11:4)
-uiLocation 13:0 resolves to: 13:0 (not in css range 7:11-11:4)
-uiLocation 14:0 resolves to: 14:0 (not in css range 7:11-11:4)
-uiLocation 15:0 resolves to: 15:0 (not in css range 7:11-11:4)
-uiLocation 16:0 resolves to: 16:0 (not in css range 7:11-11:4)
-uiLocation 17:0 resolves to: 17:0 (not in css range 7:11-11:4)
-uiLocation 18:0 resolves to: 18:0 (not in css range 17:11-17:32)
-uiLocation 19:0 resolves to: 19:0 (not in css range 17:11-17:32)
-uiLocation 20:0 resolves to: 20:0 (not in css range 17:11-17:32)
 Scanning 21 lines for script locations. Note that location line/column numbers are zero-based.
 uiLocation 14:0 resolves to: 14:0 (script)
 uiLocation 15:0 resolves to: 15:0 (script)
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/inline-styles-scripts-locations.js b/third_party/blink/web_tests/http/tests/devtools/sources/inline-styles-scripts-locations.js
index c4fc066..b1fcd811b 100644
--- a/third_party/blink/web_tests/http/tests/devtools/sources/inline-styles-scripts-locations.js
+++ b/third_party/blink/web_tests/http/tests/devtools/sources/inline-styles-scripts-locations.js
@@ -13,7 +13,6 @@
   TestRunner.addResult(`Content:\n${content}`);
   const sourceText = new TextUtils.Text(content);
 
-  TestRunner.addResult(`The following output for css locations on the unformatted source is currently wrong due to BUG(1005708).`)
   await dumpLocations("css", sourceText.lineCount(), source);
   await dumpLocations("script", sourceText.lineCount(), source);
 
@@ -49,9 +48,8 @@
       if (location instanceof SDK.CSSLocation) {
         const h = location.header();
         if (!h) return "invalid css header";
-        const {endLine, endColumn} = await computeEndPosition(h);
-        if (!h.containsLocation(location.lineNumber, location.columnNumber, endLine, endColumn))
-          return `not in css range ${h.startLine}:${h.startColumn}-${endLine}:${endColumn}`;
+        if (!h.containsLocation(location.lineNumber, location.columnNumber))
+          return `not in css range ${h.startLine}:${h.startColumn}-${h.endLine}:${h.endColumn}`;
         return "css";
       }
       if (location instanceof SDK.DebuggerModel.Location) {
@@ -63,14 +61,6 @@
       }
       return "invalid (wrong instance)"
     }
-    async function computeEndPosition(header) {
-      const content = await header.requestContent();
-      const contentText = new TextUtils.Text(content);
-      const {lineNumber, columnNumber} = contentText.positionFromOffset(header.contentLength);
-      const endLine = lineNumber + header.startLine;
-      const endColumn = columnNumber + (lineNumber == 0 ? header.startColumn : 0);
-      return {endLine, endColumn};
-    }
   }
 
 
diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
index f8d7a14..82d14229 100644
--- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
+++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -144,6 +144,11 @@
     getter reason
     getter wasClean
     method constructor
+interface CompressionStream
+    attribute @@toStringTag
+    getter readable
+    getter writable
+    method constructor
 interface ContentIndex
     attribute @@toStringTag
     method add
diff --git a/third_party/blink/web_tests/inspector-protocol/css/css-style-sheet-events-expected.txt b/third_party/blink/web_tests/inspector-protocol/css/css-style-sheet-events-expected.txt
index 6991d2c0..bcfc06b 100644
--- a/third_party/blink/web_tests/inspector-protocol/css/css-style-sheet-events-expected.txt
+++ b/third_party/blink/web_tests/inspector-protocol/css/css-style-sheet-events-expected.txt
@@ -4,6 +4,8 @@
     params : {
         header : {
             disabled : false
+            endColumn : 6
+            endLine : 4
             frameId : <string>
             isInline : false
             length : <number>
diff --git a/third_party/blink/web_tests/installedapp/getinstalledrelatedapps.html b/third_party/blink/web_tests/installedapp/getinstalledrelatedapps.html
index e48c9df..626a338 100644
--- a/third_party/blink/web_tests/installedapp/getinstalledrelatedapps.html
+++ b/third_party/blink/web_tests/installedapp/getinstalledrelatedapps.html
@@ -29,10 +29,10 @@
       [{platform: 'play', url: null, id: 'com.test'},
        {platform: 'itunes', url: 'https://itunes.apple.com/', id: null}],
       [{platform: 'play', url: null, id: 'com.test'}]);
-  // TODO(mgiuca): The |url| field should be omitted from the result, not ''.
+
   return navigator.getInstalledRelatedApps().then(result => {
     assert_array_relatedapplication_equals(
-        result, [{platform: 'play', url: '', id: 'com.test'}]);
+        result, [{platform: 'play', id: 'com.test'}]);
   });
 }, 'getInstalledRelatedApps with related and installed apps (no url)');
 
@@ -46,12 +46,12 @@
        {platform: 'itunes', url: 'https://itunes.apple.com/', id: null}],
       [{platform: 'play', url: null, id: 'com.test'},
        {platform: 'itunes', url: 'https://itunes.apple.com/', id: null}]);
-  // TODO(mgiuca): The null fields should be omitted from the result, not ''.
+
   return navigator.getInstalledRelatedApps().then(result => {
     assert_array_relatedapplication_equals(
         result,
-        [{platform: 'play', url: '', id: 'com.test'},
-         {platform: 'itunes', url: 'https://itunes.apple.com/', id: ''}]);
+        [{platform: 'play', id: 'com.test'},
+         {platform: 'itunes', url: 'https://itunes.apple.com/'}]);
   });
 }, 'getInstalledRelatedApps with multiple related and installed apps');
 
diff --git a/third_party/blink/web_tests/platform/linux/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/linux/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..6598cc5
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..994851b9
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..7644716
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-wrap-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-wrap-expected.png
index 7037d0a..46f1fd1 100644
--- a/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-wrap-expected.png
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/fast/forms/validation-bubble-appearance-wrap-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..1612bcc
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..a8fb94f
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.11/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..6bfcf05
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..4587f29
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.12/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..6bfcf05
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac10.12/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-retina/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/mac-retina/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..76365fa
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-retina/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..6bfcf05
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-retina/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/mac/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..76365fa
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..6bfcf05
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png b/third_party/blink/web_tests/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
new file mode 100644
index 0000000..8a73c538
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/controls-refresh-high-contrast/fast/forms/controls-new-ui-high-contrast/date-suggestion-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
index c974944f..5e5121a 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -113,6 +113,11 @@
 [Worker]     getter reason
 [Worker]     getter wasClean
 [Worker]     method constructor
+[Worker] interface CompressionStream
+[Worker]     attribute @@toStringTag
+[Worker]     getter readable
+[Worker]     getter writable
+[Worker]     method constructor
 [Worker] interface ContentIndex
 [Worker]     attribute @@toStringTag
 [Worker]     method add
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index 75c3b13..c427bb27 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -1109,6 +1109,11 @@
     getter data
     method constructor
     method initCompositionEvent
+interface CompressionStream
+    attribute @@toStringTag
+    getter readable
+    getter writable
+    method constructor
 interface ComputedAccessibleNode
     attribute @@toStringTag
     getter atomic
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
index cad8c04f..ccf0496 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -113,6 +113,11 @@
 [Worker]     getter reason
 [Worker]     getter wasClean
 [Worker]     method constructor
+[Worker] interface CompressionStream
+[Worker]     attribute @@toStringTag
+[Worker]     getter readable
+[Worker]     getter writable
+[Worker]     method constructor
 [Worker] interface ContentIndex
 [Worker]     attribute @@toStringTag
 [Worker]     method add
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index a88e5d1..712dea85 100644
--- a/third_party/freetype/README.chromium
+++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: VER-2-10-1-67-g1e9229f0f
-Revision: 1e9229f0fcb46fd4cd8e0fdc48fb4a44ddb7a8a1
+Version: VER-2-10-1-68-g545a481a7
+Revision: 545a481a74a3c3b70af8928793a01a84f8b0ee9b
 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
          JPEG Group) licenses"
 License File: src/docs/FTL.TXT
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids
index 79c3e27..60aa21e9 100644
--- a/tools/gritsettings/resource_ids
+++ b/tools/gritsettings/resource_ids
@@ -172,34 +172,37 @@
   "chrome/browser/resources/usb_internals/resources.grd": {
     "includes": [14030],
   },
+  "components/sync/driver/resources.grd": {
+    "includes": [14050],
+  },
   # END chrome/ WebUI resources section
 
   # START chrome/ miscellaneous section.
   "chrome/android/features/test_dummy/internal/resources/resources.grd": {
-    "includes": [14070],
+    "includes": [14090],
   },
   "chrome/common/common_resources.grd": {
-    "includes": [14160],
+    "includes": [14180],
   },
   "chrome/credential_provider/gaiacp/gaia_resources.grd": {
-    "includes": [14180],
-    "messages": [14190],
+    "includes": [14200],
+    "messages": [14210],
   },
   "chrome/renderer/resources/renderer_resources.grd": {
-    "includes": [14230],
-    "structures": [14340],
+    "includes": [14250],
+    "structures": [14360],
   },
   "chrome/test/data/webui_test_resources.grd": {
-    "includes": [14380],
+    "includes": [14400],
   },
   # END chrome/ miscellaneous section.
 
   # START chromeos/ section.
   "chromeos/chromeos_strings.grd": {
-    "messages": [14510],
+    "messages": [14530],
   },
   "chromeos/resources/chromeos_resources.grd": {
-    "includes": [14560],
+    "includes": [14580],
   },
   # END chromeos/ section.
 
@@ -208,27 +211,27 @@
   # We only use one file depending on whether we're building Chromium or
   # Google Chrome.
   "components/components_chromium_strings.grd": {
-    "messages": [15040],
+    "messages": [15060],
   },
   "components/components_google_chrome_strings.grd": {
-    "messages": [15040],
+    "messages": [15060],
   },
 
   "components/components_locale_settings.grd": {
-    "includes": [15060],
-    "messages": [15070],
+    "includes": [15080],
+    "messages": [15090],
   },
   "components/components_strings.grd": {
-    "messages": [15100],
+    "messages": [15120],
   },
   "components/omnibox/resources/omnibox_resources.grd": {
-    "includes": [17190],
+    "includes": [17210],
   },
   "components/policy/resources/policy_templates.grd": {
-    "structures": [17200],
+    "structures": [17220],
   },
   "components/resources/components_resources.grd": {
-    "includes": [17210],
+    "includes": [17230],
   },
   "components/resources/components_scaled_resources.grd": {
     "structures": [17400],
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 38854dc..26b9699 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -4707,6 +4707,17 @@
   <int value="1" label="By JavaScript"/>
 </enum>
 
+<enum name="BackForwardCacheEvictedReason">
+  <int value="0" label="Timeout"/>
+  <int value="1" label="Cache limit"/>
+  <int value="2" label="JavaScript execution"/>
+  <int value="3" label="Renderer process killed"/>
+  <int value="4" label="Renderer process crashed"/>
+  <int value="5" label="Dialog"/>
+  <int value="6" label="Granted media stream access"/>
+  <int value="7" label="Scheduler tracked feature used"/>
+</enum>
+
 <enum name="BackForwardCacheHistoryNavigationOutcome">
   <int value="0" label="Restored"/>
   <int value="1" label="Not cached"/>
@@ -7683,6 +7694,7 @@
   <int value="29" label="kHostCache"/>
   <int value="30" label="kTpmAttestationKeys"/>
   <int value="31" label="kStrikes"/>
+  <int value="32" label="kLeakedCredentials"/>
 </enum>
 
 <enum name="ChromeChannelForHistogram">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index dfc66aea..bc36d8d 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -6674,16 +6674,6 @@
   </summary>
 </histogram>
 
-<histogram name="Arc.PlayStoreLaunch.TimeDelta" units="ms"
-    expires_after="2021-11-01">
-  <owner>khmel@google.com</owner>
-  <owner>yusukes@google.com</owner>
-  <summary>
-    Elapsed time from the when the user launches the Play Store app and to when
-    the Play Store window is shown to the user.
-  </summary>
-</histogram>
-
 <histogram name="Arc.PlayStoreSearch.QueryTime" units="ms"
     expires_after="2020-03-22">
   <owner>hejq@chromium.org</owner>
@@ -6717,7 +6707,7 @@
   </summary>
 </histogram>
 
-<histogram name="Arc.PlayStoreShown.TimeDelta" units="ms" expires_after="M82">
+<histogram name="Arc.PlayStoreShown.TimeDelta" units="ms" expires_after="M81">
 <!-- Name completed by histogram_suffixes name="ArcUserTypes" -->
 
   <owner>yusukes@google.com</owner>
@@ -6908,42 +6898,6 @@
   <summary>Action of ARC++ Graphics Tracing tool.</summary>
 </histogram>
 
-<histogram name="Arc.UiAvailable.AlreadyProvisioned.TimeDelta" units="ms"
-    expires_after="2021-11-01">
-<!-- Name completed by histogram_suffixes name="ArcUserTypes" -->
-
-  <owner>khmel@google.com</owner>
-  <owner>yusukes@google.com</owner>
-  <summary>
-    Elapsed time from the when ARC++ is started in already provisioned state to
-    when the ARC is available for the user.
-  </summary>
-</histogram>
-
-<histogram name="Arc.UiAvailable.InSessionProvisioning.TimeDelta" units="ms"
-    expires_after="2021-11-01">
-<!-- Name completed by histogram_suffixes name="ArcUserTypes" -->
-
-  <owner>khmel@google.com</owner>
-  <owner>yusukes@google.com</owner>
-  <summary>
-    Elapsed time from the when ARC++ is opted in from the user's session to when
-    the ARC is available for the user.
-  </summary>
-</histogram>
-
-<histogram name="Arc.UiAvailable.OobeProvisioning.TimeDelta" units="ms"
-    expires_after="2021-11-01">
-<!-- Name completed by histogram_suffixes name="ArcUserTypes" -->
-
-  <owner>khmel@google.com</owner>
-  <owner>yusukes@google.com</owner>
-  <summary>
-    Elapsed time from the when ARC++ is opted in from OOBE to when the ARC is
-    available for the user.
-  </summary>
-</histogram>
-
 <histogram name="Arc.UserInteraction" enum="ArcUserInteraction"
     expires_after="2020-03-29">
   <owner>jhorwich@chromium.org</owner>
@@ -6971,8 +6925,7 @@
   </summary>
 </histogram>
 
-<histogram name="ArcAuth.CheckinAttempts" units="attempts"
-    expires_after="2021-11-01">
+<histogram name="ArcAuth.CheckinAttempts" units="attempts" expires_after="M81">
   <owner>elijahtaylor@chromium.org</owner>
   <summary>
     Number of attempts done while waiting for the check-in task to be completed.
@@ -6981,7 +6934,7 @@
   </summary>
 </histogram>
 
-<histogram name="ArcAuth.CheckinTime" units="ms" expires_after="2021-11-01">
+<histogram name="ArcAuth.CheckinTime" units="ms" expires_after="2020-03-08">
   <owner>elijahtaylor@chromium.org</owner>
   <summary>
     Elapsed time waiting for the check-in task to be completed. This is recorded
@@ -6997,7 +6950,7 @@
   </summary>
 </histogram>
 
-<histogram name="ArcAuth.SignInTime" units="ms" expires_after="2021-11-01">
+<histogram name="ArcAuth.SignInTime" units="ms" expires_after="M77">
   <owner>elijahtaylor@chromium.org</owner>
   <summary>Elapsed time waiting for GMS sign-in to complete.</summary>
 </histogram>
@@ -13200,6 +13153,20 @@
   </summary>
 </histogram>
 
+<histogram name="BackForwardCache.HistoryNavigationOutcome.EvictedReason"
+    enum="BackForwardCacheEvictedReason" expires_after="2020-10-01">
+  <owner>bfcache-dev@chromium.org</owner>
+  <owner>hajimehoshi@chromium.org</owner>
+  <summary>
+    When navigating back to a page in the session history, this records the
+    reason why the page is evicted from the back-forward cache. Eviction can
+    happen when the page can no longer be held by the cache. This is a breakdown
+    metric of BackForwardCache.HistoryNavigationOutcome's 'Evicted' value.
+
+    Recording starts as of M79.
+  </summary>
+</histogram>
+
 <histogram base="true" name="BackgroundFetch.EventDispatchFailure.Dispatch"
     enum="ServiceWorkerStatusCode">
 <!-- Name completed by histogram_suffixes name="BackgroundFetchEvents" -->
@@ -115035,6 +115002,84 @@
   </summary>
 </histogram>
 
+<histogram name="QuicSession.HeaderCompressionRatioHpackReceived" units="%"
+    expires_after="2020-10-08">
+  <owner>bnc@chromium.org</owner>
+  <owner>src/net/quic/OWNERS</owner>
+  <summary>
+    Header compression ratio as percentage for received headers using HPACK.
+  </summary>
+</histogram>
+
+<histogram name="QuicSession.HeaderCompressionRatioHpackSent" units="%"
+    expires_after="2020-10-08">
+  <owner>bnc@chromium.org</owner>
+  <owner>src/net/quic/OWNERS</owner>
+  <summary>
+    Header compression ratio as percentage for sent headers using HPACK.
+  </summary>
+</histogram>
+
+<histogram name="QuicSession.HeaderCompressionRatioQpackReceived" units="%"
+    expires_after="2020-10-08">
+  <owner>bnc@chromium.org</owner>
+  <owner>src/net/quic/OWNERS</owner>
+  <summary>
+    Header compression ratio as percentage for received headers using QPACK.
+  </summary>
+</histogram>
+
+<histogram name="QuicSession.HeaderCompressionRatioQpackSent" units="%"
+    expires_after="2020-10-08">
+  <owner>bnc@chromium.org</owner>
+  <owner>src/net/quic/OWNERS</owner>
+  <summary>
+    Header compression ratio as percentage for sent headers using QPACK.
+  </summary>
+</histogram>
+
+<histogram name="QuicSession.Qpack.HeaderListCountWhenBlockedStreamLimited"
+    units="count" expires_after="2020-10-08">
+  <owner>bnc@chromium.org</owner>
+  <owner>src/net/quic/OWNERS</owner>
+  <summary>
+    The ordinality of a header list within a connection during the encoding of
+    which unacknowledged dynamic table entries could not be referenced due to
+    the limit on the number of blocked streams.
+  </summary>
+</histogram>
+
+<histogram name="QuicSession.Qpack.HeaderListCountWhenInsertionBlocked"
+    units="count" expires_after="2020-10-08">
+  <owner>bnc@chromium.org</owner>
+  <owner>src/net/quic/OWNERS</owner>
+  <summary>
+    The ordinality of a header list within a connection during the encoding of
+    which at least one dynamic table insertion was blocked.
+  </summary>
+</histogram>
+
+<histogram name="QuicSession.Qpack.HeaderListCountWhenInsertionNotBlocked"
+    units="count" expires_after="2020-10-08">
+  <owner>bnc@chromium.org</owner>
+  <owner>src/net/quic/OWNERS</owner>
+  <summary>
+    The ordinality of a header list within a connection during the encoding of
+    which no dynamic table insertion was blocked.
+  </summary>
+</histogram>
+
+<histogram name="QuicSession.Qpack.HeaderListCountWhenNotBlockedStreamLimited"
+    units="count" expires_after="2020-10-08">
+  <owner>bnc@chromium.org</owner>
+  <owner>src/net/quic/OWNERS</owner>
+  <summary>
+    The ordinality of a header list within a connection during the encoding of
+    which the limit on the number of blocked streams did not prevent referencing
+    unacknowledged dynamic table entries.
+  </summary>
+</histogram>
+
 <histogram name="Quota.AgeOfDataInDays" units="days" expires_after="2020-03-29">
   <owner>jarrydg@chromium.org</owner>
   <summary>
@@ -164546,9 +164591,6 @@
   <affected-histogram name="Arc.Provisioning.TimeDelta.Success"/>
   <affected-histogram name="Arc.Reauthorization.Result"/>
   <affected-histogram name="Arc.StateByUserType"/>
-  <affected-histogram name="Arc.UiAvailable.AlreadyProvisioned.TimeDelta"/>
-  <affected-histogram name="Arc.UiAvailable.InSessionProvisioning.TimeDelta"/>
-  <affected-histogram name="Arc.UiAvailable.OobeProvisioning.TimeDelta"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="AsyncDNSPref" separator="_">
diff --git a/tools/perf/benchmarks/system_health_smoke_test.py b/tools/perf/benchmarks/system_health_smoke_test.py
index 6764d31d..98f1130e 100644
--- a/tools/perf/benchmarks/system_health_smoke_test.py
+++ b/tools/perf/benchmarks/system_health_smoke_test.py
@@ -163,6 +163,7 @@
 
   # crbug.com/1008001
   'system_health.memory_desktop/browse:tools:sheets:2019',
+  'system_health.memory_desktop/browse:tools:maps:2019',
 
   # The following tests are disabled because they are disabled on the perf
   # waterfall (using tools/perf/expectations.config) on one platform or another.
diff --git a/tools/perf/core/results_processor/compute_metrics.py b/tools/perf/core/results_processor/compute_metrics.py
index a56b8c0..4625ef0 100644
--- a/tools/perf/core/results_processor/compute_metrics.py
+++ b/tools/perf/core/results_processor/compute_metrics.py
@@ -25,43 +25,35 @@
 
 
 def _PoolWorker(test_result):
-  try:
-    metrics = [tag['value'] for tag in test_result['tags']
-               if tag['key'] == 'tbmv2']
-    html_trace = test_result['outputArtifacts'][HTML_TRACE_NAME]
-    html_local_path = html_trace['filePath']
-    html_remote_url = html_trace['remoteUrl']
+  metrics = [tag['value'] for tag in test_result['tags']
+             if tag['key'] == 'tbmv2']
+  html_trace = test_result['outputArtifacts'][HTML_TRACE_NAME]
+  html_local_path = html_trace['filePath']
+  html_remote_url = html_trace.get('remoteUrl')
 
-    logging.info('%s: Starting to compute metrics on trace.',
-                 test_result['testPath'])
-    start = time.time()
-    # The timeout needs to be coordinated with the Swarming IO timeout for the
-    # task that runs this code. If this timeout is longer or close in length
-    # to the swarming IO timeout then we risk being forcibly killed for not
-    # producing any output. Note that this could be fixed by periodically
-    # outputting logs while waiting for metrics to be calculated.
-    TEN_MINUTES = 60 * 10
-    mre_result = metric_runner.RunMetricOnSingleTrace(
-        html_local_path, metrics, canonical_url=html_remote_url,
-        timeout=TEN_MINUTES,
-        extra_import_options={'trackDetailedModelStats': True})
-    logging.info('%s: Computing metrics took %.3f seconds.' % (
-        test_result['testPath'], time.time() - start))
+  logging.info('%s: Starting to compute metrics on trace.',
+               test_result['testPath'])
+  start = time.time()
+  # The timeout needs to be coordinated with the Swarming IO timeout for the
+  # task that runs this code. If this timeout is longer or close in length
+  # to the swarming IO timeout then we risk being forcibly killed for not
+  # producing any output. Note that this could be fixed by periodically
+  # outputting logs while waiting for metrics to be calculated.
+  TEN_MINUTES = 60 * 10
+  mre_result = metric_runner.RunMetricOnSingleTrace(
+      html_local_path, metrics, canonical_url=html_remote_url,
+      timeout=TEN_MINUTES,
+      extra_import_options={'trackDetailedModelStats': True})
+  logging.info('%s: Computing metrics took %.3f seconds.' % (
+      test_result['testPath'], time.time() - start))
 
-    if mre_result.failures:
-      test_result['status'] = 'FAIL'
-      for f in mre_result.failures:
-        logging.error('Failure recorded for test %s: %s',
-                      test_result['testPath'], f)
+  if mre_result.failures:
+    test_result['status'] = 'FAIL'
+    for f in mre_result.failures:
+      logging.error('Failure recorded for test %s: %s',
+                    test_result['testPath'], f)
 
-    return mre_result.pairs.get('histograms', [])
-  except Exception:  # pylint: disable=broad-except
-    # logging exception here is the only way to get a stack trace since
-    # multiprocessing's pool implementation does not save that data. See
-    # crbug.com/953365.
-    logging.exception('%s: Exception while calculating metric' %
-                      test_result['testPath'])
-    raise
+  return mre_result.pairs.get('histograms', [])
 
 
 def ComputeTBMv2Metrics(intermediate_results):
@@ -104,9 +96,6 @@
 
     work_list.append(test_result)
 
-  if not work_list:
-    return histogram_dicts
-
   for dicts in util.ApplyInParallel(_PoolWorker, work_list):
     histogram_dicts += dicts
 
diff --git a/tools/perf/core/results_processor/processor.py b/tools/perf/core/results_processor/processor.py
index a04eb0b..d16a0c7 100644
--- a/tools/perf/core/results_processor/processor.py
+++ b/tools/perf/core/results_processor/processor.py
@@ -155,9 +155,6 @@
       remote_name = '/'.join([run_identifier, result['testPath'], name])
       work_list.append((artifact, remote_name))
 
-  if not work_list:
-    return
-
   def PoolUploader(work_item):
     artifact, remote_name = work_item
     artifact['remoteUrl'] = cloud_storage.Insert(
diff --git a/tools/perf/core/results_processor/util.py b/tools/perf/core/results_processor/util.py
index e0558b4..2bbe332 100644
--- a/tools/perf/core/results_processor/util.py
+++ b/tools/perf/core/results_processor/util.py
@@ -18,6 +18,9 @@
     A generator over results. The order of results might not match the
     order of the arguments in the work_list.
   """
+  if not work_list:
+    return
+
   try:
     # Note that this is speculatively halved as an attempt to fix
     # crbug.com/953365.
@@ -28,8 +31,18 @@
     cpu_count = 4
   pool = ThreadPool(min(cpu_count, len(work_list)))
 
+  def function_with_try(arg):
+    try:
+      return function(arg)
+    except Exception:  # pylint: disable=broad-except
+      # logging exception here is the only way to get a stack trace since
+      # multiprocessing's pool implementation does not save that data. See
+      # crbug.com/953365.
+      logging.exception('Exception while running %s' % function.__name__)
+      raise
+
   try:
-    for result in pool.imap_unordered(function, work_list):
+    for result in pool.imap_unordered(function_with_try, work_list):
       yield result
     pool.close()
     pool.join()
diff --git a/tools/perf/core/results_processor/util_unittest.py b/tools/perf/core/results_processor/util_unittest.py
index dab0607..a7af11b38 100644
--- a/tools/perf/core/results_processor/util_unittest.py
+++ b/tools/perf/core/results_processor/util_unittest.py
@@ -13,3 +13,11 @@
     fun = lambda x: x * x
     result = set(util.ApplyInParallel(fun, work_list))
     self.assertEqual(result, set([1, 4, 9]))
+
+  def testApplyInParallelExceptionRaised(self):
+    work_list = [1, 2, 3]
+    def fun(x):
+      if x == 3:
+        raise RuntimeError()
+    with self.assertRaises(RuntimeError):
+      list(util.ApplyInParallel(fun, work_list))
diff --git a/ui/base/x/x11_window.cc b/ui/base/x/x11_window.cc
index 1549cd3..a98dc56 100644
--- a/ui/base/x/x11_window.cc
+++ b/ui/base/x/x11_window.cc
@@ -11,6 +11,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "third_party/skia/include/core/SkRegion.h"
 #include "ui/base/hit_test_x11.h"
 #include "ui/base/x/x11_pointer_grab.h"
 #include "ui/base/x/x11_util.h"
@@ -25,6 +26,7 @@
 #include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_skia_rep.h"
+#include "ui/gfx/skia_util.h"
 #include "ui/gfx/x/x11_atom_cache.h"
 #include "ui/gfx/x/x11_path.h"
 #include "ui/platform_window/common/platform_window_defaults.h"
@@ -377,7 +379,7 @@
   ui::SetIntProperty(xwindow_, "_NET_WM_BYPASS_COMPOSITOR", "CARDINAL", 2);
 
   if (config.icon)
-    SetWindowIcons(gfx::ImageSkia(), *config.icon);
+    SetXWindowIcons(gfx::ImageSkia(), *config.icon);
 }
 
 void XWindow::Map(bool inactive) {
@@ -712,7 +714,7 @@
   return true;
 }
 
-void XWindow::SetOpacity(float opacity) {
+void XWindow::SetXWindowOpacity(float opacity) {
   // X server opacity is in terms of 32 bit unsigned int space, and counts from
   // the opposite direction.
   // XChangeProperty() expects "cardinality" to be long.
@@ -734,7 +736,7 @@
   }
 }
 
-void XWindow::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
+void XWindow::SetXWindowAspectRatio(const gfx::SizeF& aspect_ratio) {
   XSizeHints size_hints;
   size_hints.flags = 0;
   long supplied_return;
@@ -746,8 +748,8 @@
   XSetWMNormalHints(xdisplay_, xwindow_, &size_hints);
 }
 
-void XWindow::SetWindowIcons(const gfx::ImageSkia& window_icon,
-                             const gfx::ImageSkia& app_icon) {
+void XWindow::SetXWindowIcons(const gfx::ImageSkia& window_icon,
+                              const gfx::ImageSkia& app_icon) {
   // TODO(erg): The way we handle icons across different versions of chrome
   // could be substantially improved. The Windows version does its own thing
   // and only sometimes comes down this code path. The icon stuff in
@@ -924,12 +926,6 @@
   ResetWindowRegion();
 }
 
-void XWindow::SetShape(XRegion* xregion) {
-  custom_window_shape_ = !!xregion;
-  window_shape_.reset(xregion);
-  ResetWindowRegion();
-}
-
 void XWindow::OnCrossingEvent(bool enter,
                               bool focus_in_window_or_ancestor,
                               int mode,
@@ -1561,6 +1557,39 @@
   has_pointer_barriers_ = true;
 }
 
+bool XWindow::ContainsPointInRegion(const gfx::Point& point) const {
+  if (!shape())
+    return true;
+
+  return XPointInRegion(shape(), point.x(), point.y()) == x11::True;
+}
+
+void XWindow::SetXWindowShape(std::unique_ptr<NativeShapeRects> native_shape,
+                              const gfx::Transform& transform) {
+  XRegion* xregion = nullptr;
+  if (native_shape) {
+    SkRegion native_region;
+    for (const gfx::Rect& rect : *native_shape)
+      native_region.op(gfx::RectToSkIRect(rect), SkRegion::kUnion_Op);
+    if (!transform.IsIdentity() && !native_region.isEmpty()) {
+      SkPath path_in_dip;
+      if (native_region.getBoundaryPath(&path_in_dip)) {
+        SkPath path_in_pixels;
+        path_in_dip.transform(transform.matrix(), &path_in_pixels);
+        xregion = gfx::CreateRegionFromSkPath(path_in_pixels);
+      } else {
+        xregion = XCreateRegion();
+      }
+    } else {
+      xregion = gfx::CreateRegionFromSkRegion(native_region);
+    }
+  }
+
+  custom_window_shape_ = !!xregion;
+  window_shape_.reset(xregion);
+  ResetWindowRegion();
+}
+
 void XWindow::UnconfineCursor() {
   if (!has_pointer_barriers_)
     return;
diff --git a/ui/base/x/x11_window.h b/ui/base/x/x11_window.h
index 2b210936..505db626 100644
--- a/ui/base/x/x11_window.h
+++ b/ui/base/x/x11_window.h
@@ -27,6 +27,7 @@
 
 namespace gfx {
 class ImageSkia;
+class Transform;
 }  // namespace gfx
 
 namespace ui {
@@ -50,6 +51,8 @@
  public:
   class Delegate;
 
+  using NativeShapeRects = std::vector<gfx::Rect>;
+
   enum class WindowType {
     kWindow,
     kPopup,
@@ -121,10 +124,10 @@
 
   void SetCursor(::Cursor cursor);
   bool SetTitle(base::string16 title);
-  void SetOpacity(float opacity);
-  void SetAspectRatio(const gfx::SizeF& aspect_ratio);
-  void SetWindowIcons(const gfx::ImageSkia& window_icon,
-                      const gfx::ImageSkia& app_icon);
+  void SetXWindowOpacity(float opacity);
+  void SetXWindowAspectRatio(const gfx::SizeF& aspect_ratio);
+  void SetXWindowIcons(const gfx::ImageSkia& window_icon,
+                       const gfx::ImageSkia& app_icon);
   void SetXWindowVisibleOnAllWorkspaces(bool visible);
   bool IsXWindowVisibleOnAllWorkspaces() const;
   void MoveCursorTo(const gfx::Point& location);
@@ -132,12 +135,18 @@
   void SetFlashFrameHint(bool flash_frame);
   void UpdateMinAndMaxSize();
   void SetUseNativeFrame(bool use_native_frame);
-  void SetShape(XRegion* xregion);
   void DispatchResize();
   void CancelResize();
   void NotifySwapAfterResize();
   void ConfineCursorTo(const gfx::Rect& bounds);
 
+  // Returns if the point is within XWindow shape. If shape is not set, always
+  // returns true.
+  bool ContainsPointInRegion(const gfx::Point& point) const;
+
+  void SetXWindowShape(std::unique_ptr<NativeShapeRects> native_shape,
+                       const gfx::Transform& transform);
+
   // Resets the window region for the current window bounds if necessary.
   void ResetWindowRegion();
 
diff --git a/ui/display/util/BUILD.gn b/ui/display/util/BUILD.gn
index 16279d3..622996c 100644
--- a/ui/display/util/BUILD.gn
+++ b/ui/display/util/BUILD.gn
@@ -25,6 +25,7 @@
     "//base",
     "//skia",
     "//ui/display/types",
+    "//ui/gfx:color_space",
     "//ui/gfx/geometry",
   ]
 
diff --git a/ui/display/util/edid_parser.cc b/ui/display/util/edid_parser.cc
index 7b98349a..44f2fdb 100644
--- a/ui/display/util/edid_parser.cc
+++ b/ui/display/util/edid_parser.cc
@@ -332,6 +332,35 @@
   constexpr uint8_t kPTOverscanFlagPosition = 4;
   constexpr uint8_t kITOverscanFlagPosition = 2;
   constexpr uint8_t kCEOverscanFlagPosition = 0;
+  // See CTA-861-F, particularly Table 56 "Colorimetry Data Block".
+  constexpr uint8_t kColorimetryDataBlockCapabilityTag = 0x05;
+  constexpr gfx::ColorSpace::PrimaryID kPrimaryIDMap[] = {
+      // xvYCC601. Standard Definition Colorimetry based on IEC 61966-2-4.
+      gfx::ColorSpace::PrimaryID::SMPTE170M,
+      // xvYCC709. High Definition Colorimetry based on IEC 61966-2-4.
+      gfx::ColorSpace::PrimaryID::BT709,
+      // sYCC601. Colorimetry based on IEC 61966-2-1/Amendment 1.
+      gfx::ColorSpace::PrimaryID::SMPTE170M,
+      // opYCC601. Colorimetry based on IEC 61966-2-5, Annex A.
+      gfx::ColorSpace::PrimaryID::SMPTE170M,
+      // opRGB, Colorimetry based on IEC 61966-2-5.
+      gfx::ColorSpace::PrimaryID::SMPTE170M,
+      // BT2020RGB. Colorimetry based on ITU-R BT.2020 R’G’B’.
+      gfx::ColorSpace::PrimaryID::BT2020,
+      // BT2020YCC. Colorimetry based on ITU-R BT.2020 Y’C’BC’R.
+      gfx::ColorSpace::PrimaryID::BT2020,
+      // BT2020cYCC. Colorimetry based on ITU-R BT.2020 Y’cC’BCC’RC.
+      gfx::ColorSpace::PrimaryID::BT2020,
+  };
+  // See CEA 861.3-2015, "HDR Static Metadata Extensions" for these.
+  constexpr uint8_t kHDRStaticMetadataCapabilityTag = 0x6;
+  constexpr gfx::ColorSpace::TransferID kTransferIDMap[] = {
+      gfx::ColorSpace::TransferID::BT709,
+      gfx::ColorSpace::TransferID::GAMMA24,
+      gfx::ColorSpace::TransferID::SMPTEST2084,
+      // STD B67 is also known as Hybrid-log Gamma (HLG).
+      gfx::ColorSpace::TransferID::ARIB_STD_B67,
+  };
 
   if (edid.size() < kNumExtensionsOffset + 1) {
     LOG(ERROR) << "Too short EDID data: extensions";
@@ -359,26 +388,61 @@
       // A data block is encoded as:
       // - byte 1 high 3 bits: tag. '07' for extended tags.
       // - byte 1 remaining bits: the length of data block.
-      // - byte 2: the extended tag.  '0' for video capability.
+      // - byte 2: the extended tag. E.g. '0' for video capability. Values are
+      //   defined by the k...CapabilityTag constants.
       // - byte 3: the capability.
       const uint8_t tag = edid[data_offset] >> 5;
       const uint8_t payload_length = edid[data_offset] & 0x1f;
       if (data_offset + payload_length + 1 > edid.size())
         break;
 
-      if (tag != kExtendedTag || payload_length < 2 ||
-          edid[data_offset + 1] != kExtendedVideoCapabilityTag) {
+      if (tag != kExtendedTag || payload_length < 2) {
         data_offset += payload_length + 1;
         continue;
       }
 
-      // The difference between preferred, IT, and CE video formats doesn't
-      // matter. Set the flag to true if any of these flags are true.
-      overscan_flag_ =
-          (edid[data_offset + 2] & (1 << kPTOverscanFlagPosition)) ||
-          (edid[data_offset + 2] & (1 << kITOverscanFlagPosition)) ||
-          (edid[data_offset + 2] & (1 << kCEOverscanFlagPosition));
-      break;
+      switch (edid[data_offset + 1]) {
+        case kExtendedVideoCapabilityTag:
+          // The difference between preferred, IT, and CE video formats doesn't
+          // matter. Set the flag to true if any of these flags are true.
+          overscan_flag_ =
+              (edid[data_offset + 2] & (1 << kPTOverscanFlagPosition)) ||
+              (edid[data_offset + 2] & (1 << kITOverscanFlagPosition)) ||
+              (edid[data_offset + 2] & (1 << kCEOverscanFlagPosition));
+          break;
+
+        case kColorimetryDataBlockCapabilityTag: {
+          constexpr size_t kMaxNumColorimetryEntries = 8;
+          const std::bitset<kMaxNumColorimetryEntries>
+              supported_primaries_bitfield(edid[data_offset + 2]);
+          static_assert(
+              kMaxNumColorimetryEntries == base::size(kPrimaryIDMap),
+              "kPrimaryIDMap should describe all possible colorimetry entries");
+          for (size_t i = 0; i < kMaxNumColorimetryEntries; ++i) {
+            if (supported_primaries_bitfield[i])
+              supported_color_primary_ids_.insert(kPrimaryIDMap[i]);
+          }
+          break;
+        }
+
+        case kHDRStaticMetadataCapabilityTag: {
+          constexpr size_t kMaxNumHDRStaticMedatataEntries = 4;
+          const std::bitset<kMaxNumHDRStaticMedatataEntries>
+              supported_eotfs_bitfield(edid[data_offset + 2]);
+          static_assert(
+              kMaxNumHDRStaticMedatataEntries == base::size(kTransferIDMap),
+              "kTransferIDMap should describe all possible transfer entries");
+          for (size_t i = 0; i < kMaxNumHDRStaticMedatataEntries; ++i) {
+            if (supported_eotfs_bitfield[i])
+              supported_color_transfer_ids_.insert(kTransferIDMap[i]);
+          }
+          break;
+        }
+        default:
+          break;
+      }
+
+      data_offset += payload_length + 1;
     }
   }
 }
diff --git a/ui/display/util/edid_parser.h b/ui/display/util/edid_parser.h
index 20516a2..13a7b01 100644
--- a/ui/display/util/edid_parser.h
+++ b/ui/display/util/edid_parser.h
@@ -11,10 +11,12 @@
 #include <vector>
 
 #include "base/compiler_specific.h"
+#include "base/containers/flat_set.h"
 #include "base/macros.h"
 #include "base/optional.h"
 #include "third_party/skia/include/core/SkColorSpace.h"
 #include "ui/display/util/display_util_export.h"
+#include "ui/gfx/color_space.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace display {
@@ -37,7 +39,14 @@
   double gamma() const { return gamma_; }
   int32_t bits_per_channel() const { return bits_per_channel_; }
   const SkColorSpacePrimaries& primaries() const { return primaries_; }
-
+  const base::flat_set<gfx::ColorSpace::PrimaryID>&
+  supported_color_primary_ids() const {
+    return supported_color_primary_ids_;
+  }
+  const base::flat_set<gfx::ColorSpace::TransferID>&
+  supported_color_transfer_ids() const {
+    return supported_color_transfer_ids_;
+  }
   // Returns a 32-bit identifier for this display |manufacturer_id_| and
   // |product_id_|.
   uint32_t GetProductCode() const;
@@ -72,6 +81,9 @@
   int bits_per_channel_;
   SkColorSpacePrimaries primaries_;
 
+  base::flat_set<gfx::ColorSpace::PrimaryID> supported_color_primary_ids_;
+  base::flat_set<gfx::ColorSpace::TransferID> supported_color_transfer_ids_;
+
   DISALLOW_COPY_AND_ASSIGN(EdidParser);
 };
 
diff --git a/ui/display/util/edid_parser_unittest.cc b/ui/display/util/edid_parser_unittest.cc
index 365a922..53517a9 100644
--- a/ui/display/util/edid_parser_unittest.cc
+++ b/ui/display/util/edid_parser_unittest.cc
@@ -8,6 +8,7 @@
 
 #include <memory>
 
+#include "base/containers/flat_set.h"
 #include "base/numerics/ranges.h"
 #include "base/stl_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -152,6 +153,26 @@
     "\x00\x4c\x51\x31\x32\x33\x50\x31\x4a\x58\x33\x32\x0a\x20\x00\xb6";
 constexpr size_t kEveLength = base::size(kEve);
 
+// A Samsung monitor that supports HDR metadata.
+constexpr unsigned char kHDRMetadata[] =
+    "\x00\xff\xff\xff\xff\xff\xff\x00\x4c\x2d\xf6\x0d\x00\x0e\x00\x01"
+    "\x01\x1b\x01\x03\x80\x5f\x36\x78\x0a\x23\xad\xa4\x54\x4d\x99\x26"
+    "\x0f\x47\x4a\xbd\xef\x80\x71\x4f\x81\xc0\x81\x00\x81\x80\x95\x00"
+    "\xa9\xc0\xb3\x00\x01\x01\x04\x74\x00\x30\xf2\x70\x5a\x80\xb0\x58"
+    "\x8a\x00\x50\x1d\x74\x00\x00\x1e\x02\x3a\x80\x18\x71\x38\x2d\x40"
+    "\x58\x2c\x45\x00\x50\x1d\x74\x00\x00\x1e\x00\x00\x00\xfd\x00\x18"
+    "\x4b\x0f\x51\x1e\x00\x0a\x20\x20\x20\x20\x20\x20\x00\x00\x00\xfc"
+    "\x00\x53\x41\x4d\x53\x55\x4e\x47\x0a\x20\x20\x20\x20\x20\x01\x5a"
+    "\x02\x03\x4f\xf0\x53\x5f\x10\x1f\x04\x13\x05\x14\x20\x21\x22\x5d"
+    "\x5e\x62\x63\x64\x07\x16\x03\x12\x2c\x09\x07\x07\x15\x07\x50\x3d"
+    "\x04\xc0\x57\x07\x00\x83\x01\x00\x00\xe2\x00\x0f\xe3\x05\x03\x01"
+    "\x6e\x03\x0c\x00\x30\x00\xb8\x3c\x20\x00\x80\x01\x02\x03\x04\xe3"
+    "\x06\x0d\x01\xe5\x0e\x60\x61\x65\x66\xe5\x01\x8b\x84\x90\x01\x01"
+    "\x1d\x80\xd0\x72\x1c\x16\x20\x10\x2c\x25\x80\x50\x1d\x74\x00\x00"
+    "\x9e\x66\x21\x56\xaa\x51\x00\x1e\x30\x46\x8f\x33\x00\x50\x1d\x74"
+    "\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xbd";
+constexpr size_t kHDRMetadataLength = base::size(kHDRMetadata);
+
 // Primaries coordinates ({RX, RY, GX, GY, BX, BY, WX, WY}) calculated by hand
 // and rounded to 4 decimal places.
 constexpr SkColorSpacePrimaries kNormalDisplayPrimaries = {
@@ -172,6 +193,8 @@
     0.6338f, 0.3477f, 0.3232f, 0.5771f, 0.1514f, 0.0908f, 0.3135f, 0.3291f};
 constexpr SkColorSpacePrimaries kEvePrimaries = {
     0.6396f, 0.3291f, 0.2998f, 0.5996f, 0.1494f, 0.0596f, 0.3125f, 0.3281f};
+constexpr SkColorSpacePrimaries kHDRPrimaries = {
+    0.6406f, 0.3300f, 0.3007f, 0.6005f, 0.1503f, 0.0605f, 0.2802f, 0.2900f};
 
 // Chromaticity primaries in EDID are specified with 10 bits precision.
 constexpr static float kPrimariesPrecision = 1 / 2048.f;
@@ -219,40 +242,203 @@
   std::string manufacturer_id_string;
   std::string product_id_string;
 
+  base::flat_set<gfx::ColorSpace::PrimaryID> supported_color_primary_ids_;
+  base::flat_set<gfx::ColorSpace::TransferID> supported_color_transfer_ids_;
+
   const unsigned char* edid_blob;
   size_t edid_blob_length;
 } kTestCases[] = {
-    {0x22f0u, 0x6c28u, "HP ZR30w", gfx::Size(2560, 1600), 2012, false, 2.2, 10,
-     kNormalDisplayPrimaries, 586181672, 9834734971736576, "HWP", "286C",
-     kNormalDisplay, kNormalDisplayLength},
-    {0x4ca3u, 0x4231u, "", gfx::Size(1280, 800), 2011, false, 2.2, -1,
-     kInternalDisplayPrimaries, 1285767729, 21571318625337344, "SEC", "3142",
-     kInternalDisplay, kInternalDisplayLength},
-    {0x4c2du, 0xfe08u, "SAMSUNG", gfx::Size(1920, 1080), 2011, true, 2.2, -1,
-     kOverscanDisplayPrimaries, 1278082568, 21442559853606400, "SAM", "08FE",
-     kOverscanDisplay, kOverscanDisplayLength},
-    {0x10ACu, 0x6440u, "DELL U3011", gfx::Size(1920, 1200), 2011, false, 2.2,
-     -1, kMisdetectedDisplayPrimaries, 279733312, 4692848143772416, "DEL",
-     "4064", kMisdetectedDisplay, kMisdetectedDisplayLength},
-    {0x22f0u, 0x7626u, "HP LP2465", gfx::Size(1920, 1200), 2008, false, 2.2, -1,
-     kLP2565APrimaries, 586184230, 9834630174887424, "HWP", "2676", kLP2565A,
+    {0x22f0u,
+     0x6c28u,
+     "HP ZR30w",
+     gfx::Size(2560, 1600),
+     2012,
+     false,
+     2.2,
+     10,
+     kNormalDisplayPrimaries,
+     586181672,
+     9834734971736576,
+     "HWP",
+     "286C",
+     {},
+     {},
+     kNormalDisplay,
+     kNormalDisplayLength},
+    {0x4ca3u,
+     0x4231u,
+     "",
+     gfx::Size(1280, 800),
+     2011,
+     false,
+     2.2,
+     -1,
+     kInternalDisplayPrimaries,
+     1285767729,
+     21571318625337344,
+     "SEC",
+     "3142",
+     {},
+     {},
+     kInternalDisplay,
+     kInternalDisplayLength},
+    {0x4c2du,
+     0xfe08u,
+     "SAMSUNG",
+     gfx::Size(1920, 1080),
+     2011,
+     true,
+     2.2,
+     -1,
+     kOverscanDisplayPrimaries,
+     1278082568,
+     21442559853606400,
+     "SAM",
+     "08FE",
+     {},
+     {},
+     kOverscanDisplay,
+     kOverscanDisplayLength},
+    {0x10ACu,
+     0x6440u,
+     "DELL U3011",
+     gfx::Size(1920, 1200),
+     2011,
+     false,
+     2.2,
+     -1,
+     kMisdetectedDisplayPrimaries,
+     279733312,
+     4692848143772416,
+     "DEL",
+     "4064",
+     {gfx::ColorSpace::PrimaryID::BT709, gfx::ColorSpace::PrimaryID::SMPTE170M},
+     {},
+     kMisdetectedDisplay,
+     kMisdetectedDisplayLength},
+    {0x22f0u,
+     0x7626u,
+     "HP LP2465",
+     gfx::Size(1920, 1200),
+     2008,
+     false,
+     2.2,
+     -1,
+     kLP2565APrimaries,
+     586184230,
+     9834630174887424,
+     "HWP",
+     "2676",
+     {},
+     {},
+     kLP2565A,
      kLP2565ALength},
-    {0x22f0u, 0x7526u, "HP LP2465", gfx::Size(1920, 1200), 2008, false, 2.2, -1,
-     kLP2565BPrimaries, 586183974, 9834630174887424, "HWP", "2675", kLP2565B,
+    {0x22f0u,
+     0x7526u,
+     "HP LP2465",
+     gfx::Size(1920, 1200),
+     2008,
+     false,
+     2.2,
+     -1,
+     kLP2565BPrimaries,
+     586183974,
+     9834630174887424,
+     "HWP",
+     "2675",
+     {},
+     {},
+     kLP2565B,
      kLP2565BLength},
-    {0x22f0u, 0x7532u, "HP Z32x", gfx::Size(3840, 2160), 2017, false, 2.2, 10,
-     kHPz32xPrimaries, 586183986, 9834799315992832, "HWP", "3275", kHPz32x,
+    {0x22f0u,
+     0x7532u,
+     "HP Z32x",
+     gfx::Size(3840, 2160),
+     2017,
+     false,
+     2.2,
+     10,
+     kHPz32xPrimaries,
+     586183986,
+     9834799315992832,
+     "HWP",
+     "3275",
+     {},
+     {},
+     kHPz32x,
      kHPz32xLength},
-    {0x30E4u, 0x2E04u, "", gfx::Size(2560, 1700), 2014, false, 2.5, 8,
-     kSamusPrimaries, 820260356, 13761487533244416, "LGD", "042E", kSamus,
+    {0x30E4u,
+     0x2E04u,
+     "",
+     gfx::Size(2560, 1700),
+     2014,
+     false,
+     2.5,
+     8,
+     kSamusPrimaries,
+     820260356,
+     13761487533244416,
+     "LGD",
+     "042E",
+     {},
+     {},
+     kSamus,
      kSamusLength},
-    {0x4D10u, 0x8A14u, "LQ123P1JX32", gfx::Size(2400, 1600), 2017, false, 2.2,
-     8, kEvePrimaries, 1292929556, 21692109949126656, "SHP", "148A", kEve,
+    {0x4D10u,
+     0x8A14u,
+     "LQ123P1JX32",
+     gfx::Size(2400, 1600),
+     2017,
+     false,
+     2.2,
+     8,
+     kEvePrimaries,
+     1292929556,
+     21692109949126656,
+     "SHP",
+     "148A",
+     {},
+     {},
+     kEve,
      kEveLength},
+    {19501u,
+     62989u,
+     "SAMSUNG",
+     gfx::Size(3840, 2160),
+     2017,
+     true,
+     2.2,
+     -1,
+     kHDRPrimaries,
+     1278080525,
+     21442559853606400,
+     "SAM",
+     "0DF6",
+     {gfx::ColorSpace::PrimaryID::BT709, gfx::ColorSpace::PrimaryID::SMPTE170M},
+     {gfx::ColorSpace::TransferID::BT709,
+      gfx::ColorSpace::TransferID::SMPTEST2084,
+      gfx::ColorSpace::TransferID::ARIB_STD_B67},
+     kHDRMetadata,
+     kHDRMetadataLength},
 
     // Empty Edid, which is tantamount to error.
-    {0, 0, "", gfx::Size(0, 0), display::kInvalidYearOfManufacture, false, 0.0,
-     -1, SkColorSpacePrimaries(), 0, 0, "@@@", "0000", nullptr, 0u},
+    {0,
+     0,
+     "",
+     gfx::Size(0, 0),
+     display::kInvalidYearOfManufacture,
+     false,
+     0.0,
+     -1,
+     SkColorSpacePrimaries(),
+     0,
+     0,
+     "@@@",
+     "0000",
+     {},
+     {},
+     nullptr,
+     0u},
 };
 
 class EDIDParserTest : public TestWithParam<TestParams> {
@@ -290,6 +476,11 @@
             GetParam().manufacturer_id_string);
   EXPECT_EQ(EdidParser::ProductIdToString(parser_.product_id()),
             GetParam().product_id_string);
+
+  EXPECT_EQ(GetParam().supported_color_primary_ids_,
+            parser_.supported_color_primary_ids());
+  EXPECT_EQ(GetParam().supported_color_transfer_ids_,
+            parser_.supported_color_transfer_ids());
 }
 
 INSTANTIATE_TEST_SUITE_P(, EDIDParserTest, ValuesIn(kTestCases));
diff --git a/ui/display/util/fuzz_corpus/hdr b/ui/display/util/fuzz_corpus/hdr
new file mode 100644
index 0000000..bdc6193
--- /dev/null
+++ b/ui/display/util/fuzz_corpus/hdr
Binary files differ
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 ad35aa2..ca6cea15 100644
--- a/ui/file_manager/file_manager/foreground/css/file_manager.css
+++ b/ui/file_manager/file_manager/foreground/css/file_manager.css
@@ -109,8 +109,8 @@
   flex-direction: column;
 }
 
-/* A vertical splitter between the roots list and the file list. It is actually
-   a transparent area centered on the roots list right border.*/
+/* A vertical splitter between the directory tree and the file list. It is
+   actually a transparent area centered on the tree right border.*/
 div.splitter {
   cursor: col-resize;
   flex: none;
@@ -132,6 +132,10 @@
   top: 0;
 }
 
+html[class*='col-resize'] #directory-tree {
+  overflow-y: hidden;
+}
+
 #directory-tree .tree-row {
   align-items: center;
   color: rgb(90, 90, 90);
diff --git a/ui/ozone/platform/drm/host/drm_window_host.cc b/ui/ozone/platform/drm/host/drm_window_host.cc
index 39c760c1..735b2e4 100644
--- a/ui/ozone/platform/drm/host/drm_window_host.cc
+++ b/ui/ozone/platform/drm/host/drm_window_host.cc
@@ -153,6 +153,15 @@
   return gfx::Rect();
 }
 
+void DrmWindowHost::SetWindowIcons(const gfx::ImageSkia& window_icon,
+                                   const gfx::ImageSkia& app_icon) {
+  NOTREACHED();
+}
+
+void DrmWindowHost::SizeConstraintsChanged() {
+  NOTREACHED();
+}
+
 void DrmWindowHost::OnMouseEnter() {
   delegate_->OnMouseEnter();
 }
diff --git a/ui/ozone/platform/drm/host/drm_window_host.h b/ui/ozone/platform/drm/host/drm_window_host.h
index bda6a97..bb315da 100644
--- a/ui/ozone/platform/drm/host/drm_window_host.h
+++ b/ui/ozone/platform/drm/host/drm_window_host.h
@@ -83,6 +83,10 @@
   void ConfineCursorToBounds(const gfx::Rect& bounds) override;
   void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override;
   gfx::Rect GetRestoredBoundsInPixels() const override;
+  void SetWindowIcons(const gfx::ImageSkia& window_icon,
+                      const gfx::ImageSkia& app_icon) override;
+  void SizeConstraintsChanged() override;
+
   void OnMouseEnter();
 
   // PlatformEventDispatcher:
diff --git a/ui/ozone/platform/scenic/scenic_window.cc b/ui/ozone/platform/scenic/scenic_window.cc
index b1c78fb..188187c 100644
--- a/ui/ozone/platform/scenic/scenic_window.cc
+++ b/ui/ozone/platform/scenic/scenic_window.cc
@@ -184,6 +184,15 @@
   return gfx::Rect();
 }
 
+void ScenicWindow::SetWindowIcons(const gfx::ImageSkia& window_icon,
+                                  const gfx::ImageSkia& app_icon) {
+  NOTIMPLEMENTED();
+}
+
+void ScenicWindow::SizeConstraintsChanged() {
+  NOTIMPLEMENTED();
+}
+
 void ScenicWindow::UpdateSize() {
   gfx::SizeF scaled = ScaleSize(size_dips_, device_pixel_ratio_);
   size_pixels_ = gfx::Size(ceilf(scaled.width()), ceilf(scaled.height()));
diff --git a/ui/ozone/platform/scenic/scenic_window.h b/ui/ozone/platform/scenic/scenic_window.h
index ee8b1ac5..799669a7 100644
--- a/ui/ozone/platform/scenic/scenic_window.h
+++ b/ui/ozone/platform/scenic/scenic_window.h
@@ -72,6 +72,9 @@
   void ConfineCursorToBounds(const gfx::Rect& bounds) override;
   void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override;
   gfx::Rect GetRestoredBoundsInPixels() const override;
+  void SetWindowIcons(const gfx::ImageSkia& window_icon,
+                      const gfx::ImageSkia& app_icon) override;
+  void SizeConstraintsChanged() override;
 
  private:
   // Callbacks for |scenic_session_|.
diff --git a/ui/ozone/platform/wayland/host/wayland_window.cc b/ui/ozone/platform/wayland/host/wayland_window.cc
index d14b71d..c1e8f16 100644
--- a/ui/ozone/platform/wayland/host/wayland_window.cc
+++ b/ui/ozone/platform/wayland/host/wayland_window.cc
@@ -545,6 +545,19 @@
   return false;
 }
 
+void WaylandWindow::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
+  NOTIMPLEMENTED_LOG_ONCE();
+}
+
+void WaylandWindow::SetWindowIcons(const gfx::ImageSkia& window_icon,
+                                   const gfx::ImageSkia& app_icon) {
+  NOTIMPLEMENTED_LOG_ONCE();
+}
+
+void WaylandWindow::SizeConstraintsChanged() {
+  NOTIMPLEMENTED_LOG_ONCE();
+}
+
 bool WaylandWindow::CanDispatchEvent(const PlatformEvent& event) {
   // This window is a nested popup window, all the events must be forwarded
   // to the main popup window.
diff --git a/ui/ozone/platform/wayland/host/wayland_window.h b/ui/ozone/platform/wayland/host/wayland_window.h
index ba1be4c..965560e 100644
--- a/ui/ozone/platform/wayland/host/wayland_window.h
+++ b/ui/ozone/platform/wayland/host/wayland_window.h
@@ -139,6 +139,10 @@
   void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override;
   gfx::Rect GetRestoredBoundsInPixels() const override;
   bool ShouldWindowContentsBeTransparent() const override;
+  void SetAspectRatio(const gfx::SizeF& aspect_ratio) override;
+  void SetWindowIcons(const gfx::ImageSkia& window_icon,
+                      const gfx::ImageSkia& app_icon) override;
+  void SizeConstraintsChanged() override;
 
   // PlatformEventDispatcher
   bool CanDispatchEvent(const PlatformEvent& event) override;
diff --git a/ui/platform_window/platform_window_base.cc b/ui/platform_window/platform_window_base.cc
index 39ad974..6ddea33 100644
--- a/ui/platform_window/platform_window_base.cc
+++ b/ui/platform_window/platform_window_base.cc
@@ -4,6 +4,8 @@
 
 #include "ui/platform_window/platform_window_base.h"
 
+#include "ui/gfx/geometry/rect.h"
+
 namespace ui {
 
 PlatformWindowBase::PlatformWindowBase() = default;
@@ -26,4 +28,20 @@
 
 void PlatformWindowBase::FlashFrame(bool flash_frame) {}
 
+void PlatformWindowBase::SetShape(std::unique_ptr<ShapeRects> native_shape,
+                                  const gfx::Transform& transform) {}
+
+void PlatformWindowBase::SetAspectRatio(const gfx::SizeF& aspect_ratio) {}
+
+void PlatformWindowBase::SetWindowIcons(const gfx::ImageSkia& window_icon,
+                                        const gfx::ImageSkia& app_icon) {}
+
+bool PlatformWindowBase::IsAnimatingClosed() const {
+  return false;
+}
+
+bool PlatformWindowBase::IsTranslucentWindowOpacitySupported() const {
+  return false;
+}
+
 }  // namespace ui
diff --git a/ui/platform_window/platform_window_base.h b/ui/platform_window/platform_window_base.h
index dd9aab5..ba88b840 100644
--- a/ui/platform_window/platform_window_base.h
+++ b/ui/platform_window/platform_window_base.h
@@ -15,8 +15,11 @@
 #include "ui/platform_window/platform_window_delegate.h"
 
 namespace gfx {
+class ImageSkia;
 class Point;
 class Rect;
+class SizeF;
+class Transform;
 }  // namespace gfx
 
 namespace ui {
@@ -84,6 +87,16 @@
   virtual void SetRestoredBoundsInPixels(const gfx::Rect& bounds) = 0;
   virtual gfx::Rect GetRestoredBoundsInPixels() const = 0;
 
+  // Sets the Window icons. |window_icon| is a 16x16 icon suitable for use in
+  // a title bar. |app_icon| is a larger size for use in the host environment
+  // app switching UI.
+  virtual void SetWindowIcons(const gfx::ImageSkia& window_icon,
+                              const gfx::ImageSkia& app_icon) = 0;
+
+  // Notifies that size constraints of the host have been changed and the
+  // PlatformWindow must react on them accordingly.
+  virtual void SizeConstraintsChanged() = 0;
+
   // Tells if the content of the platform window should be transparent. By
   // default returns false.
   virtual bool ShouldWindowContentsBeTransparent() const;
@@ -102,6 +115,25 @@
   // is set, the PlatformWindow must draw attention to it. If |flash_frame| is
   // not set, flashing must be stopped.
   virtual void FlashFrame(bool flash_frame);
+
+  using ShapeRects = std::vector<gfx::Rect>;
+  // Sets shape of the PlatformWindow. ShapeRects corresponds to the
+  // Widget::ShapeRects that is a vector of gfx::Rects that describe the shape.
+  virtual void SetShape(std::unique_ptr<ShapeRects> native_shape,
+                        const gfx::Transform& transform);
+
+  // Sets the aspect ratio of the Platform Window, which will be
+  // maintained during interactive resizing. This size disregards title bar and
+  // borders. Once set, some platforms ensure the content will only size to
+  // integer multiples of |aspect_ratio|.
+  virtual void SetAspectRatio(const gfx::SizeF& aspect_ratio);
+
+  // Returns true if the window was closed but is still showing because of
+  // animations.
+  virtual bool IsAnimatingClosed() const;
+
+  // Returns true if the window supports translucency.
+  virtual bool IsTranslucentWindowOpacitySupported() const;
 };
 
 }  // namespace ui
diff --git a/ui/platform_window/platform_window_linux.cc b/ui/platform_window/platform_window_linux.cc
index 3a0c68d..0e7ed45 100644
--- a/ui/platform_window/platform_window_linux.cc
+++ b/ui/platform_window/platform_window_linux.cc
@@ -26,4 +26,15 @@
   return false;
 }
 
+gfx::Rect PlatformWindowLinux::GetXRootWindowOuterBounds() const {
+  return {};
+}
+
+bool PlatformWindowLinux::ContainsPointInXRegion(
+    const gfx::Point& point) const {
+  return false;
+}
+
+void PlatformWindowLinux::SetOpacityForXWindow(float opacity) {}
+
 }  // namespace ui
diff --git a/ui/platform_window/platform_window_linux.h b/ui/platform_window/platform_window_linux.h
index 037d2940..c9332a4 100644
--- a/ui/platform_window/platform_window_linux.h
+++ b/ui/platform_window/platform_window_linux.h
@@ -6,6 +6,7 @@
 #define UI_PLATFORM_WINDOW_PLATFORM_WINDOW_LINUX_H_
 
 #include "base/optional.h"
+#include "ui/gfx/geometry/rect.h"
 #include "ui/platform_window/platform_window_base.h"
 
 namespace ui {
@@ -30,6 +31,18 @@
   // X11-specific.  Returns true if the PlatformWindow is visible on all
   // workspaces.
   virtual bool IsVisibleOnAllWorkspaces() const;
+
+  // X11-specific.  Returns the current bounds in terms of the X11 Root Window
+  // including the borders provided by the window manager (if any).
+  virtual gfx::Rect GetXRootWindowOuterBounds() const;
+
+  // X11-specific.  Says if the X11 Root Window contains the point within its
+  // set shape. If shape is not set, returns true.
+  virtual bool ContainsPointInXRegion(const gfx::Point& point) const;
+
+  // X11-specific.  Asks X11 to set transparency of the X11 Root Window. Not
+  // used for Wayland as it uses alpha channel to blend a window instead.
+  virtual void SetOpacityForXWindow(float opacity);
 };
 
 }  // namespace ui
diff --git a/ui/platform_window/stub/stub_window.cc b/ui/platform_window/stub/stub_window.cc
index 531ff63..9e8b67a 100644
--- a/ui/platform_window/stub/stub_window.cc
+++ b/ui/platform_window/stub/stub_window.cc
@@ -96,4 +96,9 @@
   return gfx::Rect();
 }
 
+void StubWindow::SetWindowIcons(const gfx::ImageSkia& window_icon,
+                                const gfx::ImageSkia& app_icon) {}
+
+void StubWindow::SizeConstraintsChanged() {}
+
 }  // namespace ui
diff --git a/ui/platform_window/stub/stub_window.h b/ui/platform_window/stub/stub_window.h
index 3752dc7..0c548ea9 100644
--- a/ui/platform_window/stub/stub_window.h
+++ b/ui/platform_window/stub/stub_window.h
@@ -53,6 +53,9 @@
   void ConfineCursorToBounds(const gfx::Rect& bounds) override;
   void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override;
   gfx::Rect GetRestoredBoundsInPixels() const override;
+  void SetWindowIcons(const gfx::ImageSkia& window_icon,
+                      const gfx::ImageSkia& app_icon) override;
+  void SizeConstraintsChanged() override;
 
   PlatformWindowDelegate* delegate_;
   gfx::Rect bounds_;
diff --git a/ui/platform_window/win/win_window.cc b/ui/platform_window/win/win_window.cc
index 3b4ef34..37e29f4 100644
--- a/ui/platform_window/win/win_window.cc
+++ b/ui/platform_window/win/win_window.cc
@@ -195,6 +195,34 @@
   NOTIMPLEMENTED_LOG_ONCE();
 }
 
+void WinWindow::SetShape(std::unique_ptr<ShapeRects> native_shape,
+                         const gfx::Transform& transform) {
+  NOTIMPLEMENTED_LOG_ONCE();
+}
+
+void WinWindow::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
+  NOTIMPLEMENTED_LOG_ONCE();
+}
+
+void WinWindow::SetWindowIcons(const gfx::ImageSkia& window_icon,
+                               const gfx::ImageSkia& app_icon) {
+  NOTIMPLEMENTED_LOG_ONCE();
+}
+
+void WinWindow::SizeConstraintsChanged() {
+  NOTIMPLEMENTED_LOG_ONCE();
+}
+
+bool WinWindow::IsAnimatingClosed() const {
+  NOTIMPLEMENTED_LOG_ONCE();
+  return false;
+}
+
+bool WinWindow::IsTranslucentWindowOpacitySupported() const {
+  NOTIMPLEMENTED_LOG_ONCE();
+  return false;
+}
+
 bool WinWindow::IsFullscreen() const {
   return GetPlatformWindowState() == PlatformWindowState::kFullScreen;
 }
diff --git a/ui/platform_window/win/win_window.h b/ui/platform_window/win/win_window.h
index 992be002..b073cfd 100644
--- a/ui/platform_window/win/win_window.h
+++ b/ui/platform_window/win/win_window.h
@@ -59,6 +59,14 @@
   void StackAtTop() override;
   void FlashFrame(bool flash_frame) override;
   void SetVisibilityChangedAnimationsEnabled(bool enabled) override;
+  void SetShape(std::unique_ptr<ShapeRects> native_shape,
+                const gfx::Transform& transform) override;
+  void SetAspectRatio(const gfx::SizeF& aspect_ratio) override;
+  void SetWindowIcons(const gfx::ImageSkia& window_icon,
+                      const gfx::ImageSkia& app_icon) override;
+  void SizeConstraintsChanged() override;
+  bool IsAnimatingClosed() const override;
+  bool IsTranslucentWindowOpacitySupported() const override;
 
   bool IsFullscreen() const;
 
diff --git a/ui/platform_window/x11/x11_window.cc b/ui/platform_window/x11/x11_window.cc
index 3f94ada..e5c489e 100644
--- a/ui/platform_window/x11/x11_window.cc
+++ b/ui/platform_window/x11/x11_window.cc
@@ -6,6 +6,7 @@
 
 #include "base/trace_event/trace_event.h"
 #include "ui/base/x/x11_util.h"
+#include "ui/base/x/x11_util_internal.h"
 #include "ui/display/screen.h"
 #include "ui/events/devices/x11/touch_factory_x11.h"
 #include "ui/events/event.h"
@@ -398,6 +399,43 @@
   XWindow::SetFlashFrameHint(flash_frame);
 }
 
+gfx::Rect X11Window::GetXRootWindowOuterBounds() const {
+  return XWindow::GetOutterBounds();
+}
+
+bool X11Window::ContainsPointInXRegion(const gfx::Point& point) const {
+  return XWindow::ContainsPointInRegion(point);
+}
+
+void X11Window::SetShape(std::unique_ptr<ShapeRects> native_shape,
+                         const gfx::Transform& transform) {
+  return XWindow::SetXWindowShape(std::move(native_shape), transform);
+}
+
+void X11Window::SetOpacityForXWindow(float opacity) {
+  XWindow::SetXWindowOpacity(opacity);
+}
+
+void X11Window::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
+  XWindow::SetXWindowAspectRatio(aspect_ratio);
+}
+
+void X11Window::SetWindowIcons(const gfx::ImageSkia& window_icon,
+                               const gfx::ImageSkia& app_icon) {
+  XWindow::SetXWindowIcons(window_icon, app_icon);
+}
+
+void X11Window::SizeConstraintsChanged() {
+  XWindow::UpdateMinAndMaxSize();
+}
+
+bool X11Window::IsTranslucentWindowOpacitySupported() const {
+  // This function may be called before InitX11Window() (which
+  // initializes |visual_has_alpha_|), so we cannot simply return
+  // |visual_has_alpha_|.
+  return ui::XVisualManager::GetInstance()->ArgbVisualAvailable();
+}
+
 bool X11Window::CanDispatchEvent(const PlatformEvent& xev) {
 #if defined(USE_X11)
   return XWindow::IsTargetedBy(*xev);
diff --git a/ui/platform_window/x11/x11_window.h b/ui/platform_window/x11/x11_window.h
index d5e5cfe..1e16b622 100644
--- a/ui/platform_window/x11/x11_window.h
+++ b/ui/platform_window/x11/x11_window.h
@@ -92,6 +92,16 @@
   void SetVisibleOnAllWorkspaces(bool always_visible) override;
   bool IsVisibleOnAllWorkspaces() const override;
   void FlashFrame(bool flash_frame) override;
+  gfx::Rect GetXRootWindowOuterBounds() const override;
+  bool ContainsPointInXRegion(const gfx::Point& point) const override;
+  void SetShape(std::unique_ptr<ShapeRects> native_shape,
+                const gfx::Transform& transform) override;
+  void SetOpacityForXWindow(float opacity) override;
+  void SetAspectRatio(const gfx::SizeF& aspect_ratio) override;
+  void SetWindowIcons(const gfx::ImageSkia& window_icon,
+                      const gfx::ImageSkia& app_icon) override;
+  void SizeConstraintsChanged() override;
+  bool IsTranslucentWindowOpacitySupported() const override;
 
  protected:
   PlatformWindowDelegateLinux* platform_window_delegate() const {
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc
index b8a6fb5..1e66f0d7 100644
--- a/ui/views/controls/button/label_button.cc
+++ b/ui/views/controls/button/label_button.cc
@@ -530,7 +530,7 @@
   size.Enlarge(insets.width(), insets.height());
 
   // Accommodate for spacing between image and text if both are present.
-  if (!GetText().empty() && image_size.width() > 0)
+  if (image_size.width() > 0 && !GetText().empty() && !shrinking_down_label_)
     size.Enlarge(GetImageLabelSpacing(), 0);
 
   // Make the size at least as large as the minimum size needed by the border.
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_unittest.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_unittest.cc
index fdea67f..2b58b0f 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_unittest.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone_unittest.cc
@@ -59,6 +59,9 @@
   gfx::Rect GetRestoredBoundsInPixels() const override { return gfx::Rect(); }
   void SetUseNativeFrame(bool use_native_frame) override {}
   bool ShouldUseNativeFrame() const override { return false; }
+  void SetWindowIcons(const gfx::ImageSkia& window_icon,
+                      const gfx::ImageSkia& app_icon) override {}
+  void SizeConstraintsChanged() override {}
 
   // ui::WmDragHandler
   void StartDrag(const OSExchangeData& data,
diff --git a/ui/views/widget/desktop_aura/desktop_screen_x11.cc b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
index 3c58a75..a4e8174 100644
--- a/ui/views/widget/desktop_aura/desktop_screen_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_screen_x11.cc
@@ -31,8 +31,7 @@
 float GetDeviceScaleFactor() {
   float device_scale_factor = 1.0f;
   if (views::LinuxUI::instance()) {
-    device_scale_factor =
-      views::LinuxUI::instance()->GetDeviceScaleFactor();
+    device_scale_factor = views::LinuxUI::instance()->GetDeviceScaleFactor();
   } else if (display::Display::HasForceDeviceScaleFactor()) {
     device_scale_factor = display::Display::GetForcedDeviceScaleFactor();
   }
@@ -119,10 +118,10 @@
   // aura::Window's screen bounds.
   aura::WindowTreeHost* host = window->GetHost();
   if (host) {
-    DesktopWindowTreeHostX11* rwh = DesktopWindowTreeHostX11::GetHostForXID(
-        host->GetAcceleratedWidget());
+    DesktopWindowTreeHostX11* rwh =
+        DesktopWindowTreeHostX11::GetHostForXID(host->GetAcceleratedWidget());
     if (rwh) {
-      const gfx::Rect pixel_rect = rwh->GetX11RootWindowBounds();
+      const gfx::Rect pixel_rect = rwh->GetBoundsInPixels();
       const gfx::Rect dip_rect =
           gfx::ConvertRectToDIP(GetDeviceScaleFactor(), pixel_rect);
       return GetDisplayMatching(dip_rect);
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc
index e892b00..62e8913 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.cc
@@ -4,6 +4,8 @@
 
 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h"
 
+#include "ui/aura/null_window_targeter.h"
+#include "ui/aura/scoped_window_targeter.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_delegate.h"
 #include "ui/display/display.h"
@@ -67,6 +69,29 @@
   pending_x_visual_id_ = x_visual_id;
 }
 
+gfx::Rect DesktopWindowTreeHostLinux::GetXRootWindowOuterBounds() const {
+  return GetPlatformWindowLinux()->GetXRootWindowOuterBounds();
+}
+
+bool DesktopWindowTreeHostLinux::ContainsPointInXRegion(
+    const gfx::Point& point) const {
+  return GetPlatformWindowLinux()->ContainsPointInXRegion(point);
+}
+
+base::OnceClosure DesktopWindowTreeHostLinux::DisableEventListening() {
+  // Allows to open multiple file-pickers. See https://crbug.com/678982
+  modal_dialog_counter_++;
+  if (modal_dialog_counter_ == 1) {
+    // ScopedWindowTargeter is used to temporarily replace the event-targeter
+    // with NullWindowEventTargeter to make |dialog| modal.
+    targeter_for_modal_ = std::make_unique<aura::ScopedWindowTargeter>(
+        window(), std::make_unique<aura::NullWindowTargeter>());
+  }
+
+  return base::BindOnce(&DesktopWindowTreeHostLinux::EnableEventListening,
+                        weak_factory_.GetWeakPtr());
+}
+
 void DesktopWindowTreeHostLinux::Init(const Widget::InitParams& params) {
   DesktopWindowTreeHostPlatform::Init(params);
 
@@ -99,6 +124,31 @@
   return GetPlatformWindowLinux()->IsVisibleOnAllWorkspaces();
 }
 
+void DesktopWindowTreeHostLinux::SetOpacity(float opacity) {
+  DesktopWindowTreeHostPlatform::SetOpacity(opacity);
+  // Note that this is no-op for Wayland.
+  GetPlatformWindowLinux()->SetOpacityForXWindow(opacity);
+}
+
+base::flat_map<std::string, std::string>
+DesktopWindowTreeHostLinux::GetKeyboardLayoutMap() {
+  if (views::LinuxUI::instance())
+    return views::LinuxUI::instance()->GetKeyboardLayoutMap();
+  return {};
+}
+
+void DesktopWindowTreeHostLinux::InitModalType(ui::ModalType modal_type) {
+  switch (modal_type) {
+    case ui::MODAL_TYPE_NONE:
+      break;
+    default:
+      // TODO(erg): Figure out under what situations |modal_type| isn't
+      // none. The comment in desktop_native_widget_aura.cc suggests that this
+      // is rare.
+      NOTIMPLEMENTED();
+  }
+}
+
 void DesktopWindowTreeHostLinux::OnDisplayMetricsChanged(
     const display::Display& display,
     uint32_t changed_metrics) {
@@ -249,6 +299,16 @@
   }
 }
 
+void DesktopWindowTreeHostLinux::OnLostMouseGrab() {
+  dispatcher()->OnHostLostMouseGrab();
+}
+
+void DesktopWindowTreeHostLinux::EnableEventListening() {
+  DCHECK_GT(modal_dialog_counter_, 0UL);
+  if (!--modal_dialog_counter_)
+    targeter_for_modal_.reset();
+}
+
 const ui::PlatformWindowLinux*
 DesktopWindowTreeHostLinux::GetPlatformWindowLinux() const {
   return static_cast<const ui::PlatformWindowLinux*>(platform_window());
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h
index 534faf4..ceeabac 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h
@@ -6,11 +6,18 @@
 #define UI_VIEWS_WIDGET_DESKTOP_AURA_DESKTOP_WINDOW_TREE_HOST_LINUX_H_
 
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "ui/aura/scoped_window_targeter.h"
+#include "ui/gfx/geometry/rect.h"
 #include "ui/views/views_export.h"
 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_platform.h"
 
 class SkPath;
 
+namespace aura {
+class ScopedWindowTargeter;
+}  // namespace aura
+
 namespace ui {
 class PlatformWindowLinux;
 }  // namespace ui
@@ -32,6 +39,17 @@
   // be changed after. Useful for X11. Not in use for Wayland.
   void SetPendingXVisualId(int x_visual_id);
 
+  // Returns the current bounds in terms of the X11 Root Window including the
+  // borders provided by the window manager (if any). Not in use for Wayland.
+  gfx::Rect GetXRootWindowOuterBounds() const;
+
+  // Tells if the point is within X11 Root Window's region. Not in use for
+  // Wayland.
+  bool ContainsPointInXRegion(const gfx::Point& point) const;
+
+  // Disables event listening to make |dialog| modal.
+  base::OnceClosure DisableEventListening();
+
  protected:
   // Overridden from DesktopWindowTreeHost:
   void Init(const Widget::InitParams& params) override;
@@ -39,6 +57,9 @@
   std::string GetWorkspace() const override;
   void SetVisibleOnAllWorkspaces(bool always_visible) override;
   bool IsVisibleOnAllWorkspaces() const override;
+  void SetOpacity(float opacity) override;
+  base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
+  void InitModalType(ui::ModalType modal_type) override;
 
   // PlatformWindowDelegateBase:
   void DispatchEvent(ui::Event* event) override;
@@ -65,6 +86,10 @@
   // PlatformWindowDelegateLinux overrides:
   void OnWorkspaceChanged() override;
   void GetWindowMask(const gfx::Size& size, SkPath* window_mask) override;
+  void OnLostMouseGrab() override;
+
+  // Enables event listening after closing |dialog|.
+  void EnableEventListening();
 
   const ui::PlatformWindowLinux* GetPlatformWindowLinux() const;
   ui::PlatformWindowLinux* GetPlatformWindowLinux();
@@ -81,6 +106,13 @@
 
   std::unique_ptr<CompositorObserver> compositor_observer_;
 
+  std::unique_ptr<aura::ScopedWindowTargeter> targeter_for_modal_;
+
+  uint32_t modal_dialog_counter_ = 0;
+
+  // The display and the native X window hosting the root window.
+  base::WeakPtrFactory<DesktopWindowTreeHostLinux> weak_factory_{this};
+
   DISALLOW_COPY_AND_ASSIGN(DesktopWindowTreeHostLinux);
 };
 
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
index e697cf0..78e02d4 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
@@ -402,7 +402,7 @@
 
 void DesktopWindowTreeHostPlatform::SetShape(
     std::unique_ptr<Widget::ShapeRects> native_shape) {
-  NOTIMPLEMENTED_LOG_ONCE();
+  platform_window()->SetShape(std::move(native_shape), GetRootTransform());
 }
 
 void DesktopWindowTreeHostPlatform::Activate() {
@@ -559,26 +559,21 @@
 }
 
 void DesktopWindowTreeHostPlatform::SetOpacity(float opacity) {
-  // TODO: needs PlatformWindow support.
-  NOTIMPLEMENTED_LOG_ONCE();
+  GetContentWindow()->layer()->SetOpacity(opacity);
 }
 
 void DesktopWindowTreeHostPlatform::SetAspectRatio(
     const gfx::SizeF& aspect_ratio) {
-  // TODO: needs PlatformWindow support.
-  NOTIMPLEMENTED_LOG_ONCE();
+  platform_window()->SetAspectRatio(aspect_ratio);
 }
 
 void DesktopWindowTreeHostPlatform::SetWindowIcons(
     const gfx::ImageSkia& window_icon,
     const gfx::ImageSkia& app_icon) {
-  // TODO: needs PlatformWindow support.
-  NOTIMPLEMENTED_LOG_ONCE();
+  platform_window()->SetWindowIcons(window_icon, app_icon);
 }
 
 void DesktopWindowTreeHostPlatform::InitModalType(ui::ModalType modal_type) {
-  // TODO: needs PlatformWindow support (alternatively, remove as
-  // DesktopWindowTreeHostX11 doesn't support at all).
   NOTIMPLEMENTED_LOG_ONCE();
 }
 
@@ -587,21 +582,16 @@
 }
 
 bool DesktopWindowTreeHostPlatform::IsAnimatingClosed() const {
-  // TODO: needs PlatformWindow support.
-  NOTIMPLEMENTED_LOG_ONCE();
-  return false;
+  return platform_window()->IsAnimatingClosed();
 }
 
 bool DesktopWindowTreeHostPlatform::IsTranslucentWindowOpacitySupported()
     const {
-  // TODO: needs PlatformWindow support.
-  NOTIMPLEMENTED_LOG_ONCE();
-  return false;
+  return platform_window()->IsTranslucentWindowOpacitySupported();
 }
 
 void DesktopWindowTreeHostPlatform::SizeConstraintsChanged() {
-  // TODO: needs PlatformWindow support.
-  NOTIMPLEMENTED_LOG_ONCE();
+  platform_window()->SizeConstraintsChanged();
 }
 
 bool DesktopWindowTreeHostPlatform::ShouldUpdateWindowTransparency() const {
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
index 8bcf317..cbcebb0 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
@@ -129,18 +129,6 @@
   return windows;
 }
 
-gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowBounds() const {
-  return GetBoundsInPixels();
-}
-
-gfx::Rect DesktopWindowTreeHostX11::GetX11RootWindowOuterBounds() const {
-  return GetXWindow()->GetOutterBounds();
-}
-
-::Region DesktopWindowTreeHostX11::GetWindowShape() const {
-  return GetXWindow()->shape();
-}
-
 void DesktopWindowTreeHostX11::AddObserver(
     DesktopWindowTreeHostObserverX11* observer) {
   observer_list_.AddObserver(observer);
@@ -206,30 +194,6 @@
   return base::WrapUnique(drag_drop_client_);
 }
 
-void DesktopWindowTreeHostX11::SetShape(
-    std::unique_ptr<Widget::ShapeRects> native_shape) {
-  XRegion* xregion = nullptr;
-  if (native_shape) {
-    SkRegion native_region;
-    for (const gfx::Rect& rect : *native_shape)
-      native_region.op(gfx::RectToSkIRect(rect), SkRegion::kUnion_Op);
-    gfx::Transform transform = GetRootTransform();
-    if (!transform.IsIdentity() && !native_region.isEmpty()) {
-      SkPath path_in_dip;
-      if (native_region.getBoundaryPath(&path_in_dip)) {
-        SkPath path_in_pixels;
-        path_in_dip.transform(transform.matrix(), &path_in_pixels);
-        xregion = gfx::CreateRegionFromSkPath(path_in_pixels);
-      } else {
-        xregion = XCreateRegion();
-      }
-    } else {
-      xregion = gfx::CreateRegionFromSkRegion(native_region);
-    }
-  }
-  GetXWindow()->SetShape(xregion);
-}
-
 Widget::MoveLoopResult DesktopWindowTreeHostX11::RunMoveLoop(
     const gfx::Vector2d& drag_offset,
     Widget::MoveLoopSource source,
@@ -249,54 +213,6 @@
   x11_window_move_client_->EndMoveLoop();
 }
 
-void DesktopWindowTreeHostX11::SetOpacity(float opacity) {
-  GetXWindow()->SetOpacity(opacity);
-}
-
-void DesktopWindowTreeHostX11::SetAspectRatio(const gfx::SizeF& aspect_ratio) {
-  GetXWindow()->SetAspectRatio(aspect_ratio);
-}
-
-void DesktopWindowTreeHostX11::SetWindowIcons(const gfx::ImageSkia& window_icon,
-                                              const gfx::ImageSkia& app_icon) {
-  GetXWindow()->SetWindowIcons(window_icon, app_icon);
-}
-
-void DesktopWindowTreeHostX11::InitModalType(ui::ModalType modal_type) {
-  switch (modal_type) {
-    case ui::MODAL_TYPE_NONE:
-      break;
-    default:
-      // TODO(erg): Figure out under what situations |modal_type| isn't
-      // none. The comment in desktop_native_widget_aura.cc suggests that this
-      // is rare.
-      NOTIMPLEMENTED();
-  }
-}
-
-bool DesktopWindowTreeHostX11::IsAnimatingClosed() const {
-  return false;
-}
-
-bool DesktopWindowTreeHostX11::IsTranslucentWindowOpacitySupported() const {
-  // This function may be called before InitX11Window() (which
-  // initializes |visual_has_alpha_|), so we cannot simply return
-  // |visual_has_alpha_|.
-  return ui::XVisualManager::GetInstance()->ArgbVisualAvailable();
-}
-
-void DesktopWindowTreeHostX11::SizeConstraintsChanged() {
-  GetXWindow()->UpdateMinAndMaxSize();
-}
-
-bool DesktopWindowTreeHostX11::ShouldUseDesktopNativeCursorManager() const {
-  return true;
-}
-
-bool DesktopWindowTreeHostX11::ShouldCreateVisibilityController() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // DesktopWindowTreeHostX11, private:
 
@@ -309,38 +225,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 // DesktopWindowTreeHostX11 implementation:
 
-base::OnceClosure DesktopWindowTreeHostX11::DisableEventListening() {
-  // Allows to open multiple file-pickers. See https://crbug.com/678982
-  modal_dialog_counter_++;
-  if (modal_dialog_counter_ == 1) {
-    // ScopedWindowTargeter is used to temporarily replace the event-targeter
-    // with NullWindowEventTargeter to make |dialog| modal.
-    targeter_for_modal_ = std::make_unique<aura::ScopedWindowTargeter>(
-        window(), std::make_unique<aura::NullWindowTargeter>());
-  }
-
-  return base::BindOnce(&DesktopWindowTreeHostX11::EnableEventListening,
-                        weak_factory_.GetWeakPtr());
-}
-
-void DesktopWindowTreeHostX11::EnableEventListening() {
-  DCHECK_GT(modal_dialog_counter_, 0UL);
-  if (!--modal_dialog_counter_)
-    targeter_for_modal_.reset();
-}
-
-void DesktopWindowTreeHostX11::OnCompleteSwapWithNewSize(
-    const gfx::Size& size) {
-  GetXWindow()->NotifySwapAfterResize();
-}
-
-base::flat_map<std::string, std::string>
-DesktopWindowTreeHostX11::GetKeyboardLayoutMap() {
-  if (views::LinuxUI::instance())
-    return views::LinuxUI::instance()->GetKeyboardLayoutMap();
-  return {};
-}
-
 void DesktopWindowTreeHostX11::OnClosed() {
   open_windows().remove(GetAcceleratedWidget());
   DesktopWindowTreeHostLinux::OnClosed();
@@ -375,10 +259,6 @@
     observer.OnWindowUnmapped(GetXWindow()->window());
 }
 
-void DesktopWindowTreeHostX11::OnLostMouseGrab() {
-  dispatcher()->OnHostLostMouseGrab();
-}
-
 void DesktopWindowTreeHostX11::OnXWindowSelectionEvent(XEvent* xev) {
   DCHECK(xev);
   DCHECK(drag_drop_client_);
@@ -431,13 +311,6 @@
   }
 }
 
-ui::XWindow* DesktopWindowTreeHostX11::GetXWindow() {
-  DCHECK(platform_window());
-  // ui::X11Window inherits both PlatformWindow and ui::XWindow.
-  return static_cast<ui::XWindow*>(
-      static_cast<ui::X11Window*>(platform_window()));
-}
-
 const ui::XWindow* DesktopWindowTreeHostX11::GetXWindow() const {
   DCHECK(platform_window());
   // ui::X11Window inherits both PlatformWindow and ui::XWindow.
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
index e8b15e42..e641d8b 100644
--- a/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
+++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
@@ -18,7 +18,6 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
-#include "ui/aura/scoped_window_targeter.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/x/x11_types.h"
@@ -27,10 +26,6 @@
 #include "ui/views/views_export.h"
 #include "ui/views/widget/desktop_aura/desktop_window_tree_host_linux.h"
 
-namespace gfx {
-class ImageSkia;
-}
-
 namespace ui {
 enum class DomCode;
 class X11Window;
@@ -61,17 +56,6 @@
   // is the topmost window.
   static std::vector<aura::Window*> GetAllOpenWindows();
 
-  // Returns the current bounds in terms of the X11 Root Window.
-  gfx::Rect GetX11RootWindowBounds() const;
-
-  // Returns the current bounds in terms of the X11 Root Window including the
-  // borders provided by the window manager (if any).
-  gfx::Rect GetX11RootWindowOuterBounds() const;
-
-  // Returns the window shape if the window is not rectangular. Returns NULL
-  // otherwise.
-  ::Region GetWindowShape() const;
-
   void AddObserver(DesktopWindowTreeHostObserverX11* observer);
   void RemoveObserver(DesktopWindowTreeHostObserverX11* observer);
 
@@ -79,34 +63,17 @@
   // internal list of open windows.
   static void CleanUpWindowList(void (*func)(aura::Window* window));
 
-  // Disables event listening to make |dialog| modal.
-  base::OnceClosure DisableEventListening();
-
-  // Returns a map of KeyboardEvent code to KeyboardEvent key values.
-  base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
-
  protected:
   // Overridden from DesktopWindowTreeHost:
   void Init(const Widget::InitParams& params) override;
   void OnNativeWidgetCreated(const Widget::InitParams& params) override;
   std::unique_ptr<aura::client::DragDropClient> CreateDragDropClient(
       DesktopNativeCursorManager* cursor_manager) override;
-  void SetShape(std::unique_ptr<Widget::ShapeRects> native_shape) override;
   Widget::MoveLoopResult RunMoveLoop(
       const gfx::Vector2d& drag_offset,
       Widget::MoveLoopSource source,
       Widget::MoveLoopEscapeBehavior escape_behavior) override;
   void EndMoveLoop() override;
-  void SetOpacity(float opacity) override;
-  void SetAspectRatio(const gfx::SizeF& aspect_ratio) override;
-  void SetWindowIcons(const gfx::ImageSkia& window_icon,
-                      const gfx::ImageSkia& app_icon) override;
-  void InitModalType(ui::ModalType modal_type) override;
-  bool IsAnimatingClosed() const override;
-  bool IsTranslucentWindowOpacitySupported() const override;
-  void SizeConstraintsChanged() override;
-  bool ShouldUseDesktopNativeCursorManager() const override;
-  bool ShouldCreateVisibilityController() const override;
 
  private:
   friend class DesktopWindowTreeHostX11HighDPITest;
@@ -114,12 +81,6 @@
   // See comment for variable open_windows_.
   static std::list<XID>& open_windows();
 
-  // Enables event listening after closing |dialog|.
-  void EnableEventListening();
-
-  // Callback for a swapbuffer after resize.
-  void OnCompleteSwapWithNewSize(const gfx::Size& size) override;
-
   // PlatformWindowDelegate overrides:
   //
   // DWTHX11 temporarily overrides the PlatformWindowDelegate methods instead of
@@ -131,7 +92,6 @@
   void OnActivationChanged(bool active) override;
   void OnXWindowMapped() override;
   void OnXWindowUnmapped() override;
-  void OnLostMouseGrab() override;
 
   // Overridden from ui::XEventDelegate.
   void OnXWindowSelectionEvent(XEvent* xev) override;
@@ -142,7 +102,6 @@
   // solution to access XWindow, which is subclassed by the X11Window, which is
   // PlatformWindow. This will be removed once we no longer to access XWindow
   // directly. See https://crbug.com/990756.
-  ui::XWindow* GetXWindow();
   const ui::XWindow* GetXWindow() const;
 
   DesktopDragDropClientAuraX11* drag_drop_client_ = nullptr;
@@ -156,10 +115,6 @@
   // destroyed.
   static std::list<gfx::AcceleratedWidget>* open_windows_;
 
-  std::unique_ptr<aura::ScopedWindowTargeter> targeter_for_modal_;
-
-  uint32_t modal_dialog_counter_ = 0;
-
   // The display and the native X window hosting the root window.
   base::WeakPtrFactory<DesktopWindowTreeHostX11> weak_factory_{this};
 
diff --git a/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc b/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc
index 37d96bf..4ef8e358e 100644
--- a/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc
+++ b/ui/views/widget/desktop_aura/x11_topmost_window_finder.cc
@@ -72,21 +72,16 @@
   if (!window->IsVisible())
     return false;
 
-  DesktopWindowTreeHostX11* host =
-      DesktopWindowTreeHostX11::GetHostForXID(
-          window->GetHost()->GetAcceleratedWidget());
-  if (!host->GetX11RootWindowOuterBounds().Contains(screen_loc_in_pixels_))
+  DesktopWindowTreeHostX11* host = DesktopWindowTreeHostX11::GetHostForXID(
+      window->GetHost()->GetAcceleratedWidget());
+  if (!host->GetXRootWindowOuterBounds().Contains(screen_loc_in_pixels_))
     return false;
 
-  ::Region shape = host->GetWindowShape();
-  if (!shape)
-    return true;
-
   aura::client::ScreenPositionClient* screen_position_client =
       aura::client::GetScreenPositionClient(window->GetRootWindow());
   gfx::Point window_loc(screen_loc_in_pixels_);
   screen_position_client->ConvertPointFromScreen(window, &window_loc);
-  return XPointInRegion(shape, window_loc.x(), window_loc.y()) == x11::True;
+  return host->ContainsPointInXRegion(window_loc);
 }
 
 }  // namespace views
diff --git a/ui/views/window/dialog_client_view.cc b/ui/views/window/dialog_client_view.cc
index 9d7c5b5..533cfbe 100644
--- a/ui/views/window/dialog_client_view.cc
+++ b/ui/views/window/dialog_client_view.cc
@@ -225,7 +225,7 @@
   // dialog style simply inherits the bubble's frame view color.
   const DialogDelegate* dialog = GetDialogDelegate();
 
-  if (dialog && !dialog->ShouldUseCustomFrame()) {
+  if (dialog && !dialog->use_custom_frame()) {
     SetBackground(views::CreateSolidBackground(GetNativeTheme()->GetSystemColor(
         ui::NativeTheme::kColorId_DialogBackground)));
   }
diff --git a/ui/views/window/dialog_client_view_unittest.cc b/ui/views/window/dialog_client_view_unittest.cc
index 1647c36..354adea 100644
--- a/ui/views/window/dialog_client_view_unittest.cc
+++ b/ui/views/window/dialog_client_view_unittest.cc
@@ -39,6 +39,8 @@
   void SetUp() override {
     WidgetTest::SetUp();
 
+    DialogDelegate::set_use_custom_frame(false);
+
     // Note: not using DialogDelegate::CreateDialogWidget(..), since that can
     // alter the frame type according to the platform.
     widget_ = new views::Widget;
@@ -62,8 +64,6 @@
     return client_view_;
   }
 
-  bool ShouldUseCustomFrame() const override { return false; }
-
   void DeleteDelegate() override {
     // DialogDelegateView would delete this, but |this| is owned by the test.
   }
diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc
index e9b59cfb..61d4e59 100644
--- a/ui/views/window/dialog_delegate.cc
+++ b/ui/views/window/dialog_delegate.cc
@@ -81,9 +81,9 @@
   DialogDelegate* dialog = delegate->AsDialogDelegate();
 
   if (dialog)
-    dialog->supports_custom_frame_ &= CanSupportCustomFrame(parent);
+    dialog->params_.custom_frame &= CanSupportCustomFrame(parent);
 
-  if (!dialog || dialog->ShouldUseCustomFrame()) {
+  if (!dialog || dialog->use_custom_frame()) {
     params.opacity = Widget::InitParams::TRANSLUCENT_WINDOW;
     params.remove_standard_frame = true;
 #if !defined(OS_MACOSX)
@@ -211,7 +211,7 @@
 }
 
 NonClientFrameView* DialogDelegate::CreateNonClientFrameView(Widget* widget) {
-  if (ShouldUseCustomFrame())
+  if (use_custom_frame())
     return CreateDialogFrameView(widget);
   return WidgetDelegate::CreateNonClientFrameView(widget);
 }
@@ -241,10 +241,6 @@
   return frame;
 }
 
-bool DialogDelegate::ShouldUseCustomFrame() const {
-  return supports_custom_frame_;
-}
-
 const DialogClientView* DialogDelegate::GetDialogClientView() const {
   if (!GetWidget())
     return nullptr;
diff --git a/ui/views/window/dialog_delegate.h b/ui/views/window/dialog_delegate.h
index 28ff960..5431cf1b 100644
--- a/ui/views/window/dialog_delegate.h
+++ b/ui/views/window/dialog_delegate.h
@@ -41,6 +41,12 @@
     base::Optional<int> default_button = base::nullopt;
     bool round_corners = true;
     bool draggable = false;
+
+    // Whether to use the Views-styled frame (if true) or a platform-native
+    // frame if false. In general, dialogs that look like fully separate windows
+    // should use the platform-native frame, and all other dialogs should use
+    // the Views-styled one.
+    bool custom_frame = true;
   };
 
   DialogDelegate();
@@ -131,11 +137,6 @@
 
   static NonClientFrameView* CreateDialogFrameView(Widget* widget);
 
-  // Returns true if this particular dialog should use a Chrome-styled frame
-  // like the one used for bubbles. The alternative is a more platform-native
-  // frame.
-  virtual bool ShouldUseCustomFrame() const;
-
   const gfx::Insets& margins() const { return margins_; }
   void set_margins(const gfx::Insets& margins) { margins_ = margins; }
 
@@ -155,6 +156,8 @@
   void set_use_round_corners(bool round) { params_.round_corners = round; }
   void set_draggable(bool draggable) { params_.draggable = draggable; }
   bool draggable() const { return params_.draggable; }
+  void set_use_custom_frame(bool use) { params_.custom_frame = use; }
+  bool use_custom_frame() const { return params_.custom_frame; }
 
  protected:
   ~DialogDelegate() override;
@@ -165,10 +168,6 @@
   const Params& GetParams() const { return params_; }
 
  private:
-  // A flag indicating whether this dialog is able to use the custom frame
-  // style for dialogs.
-  bool supports_custom_frame_ = true;
-
   // The margins between the content and the inside of the border.
   // TODO(crbug.com/733040): Most subclasses assume they must set their own
   // margins explicitly, so we set them to 0 here for now to avoid doubled
diff --git a/ui/views/window/dialog_delegate_unittest.cc b/ui/views/window/dialog_delegate_unittest.cc
index 8cd18bd8e..95754f97 100644
--- a/ui/views/window/dialog_delegate_unittest.cc
+++ b/ui/views/window/dialog_delegate_unittest.cc
@@ -69,7 +69,6 @@
   }
   base::string16 GetWindowTitle() const override { return title_; }
   View* GetInitiallyFocusedView() override { return input_; }
-  bool ShouldUseCustomFrame() const override { return true; }
   int GetDialogButtons() const override { return dialog_buttons_; }
 
   void CheckAndResetStates(bool canceled,
@@ -123,12 +122,24 @@
 
   void SetUp() override {
     ViewsTestBase::SetUp();
+
+    // These tests all expect to use a custom frame on the dialog so they can
+    // control hit-testing and other behavior. Custom frames are only supported
+    // with a parent widget, so create the parent widget here.
+    views::Widget::InitParams params =
+        CreateParams(views::Widget::InitParams::TYPE_WINDOW);
+    params.bounds = gfx::Rect(10, 11, 200, 200);
+    params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+    parent_widget_.Init(std::move(params));
+    parent_widget_.Show();
+
     InitializeDialog();
     ShowDialog();
   }
 
   void TearDown() override {
     dialog_->TearDown();
+    parent_widget_.Close();
     ViewsTestBase::TearDown();
   }
 
@@ -140,10 +151,14 @@
     dialog_->Init();
   }
 
-  void ShowDialog() {
-    DialogDelegate::CreateDialogWidget(dialog_, GetContext(), nullptr)->Show();
+  views::Widget* CreateDialogWidget(DialogDelegate* dialog) {
+    views::Widget* widget = DialogDelegate::CreateDialogWidget(
+        dialog, GetContext(), parent_widget_.GetNativeView());
+    return widget;
   }
 
+  void ShowDialog() { CreateDialogWidget(dialog_)->Show(); }
+
   void SimulateKeyEvent(const ui::KeyEvent& event) {
     ui::KeyEvent event_copy = event;
     if (dialog()->GetFocusManager()->OnKeyEvent(event_copy))
@@ -151,8 +166,10 @@
   }
 
   TestDialog* dialog() const { return dialog_; }
+  views::Widget* parent_widget() { return &parent_widget_; }
 
  private:
+  views::Widget parent_widget_;
   TestDialog* dialog_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(DialogTest);
@@ -301,7 +318,7 @@
 TEST_F(DialogTest, BoundsAccommodateTitle) {
   TestDialog* dialog2(new TestDialog());
   dialog2->set_title(base::ASCIIToUTF16("Title"));
-  DialogDelegate::CreateDialogWidget(dialog2, GetContext(), nullptr);
+  CreateDialogWidget(dialog2);
 
   // Remove the close button so it doesn't influence the bounds if it's taller
   // than the title.
@@ -369,8 +386,7 @@
 // focus, test it is still able to receive focus once the Widget is activated.
 TEST_F(DialogTest, InitialFocusWithDeactivatedWidget) {
   InitialFocusTestDialog* dialog = new InitialFocusTestDialog();
-  Widget* dialog_widget =
-      DialogDelegate::CreateDialogWidget(dialog, GetContext(), nullptr);
+  Widget* dialog_widget = CreateDialogWidget(dialog);
   // Set the initial focus while the Widget is unactivated to prevent the
   // initially focused View from receiving focus. Use a minimised state here to
   // prevent the Widget from being activated while this happens.
@@ -402,8 +418,7 @@
   DialogDelegateView* dialog = new DialogDelegateView();
   Textfield* textfield = new Textfield();
   dialog->AddChildView(textfield);
-  Widget* dialog_widget =
-      DialogDelegate::CreateDialogWidget(dialog, GetContext(), nullptr);
+  Widget* dialog_widget = CreateDialogWidget(dialog);
 
 #if !defined(OS_MACOSX)
   // For non-Mac, turn off focusability on all the dialog's buttons manually.