diff --git a/DEPS b/DEPS
index 9a6bffc..6e43346 100644
--- a/DEPS
+++ b/DEPS
@@ -309,7 +309,7 @@
   # 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': '3b7a62e2ac3f4c4dcb00e122f7728865cb125c87',
+  'skia_revision': '55b8b5b71355ab383a379652577109feea758a85',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -317,7 +317,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': 'eb6d1a82313c5852999968d6d678d7c04c6cf8c4',
+  'angle_revision': 'c5eb810b941fff42bd4d1a8c884bf33e733b4626',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -360,7 +360,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': 'b0265ccd336cafce6865f6f260e9b61d69459b7e',
+  'freetype_revision': 'c580926f354108c1e693364dbe9e64af2d11038a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -380,11 +380,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '23e70e69e5584cd120a57befe5896df916e91dcc',
+  'catapult_revision': 'e1208d01fe87e354960b5f91128aacd65d11f041',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling chromium_variations
   # and whatever else without interference from each other.
-  'chromium_variations_revision': '0a32d1cfed9c8329fbc36c7ed4c264a2b3bdd860',
+  'chromium_variations_revision': 'cc3abd9b31c38f36ad77f404adf37837e33c4c3a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling CrossBench
   # and whatever else without interference from each other.
@@ -824,7 +824,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    '5649615b9c2b9521f10acd5a4d48a729225b9474',
+    '0b6331f42591e5867461997a30f034db138ebae2',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -1183,7 +1183,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '74e55f68b5d4e5e0e958a02b306cc062caf1c7ca',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '5976e0d356895032a85474c875ed9960ba146a98',
       'condition': 'checkout_chromeos',
   },
 
@@ -1467,7 +1467,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/kotlinc',
-              'version': 'qeRCtEA1uhs8D1wL8wj0UZllCoScbcA6QrEQu9g4NGoC',
+              'version': 'y9zd2-JF5FESwNZEVJnnejmk6J97g7fjlmwxNaMuJAoC',
           },
       ],
       'condition': 'checkout_android',
@@ -1678,7 +1678,7 @@
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '09a4f3ec842a8932341b195c5b01e141c8a16eb7',
 
   'src/third_party/openscreen/src':
-    Var('chromium_git') + '/openscreen' + '@' + '96daa682c82a8e7cce45da9cbc49bc4b0ec504bb',
+    Var('chromium_git') + '/openscreen' + '@' + '4701cb1e1777f08c3a40c4f6085f91a294cefc71',
 
   'src/third_party/openxr/src': {
     'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + '58a00cf85c39ad5ec4dc43a769624e420c06179a',
@@ -1871,7 +1871,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'f4bf599a8b575df685c31d9c4729a70a04e377ed',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'd3e4c5300efaec139cc5728c3455508386fe4db2',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'e14e419cf67727abe03646e35b7460f96b9d5051',
 
   'src/third_party/webrtc':
     Var('webrtc_git') + '/src.git' + '@' + '9dac048f176f9ba857be9baa973840dfa7f18b13',
@@ -2008,7 +2008,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'FvLaeQSoWZuGaOhPguxDbSLl5gvzTt6_ekzGbEVwj6YC',
+        'version': '_rX_N8Me5oLyS71fB-V0tKB3swszffgV4O24PY-ShfoC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4031,7 +4031,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        '7dd4f693cac89c32dd5001e682b2f6e9e3efcee5',
+        '26f33f95250902dbd2a39dba186ac5998d41dbf1',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/android_webview/browser/aw_user_agent_metadata.cc b/android_webview/browser/aw_user_agent_metadata.cc
index 88da65f3..741954f 100644
--- a/android_webview/browser/aw_user_agent_metadata.cc
+++ b/android_webview/browser/aw_user_agent_metadata.cc
@@ -15,6 +15,7 @@
 using base::android::Java2dStringArrayTo2dStringVector;
 using base::android::ScopedJavaLocalRef;
 using base::android::ToJavaArrayOfStringArray;
+using base::android::ToJavaArrayOfStrings;
 
 namespace android_webview {
 
@@ -90,8 +91,9 @@
 
   ua_metadata.wow64 = Java_AwUserAgentMetadata_isWow64(env, java_ua_metadata);
 
-  ua_metadata.form_factor = ConvertJavaStringToUTF8Wrapper(
-      Java_AwUserAgentMetadata_getFormFactor(env, java_ua_metadata));
+  AppendJavaStringArrayToStringVector(
+      env, Java_AwUserAgentMetadata_getFormFactor(env, java_ua_metadata),
+      &ua_metadata.form_factor);
 
   return ua_metadata;
 }
@@ -128,8 +130,8 @@
   ScopedJavaLocalRef<jstring> java_bitness =
       ConvertUTF8ToJavaString(env, ua_metadata.bitness);
   jboolean java_wow64 = ua_metadata.wow64;
-  ScopedJavaLocalRef<jstring> java_form_factor =
-      ConvertUTF8ToJavaString(env, ua_metadata.form_factor);
+  ScopedJavaLocalRef<jobjectArray> java_form_factor =
+      ToJavaArrayOfStrings(env, ua_metadata.form_factor);
 
   return Java_AwUserAgentMetadata_create(
       env, java_brand_version_list, java_brand_full_version_lis,
diff --git a/android_webview/browser/aw_user_agent_metadata_unittest.cc b/android_webview/browser/aw_user_agent_metadata_unittest.cc
index 6512ba4..d67330ad 100644
--- a/android_webview/browser/aw_user_agent_metadata_unittest.cc
+++ b/android_webview/browser/aw_user_agent_metadata_unittest.cc
@@ -79,7 +79,7 @@
       .mobile = true,
       .bitness = "64",
       .wow64 = false,
-      .form_factor = ""};
+      .form_factor = {"Desktop", "Mobile"}};
   verifyUaMetadata(ua_metadata,
                    FromJavaAwUserAgentMetadata(
                        env(), ToJavaAwUserAgentMetadata(env(), ua_metadata)));
@@ -98,7 +98,7 @@
       .mobile = true,
       .bitness = "64",
       .wow64 = false,
-      .form_factor = ""};
+      .form_factor = {"Desktop"}};
   verifyUaMetadata(ua_metadata,
                    FromJavaAwUserAgentMetadata(
                        env(), ToJavaAwUserAgentMetadata(env(), ua_metadata)));
@@ -117,7 +117,7 @@
       .mobile = true,
       .bitness = "64",
       .wow64 = false,
-      .form_factor = ""};
+      .form_factor = {}};
   verifyUaMetadata(ua_metadata,
                    FromJavaAwUserAgentMetadata(
                        env(), ToJavaAwUserAgentMetadata(env(), ua_metadata)));
@@ -135,7 +135,7 @@
       .mobile = true,
       .bitness = "64",
       .wow64 = false,
-      .form_factor = ""};
+      .form_factor = {"Desktop"}};
   verifyUaMetadata(ua_metadata,
                    FromJavaAwUserAgentMetadata(
                        env(), ToJavaAwUserAgentMetadata(env(), ua_metadata)));
@@ -153,7 +153,7 @@
       .mobile = false,
       .bitness = "",
       .wow64 = false,
-      .form_factor = ""};
+      .form_factor = {"Desktop"}};
   verifyUaMetadata(ua_metadata,
                    FromJavaAwUserAgentMetadata(
                        env(), ToJavaAwUserAgentMetadata(env(), ua_metadata)));
diff --git a/android_webview/java/src/org/chromium/android_webview/client_hints/AwUserAgentMetadata.java b/android_webview/java/src/org/chromium/android_webview/client_hints/AwUserAgentMetadata.java
index 3eed4ce..356aa07 100644
--- a/android_webview/java/src/org/chromium/android_webview/client_hints/AwUserAgentMetadata.java
+++ b/android_webview/java/src/org/chromium/android_webview/client_hints/AwUserAgentMetadata.java
@@ -35,7 +35,7 @@
     private boolean mMobile;
     private int mBitness;
     private boolean mWow64;
-    private String mFormFactor;
+    private @FormFactors String[] mFormFactor;
 
     /**
      * Key for the user-agent metadata properties.
@@ -65,6 +65,32 @@
      */
     public static final int BRAND_VERSION_LENGTH = 3;
 
+    /**
+     * Values for the Sec-CH-UA-Form-Factor header.
+     * https://wicg.github.io/ua-client-hints/#sec-ch-ua-form-factor
+     */
+    // LINT.IfChange
+    @StringDef({
+        FormFactors.DESKTOP,
+        FormFactors.AUTOMOTIVE,
+        FormFactors.MOBILE,
+        FormFactors.TABLET,
+        FormFactors.XR,
+        FormFactors.EINK,
+        FormFactors.WATCH
+    })
+    // LINT.ThenChange(/third_party/blink/public/common/user_agent/user_agent_metadata.h)
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FormFactors {
+        String DESKTOP = "Desktop";
+        String AUTOMOTIVE = "Automotive";
+        String MOBILE = "Mobile";
+        String TABLET = "Tablet";
+        String XR = "XR";
+        String EINK = "EInk";
+        String WATCH = "Watch";
+    };
+
     // To better manage the data within this class, make the constructor as private to avoid
     // creating instances outside of the class.
     private AwUserAgentMetadata() {}
@@ -152,7 +178,7 @@
     }
 
     @CalledByNative
-    private String getFormFactor() {
+    private @FormFactors String[] getFormFactor() {
         return mFormFactor;
     }
 
@@ -160,10 +186,18 @@
      * Construct a AwUserAgentMetadata instance, and low-entropy client hints should not be null.
      */
     @CalledByNative
-    private static AwUserAgentMetadata create(@NonNull String[][] brandVersionList,
-            String[][] brandFullVersionList, String fullVersion, @NonNull String platform,
-            String platformVersion, String architecture, String model, boolean mobile,
-            String bitness, boolean wow64, String formFactor) {
+    private static AwUserAgentMetadata create(
+            @NonNull String[][] brandVersionList,
+            String[][] brandFullVersionList,
+            String fullVersion,
+            @NonNull String platform,
+            String platformVersion,
+            String architecture,
+            String model,
+            boolean mobile,
+            String bitness,
+            boolean wow64,
+            @FormFactors String[] formFactor) {
         AwUserAgentMetadata result = new AwUserAgentMetadata();
         result.mBrandVersionList = new String[brandVersionList.length][BRAND_VERSION_LENGTH];
         for (int i = 0; i < brandVersionList.length; i++) {
@@ -271,6 +305,19 @@
             }
         }
 
+        Object formFactorValue = uaMetadataMap.get(MetadataKeys.FORM_FACTOR);
+        @FormFactors String[] formFactor = defaultData.mFormFactor;
+        if (formFactorValue != null) {
+            if (!(formFactorValue instanceof String[])) {
+                throw new IllegalArgumentException(
+                        "AwUserAgentMetadata map does not have "
+                                + "right type of value for key: "
+                                + MetadataKeys.FORM_FACTOR);
+            }
+            @FormFactors String[] asArray = (String[]) formFactorValue;
+            formFactor = Arrays.copyOf(asArray, asArray.length);
+        }
+
         AwUserAgentMetadata result = new AwUserAgentMetadata();
         result.mBrandVersionList = brandVersionList;
         result.mFullVersion = getValueAsString(
@@ -285,8 +332,7 @@
         result.mMobile = getValueAsBoolean(uaMetadataMap, MetadataKeys.MOBILE, defaultData.mMobile);
         result.mBitness = getValueAsInt(uaMetadataMap, MetadataKeys.BITNESS, defaultData.mBitness);
         result.mWow64 = getValueAsBoolean(uaMetadataMap, MetadataKeys.WOW64, defaultData.mWow64);
-        result.mFormFactor =
-                getValueAsString(uaMetadataMap, MetadataKeys.FORM_FACTOR, defaultData.mFormFactor);
+        result.mFormFactor = formFactor;
         return result;
     }
 
@@ -314,19 +360,30 @@
             return false;
         }
         AwUserAgentMetadata that = (AwUserAgentMetadata) o;
-        return mMobile == that.mMobile && mWow64 == that.mWow64 && mBitness == that.mBitness
+        return mMobile == that.mMobile
+                && mWow64 == that.mWow64
+                && mBitness == that.mBitness
                 && Arrays.deepEquals(mBrandVersionList, that.mBrandVersionList)
                 && Objects.equals(mFullVersion, that.mFullVersion)
                 && Objects.equals(mPlatform, that.mPlatform)
                 && Objects.equals(mPlatformVersion, that.mPlatformVersion)
                 && Objects.equals(mArchitecture, that.mArchitecture)
                 && Objects.equals(mModel, that.mModel)
-                && Objects.equals(mFormFactor, that.mFormFactor);
+                && Arrays.deepEquals(mFormFactor, that.mFormFactor);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(Arrays.deepHashCode(mBrandVersionList), mFullVersion, mPlatform,
-                mPlatformVersion, mArchitecture, mModel, mMobile, mBitness, mWow64, mFormFactor);
+        return Objects.hash(
+                Arrays.deepHashCode(mBrandVersionList),
+                mFullVersion,
+                mPlatform,
+                mPlatformVersion,
+                mArchitecture,
+                mModel,
+                mMobile,
+                mBitness,
+                mWow64,
+                Arrays.deepHashCode(mFormFactor));
     }
 }
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
index 07eaef9..157e111 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -287,6 +287,9 @@
                 AutofillFeatures.AUTOFILL_ENABLE_SUPPORT_FOR_LANDMARK,
                 "When enabled, Autofill supports landmark fields."),
         Flag.baseFeature(
+                AutofillFeatures.AUTOFILL_ENABLE_PARSING_OF_STREET_LOCATION,
+                "When enabled, Autofill supports parsing fields as street locations."),
+        Flag.baseFeature(
                 AutofillFeatures.AUTOFILL_ENABLE_SUPPORT_FOR_APARTMENT_NUMBERS,
                 "When enabled, Autofill supports apartment number fields."),
         Flag.baseFeature(
@@ -500,6 +503,7 @@
         Flag.baseFeature(BlinkFeatures.SOLID_COLOR_LAYERS),
         Flag.baseFeature(BlinkFeatures.EXPAND_COMPOSITED_CULL_RECT),
         Flag.baseFeature(BlinkFeatures.SCROLLBAR_COLOR),
+        Flag.baseFeature(BlinkFeatures.ONE_PASS_RASTER_INVALIDATION),
         Flag.baseFeature(
                 BlinkFeatures.DELAY_OUT_OF_VIEWPORT_LAZY_IMAGES,
                 "Delays out-of-viewport lazy loaded images."),
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/ClientHintsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/ClientHintsTest.java
index 811610a..4da41b8 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/ClientHintsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/ClientHintsTest.java
@@ -239,7 +239,8 @@
         Assert.assertEquals("HEADER_NOT_FOUND", jsonObject.getString("sec-ch-ua-wow64"));
         // This client hint isn't sent when data-saver is off.
         Assert.assertEquals("HEADER_NOT_FOUND", jsonObject.getString("save-data"));
-        Assert.assertNotEquals("HEADER_NOT_FOUND", jsonObject.getString("sec-ch-prefers-reduced-motion"));
+        Assert.assertNotEquals(
+                "HEADER_NOT_FOUND", jsonObject.getString("sec-ch-prefers-reduced-motion"));
         Assert.assertEquals("HEADER_NOT_FOUND", jsonObject.getString("sec-ch-ua-form-factor"));
         Assert.assertNotEquals(
                 "HEADER_NOT_FOUND", jsonObject.getString("sec-ch-prefers-reduced-transparency"));
@@ -978,7 +979,8 @@
         Assert.assertEquals("?1", clientHintsMap.get("sec-ch-ua-mobile"));
         Assert.assertEquals("\"128\"", clientHintsMap.get("sec-ch-ua-bitness"));
         Assert.assertEquals("?1", clientHintsMap.get("sec-ch-ua-wow64"));
-        Assert.assertEquals("\"fake_mobile\"", clientHintsMap.get("sec-ch-ua-form-factor"));
+        Assert.assertEquals(
+                "\"Automotive\", \"Tablet\"", clientHintsMap.get("sec-ch-ua-form-factor"));
 
         // Verify js client hints result.
         JSONObject jsClientHints = clientHintsResult.mJsClientHints;
@@ -998,7 +1000,7 @@
         Assert.assertTrue(jsClientHints.getBoolean("mobile"));
         Assert.assertEquals("128", jsClientHints.getString("bitness"));
         Assert.assertTrue(jsClientHints.getBoolean("wow64"));
-        Assert.assertEquals("fake_mobile", jsClientHints.getString("formFactor"));
+        Assert.assertEquals("[\"Automotive\",\"Tablet\"]", jsClientHints.getString("formFactor"));
     }
 
     private Map<String, Object> makeFakeMetadata() {
@@ -1014,7 +1016,9 @@
         settings.put(AwUserAgentMetadata.MetadataKeys.MOBILE, true);
         settings.put(AwUserAgentMetadata.MetadataKeys.BITNESS, 128);
         settings.put(AwUserAgentMetadata.MetadataKeys.WOW64, true);
-        settings.put(AwUserAgentMetadata.MetadataKeys.FORM_FACTOR, "fake_mobile");
+        settings.put(
+                AwUserAgentMetadata.MetadataKeys.FORM_FACTOR,
+                new String[] {"Automotive", "Tablet"});
         return settings;
     }
 
diff --git a/ash/ambient/managed/screensaver_image_downloader.cc b/ash/ambient/managed/screensaver_image_downloader.cc
index 2347223..2b7349d0 100644
--- a/ash/ambient/managed/screensaver_image_downloader.cc
+++ b/ash/ambient/managed/screensaver_image_downloader.cc
@@ -119,9 +119,8 @@
 }
 
 std::string GetHashedFileNameForUrl(const std::string& url) {
-  const std::string hash = base::SHA1HashString(url);
-  const std::string encoded_hash = base::HexEncode(hash.data(), hash.size());
-  return encoded_hash + kCacheFileExt;
+  auto hash = base::SHA1HashSpan(base::as_bytes(base::make_span(url)));
+  return base::HexEncode(hash) + kCacheFileExt;
 }
 
 std::vector<std::string> GetImageUrlsToProcess(
diff --git a/ash/ambient/managed/screensaver_image_downloader_unittest.cc b/ash/ambient/managed/screensaver_image_downloader_unittest.cc
index 2d7db0d..8f08abfa 100644
--- a/ash/ambient/managed/screensaver_image_downloader_unittest.cc
+++ b/ash/ambient/managed/screensaver_image_downloader_unittest.cc
@@ -89,8 +89,8 @@
   }
 
   base::FilePath GetExpectedFilePath(const std::string url) {
-    const std::string hash = base::SHA1HashString(url);
-    const std::string encoded_hash = base::HexEncode(hash.data(), hash.size());
+    auto hash = base::SHA1HashSpan(base::as_bytes(base::make_span(url)));
+    const std::string encoded_hash = base::HexEncode(hash);
     return test_download_folder_.AppendASCII(encoded_hash + kCacheFileExt);
   }
 
diff --git a/ash/ambient/managed/screensaver_images_policy_handler_unittest.cc b/ash/ambient/managed/screensaver_images_policy_handler_unittest.cc
index 556f342..b3f006a 100644
--- a/ash/ambient/managed/screensaver_images_policy_handler_unittest.cc
+++ b/ash/ambient/managed/screensaver_images_policy_handler_unittest.cc
@@ -267,11 +267,10 @@
   void ResetScreensaverImagesPolicyHandler() { policy_handler_.reset(); }
 
   base::FilePath GetExpectedFilePath(const std::string url) {
-    const std::string hash = base::SHA1HashString(url);
-    const std::string encoded_hash = base::HexEncode(hash.data(), hash.size());
+    auto hash = base::SHA1HashSpan(base::as_bytes(base::make_span(url)));
     return temp_dir_.GetPath()
         .AppendASCII(GetParam().base_directory)
-        .AppendASCII(encoded_hash + kCacheFileExt);
+        .AppendASCII(base::HexEncode(hash) + kCacheFileExt);
   }
 };
 
diff --git a/ash/api/tasks/tasks_delegate.h b/ash/api/tasks/tasks_delegate.h
index 7fd4f51..1f88c194 100644
--- a/ash/api/tasks/tasks_delegate.h
+++ b/ash/api/tasks/tasks_delegate.h
@@ -42,6 +42,16 @@
 
   // Sends cached tasks completion data to the Google Tasks API.
   virtual void SendCompletedTasks() = 0;
+
+  // Adds a task with the given `title` to the task list with id `task_list_id`.
+  virtual void AddTask(const std::string& task_list_id,
+                       const std::string& title) = 0;
+
+  // Updates the title of the task in the task list with id `task_list_id`
+  // with id `task_id`.
+  virtual void UpdateTaskTitle(const std::string& task_list_id,
+                               const std::string& task_id,
+                               const std::string& title) = 0;
 };
 
 }  // namespace ash::api
diff --git a/ash/api/tasks/test_tasks_delegate.cc b/ash/api/tasks/test_tasks_delegate.cc
index 2e725e6..a6c069d 100644
--- a/ash/api/tasks/test_tasks_delegate.cc
+++ b/ash/api/tasks/test_tasks_delegate.cc
@@ -39,4 +39,15 @@
   NOTIMPLEMENTED();
 }
 
+void TestTasksDelegate::AddTask(const std::string& task_list_id,
+                                const std::string& title) {
+  NOTIMPLEMENTED();
+}
+
+void TestTasksDelegate::UpdateTaskTitle(const std::string& task_list_id,
+                                        const std::string& task_id,
+                                        const std::string& title) {
+  NOTIMPLEMENTED();
+}
+
 }  // namespace ash::api
diff --git a/ash/api/tasks/test_tasks_delegate.h b/ash/api/tasks/test_tasks_delegate.h
index 2ea0176e..36ec6aaf 100644
--- a/ash/api/tasks/test_tasks_delegate.h
+++ b/ash/api/tasks/test_tasks_delegate.h
@@ -26,6 +26,11 @@
                        const std::string& task_id,
                        bool completed) override;
   void SendCompletedTasks() override;
+  void AddTask(const std::string& task_list_id,
+               const std::string& title) override;
+  void UpdateTaskTitle(const std::string& task_list_id,
+                       const std::string& task_id,
+                       const std::string& title) override;
 };
 
 }  // namespace ash::api
diff --git a/ash/display/display_manager_unittest.cc b/ash/display/display_manager_unittest.cc
index 794830c0..c5a42fb 100644
--- a/ash/display/display_manager_unittest.cc
+++ b/ash/display/display_manager_unittest.cc
@@ -36,7 +36,6 @@
 #include "base/format_macros.h"
 #include "base/memory/raw_ptr.h"
 #include "base/numerics/math_constants.h"
-#include "base/ranges/algorithm.h"
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
@@ -86,80 +85,6 @@
   return base::StringPrintf("Display-%d", static_cast<int>(id));
 }
 
-// Asserts that metrics propagated by DisplayManager and DisplayManagerObserver
-// are consistent.
-class DisplayManagerObserverValidator : public display::DisplayObserver,
-                                        public display::DisplayManagerObserver {
- public:
-  DisplayManagerObserverValidator() {
-    display_observer_.emplace(this);
-    display_manager_observation_.Observe(Shell::Get()->display_manager());
-  }
-
-  // display::DisplayObserver:
-  void OnDisplayAdded(const display::Display& new_display) override {
-    if (!base::Contains(added_displays_, new_display)) {
-      added_displays_.push_back(new_display);
-    }
-  }
-  void OnDisplayRemoved(const display::Display& old_display) override {
-    if (!base::Contains(added_displays_, old_display)) {
-      removed_displays_.push_back(old_display);
-    }
-  }
-  void OnDisplayMetricsChanged(const display::Display& display,
-                               uint32_t changed_metrics) override {
-    if (!base::Contains(changed_displays_, display)) {
-      changed_displays_.push_back(display);
-    }
-    if (!changed_metrics_.try_emplace(display.id(), changed_metrics).second) {
-      changed_metrics_[display.id()] |= changed_metrics;
-    }
-  }
-
-  // display::DisplayManager::Observer:
-  void OnWillProcessDisplayChanges() override {
-    // There should not be multiple OnWillProcessDisplayChanges() calls before
-    // the subsequent call to OnDidProcessDisplayChanges().
-    EXPECT_FALSE(processing_display_changes_);
-    processing_display_changes_ = true;
-  }
-  void OnDidProcessDisplayChanges(
-      const DisplayConfigurationChange& configuration_change) override {
-    EXPECT_TRUE(processing_display_changes_);
-
-    EXPECT_TRUE(base::ranges::is_permutation(
-        added_displays_, configuration_change.added_displays));
-    EXPECT_TRUE(base::ranges::is_permutation(
-        removed_displays_, configuration_change.removed_displays));
-
-    EXPECT_EQ(changed_metrics_.size(),
-              configuration_change.display_metrics_changes.size());
-    for (const auto& change : configuration_change.display_metrics_changes) {
-      EXPECT_TRUE(base::Contains(changed_metrics_, change.display->id()));
-      EXPECT_EQ(changed_metrics_[change.display->id()], change.changed_metrics);
-    }
-
-    processing_display_changes_ = false;
-    added_displays_.clear();
-    removed_displays_.clear();
-    changed_displays_.clear();
-    changed_metrics_.clear();
-  }
-
- private:
-  bool processing_display_changes_ = false;
-  vector<display::Display> added_displays_;
-  vector<display::Display> removed_displays_;
-  vector<display::Display> changed_displays_;
-  base::flat_map<int64_t, uint32_t> changed_metrics_;
-
-  absl::optional<display::ScopedDisplayObserver> display_observer_;
-  base::ScopedObservation<display::DisplayManager,
-                          display::DisplayManagerObserver>
-      display_manager_observation_{this};
-};
-
 }  // namespace
 
 class DisplayManagerTest : public AshTestBase,
@@ -179,7 +104,6 @@
     display_observer_.emplace(this);
     display_manager_observation_.Observe(Shell::Get()->display_manager());
     Shell::GetPrimaryRootWindow()->AddObserver(this);
-    display_manager_observer_validator_.emplace();
   }
   void TearDown() override {
     Shell::GetPrimaryRootWindow()->RemoveObserver(this);
@@ -250,10 +174,7 @@
 
   // display::DisplayManager::Observer:
   void OnWillProcessDisplayChanges() override { ++will_process_count_; }
-  void OnDidProcessDisplayChanges(
-      const DisplayConfigurationChange& configuration_change) override {
-    ++did_process_count_;
-  }
+  void OnDidProcessDisplayChanges() override { ++did_process_count_; }
 
   // aura::WindowObserver overrides:
   void OnWindowDestroying(aura::Window* window) override {
@@ -303,9 +224,6 @@
   base::flat_map<int64_t, uint32_t> changed_metrics_;
   bool check_root_window_on_destruction_ = true;
 
-  absl::optional<DisplayManagerObserverValidator>
-      display_manager_observer_validator_;
-
   absl::optional<display::ScopedDisplayObserver> display_observer_;
   base::ScopedObservation<display::DisplayManager,
                           display::DisplayManagerObserver>
diff --git a/ash/display/screen_orientation_controller.cc b/ash/display/screen_orientation_controller.cc
index 17264088..79a410ab 100644
--- a/ash/display/screen_orientation_controller.cc
+++ b/ash/display/screen_orientation_controller.cc
@@ -441,8 +441,7 @@
   suspend_orientation_lock_refreshes_ = true;
 }
 
-void ScreenOrientationController::OnDidProcessDisplayChanges(
-    const DisplayConfigurationChange& configuration_change) {
+void ScreenOrientationController::OnDidProcessDisplayChanges() {
   suspend_orientation_lock_refreshes_ = false;
   if (is_orientation_lock_refresh_pending_) {
     // Note: We must set |is_orientation_lock_refresh_pending_| to false first
diff --git a/ash/display/screen_orientation_controller.h b/ash/display/screen_orientation_controller.h
index 0776000..cd82db5 100644
--- a/ash/display/screen_orientation_controller.h
+++ b/ash/display/screen_orientation_controller.h
@@ -155,8 +155,7 @@
 
   // display::DisplayManagerObserver:
   void OnWillProcessDisplayChanges() override;
-  void OnDidProcessDisplayChanges(
-      const DisplayConfigurationChange& configuration_change) override;
+  void OnDidProcessDisplayChanges() override;
 
  private:
   friend class ScreenOrientationControllerTestApi;
diff --git a/ash/drag_drop/drag_drop_controller_unittest.cc b/ash/drag_drop/drag_drop_controller_unittest.cc
index 3c03dc6..d214088 100644
--- a/ash/drag_drop/drag_drop_controller_unittest.cc
+++ b/ash/drag_drop/drag_drop_controller_unittest.cc
@@ -1773,7 +1773,7 @@
   // Configure `dlp_controller_` to allow sync drop.
   EXPECT_CALL(dlp_contoller_, DropIfAllowed(_, _, _))
       .WillOnce([&](const ui::OSExchangeData* drag_data,
-                    const ui::DataTransferEndpoint* data_dst,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::OnceClosure drop_cb) { std::move(drop_cb).Run(); });
 
   PerformDlpDragAndDrop(CreateDragData(/*with_image=*/false));
@@ -1829,7 +1829,7 @@
   base::OnceClosure drop_callback;
   EXPECT_CALL(dlp_contoller_, DropIfAllowed(_, _, _))
       .WillOnce([&](const ui::OSExchangeData* drag_data,
-                    const ui::DataTransferEndpoint* data_dst,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::OnceClosure drop_cb) {
         drop_callback = std::move(drop_cb);
       });
@@ -1857,7 +1857,7 @@
   base::OnceClosure drop_callback;
   EXPECT_CALL(dlp_contoller_, DropIfAllowed(_, _, _))
       .WillOnce([&](const ui::OSExchangeData* drag_data,
-                    const ui::DataTransferEndpoint* data_dst,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::OnceClosure drop_cb) {
         drop_callback = std::move(drop_cb);
       });
@@ -1894,7 +1894,7 @@
   base::OnceClosure drop_callback;
   EXPECT_CALL(dlp_contoller_, DropIfAllowed(_, _, _))
       .WillOnce([&](const ui::OSExchangeData* drag_data,
-                    const ui::DataTransferEndpoint* data_dst,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::OnceClosure drop_cb) {
         drop_callback = std::move(drop_cb);
       });
diff --git a/ash/public/cpp/desk_template.cc b/ash/public/cpp/desk_template.cc
index efcffcc..546fe9e 100644
--- a/ash/public/cpp/desk_template.cc
+++ b/ash/public/cpp/desk_template.cc
@@ -6,6 +6,7 @@
 
 #include "ash/constants/app_types.h"
 #include "ash/constants/ash_features.h"
+#include "ash/public/cpp/window_properties.h"
 #include "base/i18n/time_formatting.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
@@ -18,6 +19,8 @@
 
 namespace {
 
+constexpr char kOsFeedbackAppId[] = "iffgohomcomlpmkfikfffagkkoojjffm";
+
 std::string TabGroupDataToString(const app_restore::RestoreData* restore_data) {
   std::string result = "tab groups:[";
 
@@ -79,8 +82,14 @@
     case AppType::ARC_APP:
     case AppType::BROWSER:
     case AppType::CHROME_APP:
-    case AppType::SYSTEM_APP:
-      break;
+      return true;
+    case AppType::SYSTEM_APP: {
+      const auto* app_id = window->GetProperty(kAppIDKey);
+      // Feedback app is not saved, see b/301479278.
+      if (app_id && *app_id == kOsFeedbackAppId) {
+        return false;
+      }
+    } break;
   }
 
   return true;
diff --git a/ash/system/audio/unified_volume_view_unittest.cc b/ash/system/audio/unified_volume_view_unittest.cc
index 4d9a708..a1e67c41 100644
--- a/ash/system/audio/unified_volume_view_unittest.cc
+++ b/ash/system/audio/unified_volume_view_unittest.cc
@@ -243,4 +243,26 @@
   EXPECT_EQ(CrasAudioHandler::Get()->IsOutputMuted(), !is_muted);
 }
 
+// Regression test for b/310804814.
+TEST_F(UnifiedVolumeViewTest, MultipleDisplay) {
+  // Add a secondary display to the left of the primary one.
+  UpdateDisplay("1280x1024,1980x1080");
+
+  // Sets the volume level by user.
+  const float level = 0.5;
+  volume_slider_controller()->SliderValueChanged(
+      slider(), level, slider()->GetValue(),
+      views::SliderChangeReason::kByUser);
+
+  EXPECT_EQ(slider()->GetValue(), level);
+  CheckSliderIcon(level);
+
+  PressAndReleaseKey(ui::KeyboardCode::VKEY_VOLUME_UP);
+  // The slider level should increase by `kVolumeStepChange` and the icon should
+  // change accordingly. The mute state toggles back to the original state.
+  const float new_level = level + kVolumeStepChange;
+  EXPECT_FLOAT_EQ(slider()->GetValue(), new_level);
+  CheckSliderIcon(new_level);
+}
+
 }  // namespace ash
diff --git a/ash/system/message_center/ash_notification_view_unittest.cc b/ash/system/message_center/ash_notification_view_unittest.cc
index 130f39c..ba1f96d 100644
--- a/ash/system/message_center/ash_notification_view_unittest.cc
+++ b/ash/system/message_center/ash_notification_view_unittest.cc
@@ -1713,7 +1713,7 @@
   base::OnceClosure drop_callback;
   EXPECT_CALL(dlp_controller_, DropIfAllowed(_, _, _))
       .WillOnce([&](const ui::OSExchangeData* drag_data,
-                    const ui::DataTransferEndpoint* data_dst,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::OnceClosure drop_cb) {
         drop_callback = std::move(drop_cb);
       });
@@ -1750,17 +1750,19 @@
     // Configure `dlp_controller_` to hold all drop callbacks.
     testing::InSequence s;
     EXPECT_CALL(dlp_controller_, DropIfAllowed(_, _, _))
-        .WillOnce([&](const ui::OSExchangeData* drag_data,
-                      const ui::DataTransferEndpoint* data_dst,
-                      base::OnceClosure drop_cb) {
-          first_drop_callback = std::move(drop_cb);
-        });
+        .WillOnce(
+            [&](const ui::OSExchangeData* drag_data,
+                base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+                base::OnceClosure drop_cb) {
+              first_drop_callback = std::move(drop_cb);
+            });
     EXPECT_CALL(dlp_controller_, DropIfAllowed(_, _, _))
-        .WillOnce([&](const ui::OSExchangeData* drag_data,
-                      const ui::DataTransferEndpoint* data_dst,
-                      base::OnceClosure drop_cb) {
-          second_drop_callback = std::move(drop_cb);
-        });
+        .WillOnce(
+            [&](const ui::OSExchangeData* drag_data,
+                base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+                base::OnceClosure drop_cb) {
+              second_drop_callback = std::move(drop_cb);
+            });
   }
 
   // Add one image notification then perform drag-and-drop.
@@ -1807,17 +1809,19 @@
     // Configure `dlp_controller_` to hold all drop callbacks.
     testing::InSequence s;
     EXPECT_CALL(dlp_controller_, DropIfAllowed(_, _, _))
-        .WillOnce([&](const ui::OSExchangeData* drag_data,
-                      const ui::DataTransferEndpoint* data_dst,
-                      base::OnceClosure drop_cb) {
-          first_drop_callback = std::move(drop_cb);
-        });
+        .WillOnce(
+            [&](const ui::OSExchangeData* drag_data,
+                base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+                base::OnceClosure drop_cb) {
+              first_drop_callback = std::move(drop_cb);
+            });
     EXPECT_CALL(dlp_controller_, DropIfAllowed(_, _, _))
-        .WillOnce([&](const ui::OSExchangeData* drag_data,
-                      const ui::DataTransferEndpoint* data_dst,
-                      base::OnceClosure drop_cb) {
-          second_drop_callback = std::move(drop_cb);
-        });
+        .WillOnce(
+            [&](const ui::OSExchangeData* drag_data,
+                base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+                base::OnceClosure drop_cb) {
+              second_drop_callback = std::move(drop_cb);
+            });
   }
 
   // Add one image notification then perform drag-and-drop.
diff --git a/ash/system/unified/notification_counter_view.cc b/ash/system/unified/notification_counter_view.cc
index 4083c1a6..a3ab9cd 100644
--- a/ash/system/unified/notification_counter_view.cc
+++ b/ash/system/unified/notification_counter_view.cc
@@ -4,7 +4,6 @@
 
 #include "ash/system/unified/notification_counter_view.h"
 
-#include "ash/constants/ash_features.h"
 #include "ash/resources/vector_icons/vector_icons.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
@@ -17,7 +16,6 @@
 #include "ash/system/unified/notification_icons_controller.h"
 #include "base/i18n/number_formatting.h"
 #include "base/memory/raw_ptr.h"
-#include "chromeos/constants/chromeos_features.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/base/models/image_model.h"
@@ -63,20 +61,10 @@
 // Returns true if we should show the counter view (e.g. during quiet mode,
 // screen lock, etc.).
 bool ShouldShowCounterView() {
-  SessionControllerImpl* session_controller =
-      Shell::Get()->session_controller();
-
-  if (features::IsQsRevampEnabled()) {
-    // The `NotificationCounterView` should only be hidden if the screen is not
-    // locked and quiet mode is enabled.
-    return !message_center::MessageCenter::Get()->IsQuietMode() ||
-           session_controller->IsScreenLocked();
-  }
-
-  return !message_center::MessageCenter::Get()->IsQuietMode() &&
-         session_controller->ShouldShowNotificationTray() &&
-         (!session_controller->IsScreenLocked() ||
-          AshMessageCenterLockScreenController::IsEnabled());
+  // The `NotificationCounterView` should only be hidden if the screen is not
+  // locked and quiet mode is enabled.
+  return !message_center::MessageCenter::Get()->IsQuietMode() ||
+         Shell::Get()->session_controller()->IsScreenLocked();
 }
 
 class NumberIconImageSource : public gfx::CanvasImageSource {
@@ -96,13 +84,10 @@
 
   void Draw(gfx::Canvas* canvas) override {
     ui::ColorId tray_icon_color_id;
-    if (chromeos::features::IsJellyEnabled()) {
-      tray_icon_color_id = notification_counter_view_->is_active()
-                               ? cros_tokens::kCrosSysSystemOnPrimaryContainer
-                               : cros_tokens::kCrosSysOnSurface;
-    } else {
-      tray_icon_color_id = kColorAshIconColorPrimary;
-    }
+    tray_icon_color_id = notification_counter_view_->is_active()
+                             ? cros_tokens::kCrosSysSystemOnPrimaryContainer
+                             : cros_tokens::kCrosSysOnSurface;
+
     const SkColor tray_icon_color =
         notification_counter_view_->GetColorProvider()->GetColor(
             tray_icon_color_id);
@@ -193,19 +178,10 @@
 
 void NotificationCounterView::OnThemeChanged() {
   TrayItemView::OnThemeChanged();
-  if (!chromeos::features::IsJellyEnabled()) {
-    image_view()->SetImage(
-        gfx::CanvasImageSource::MakeImageSkia<NumberIconImageSource>(
-            this, count_for_display_));
-    return;
-  }
   UpdateLabelOrImageViewColor(is_active());
 }
 
 void NotificationCounterView::UpdateLabelOrImageViewColor(bool active) {
-  if (!chromeos::features::IsJellyEnabled()) {
-    return;
-  }
   TrayItemView::UpdateLabelOrImageViewColor(active);
 
   image_view()->SetImage(
@@ -230,11 +206,6 @@
       Shell::Get()->session_controller()->GetSessionState() ==
           session_manager::SessionState::ACTIVE) {
     SetVisible(true);
-    if (!chromeos::features::IsJellyEnabled()) {
-      image_view()->SetImage(ui::ImageModel::FromVectorIcon(
-          kSystemTrayDoNotDisturbIcon, kColorAshIconColorPrimary));
-      return;
-    }
     UpdateLabelOrImageViewColor(is_active());
   } else {
     SetVisible(false);
@@ -252,9 +223,6 @@
 }
 
 void QuietModeView::UpdateLabelOrImageViewColor(bool active) {
-  if (!chromeos::features::IsJellyEnabled()) {
-    return;
-  }
   TrayItemView::UpdateLabelOrImageViewColor(active);
 
   image_view()->SetImage(ui::ImageModel::FromVectorIcon(
diff --git a/ash/system/unified/notification_counter_view_unittest.cc b/ash/system/unified/notification_counter_view_unittest.cc
index 92793c38..8276174 100644
--- a/ash/system/unified/notification_counter_view_unittest.cc
+++ b/ash/system/unified/notification_counter_view_unittest.cc
@@ -4,13 +4,11 @@
 
 #include "ash/system/unified/notification_counter_view.h"
 
-#include "ash/constants/ash_features.h"
 #include "ash/shelf/shelf.h"
 #include "ash/system/notification_center/notification_center_tray.h"
 #include "ash/system/unified/notification_icons_controller.h"
 #include "ash/test/ash_test_base.h"
 #include "base/strings/string_number_conversions.h"
-#include "base/test/scoped_feature_list.h"
 #include "ui/message_center/message_center.h"
 #include "ui/message_center/public/cpp/notification.h"
 #include "ui/message_center/public/cpp/notification_types.h"
@@ -37,8 +35,7 @@
 
 }  // namespace
 
-class NotificationCounterViewTest : public AshTestBase,
-                                    public testing::WithParamInterface<bool> {
+class NotificationCounterViewTest : public AshTestBase {
  public:
   NotificationCounterViewTest()
       : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
@@ -47,17 +44,6 @@
       delete;
   ~NotificationCounterViewTest() override = default;
 
-  void SetUp() override {
-    scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
-    scoped_feature_list_->InitWithFeatureState(features::kQsRevamp,
-                                               /*enabled=*/IsQsRevampEnabled());
-
-    AshTestBase::SetUp();
-  }
-
-  // TODO(b/305075031) clean up after the flag is removed.
-  bool IsQsRevampEnabled() { return true; }
-
  protected:
   NotificationCounterView* GetNotificationCounterView() {
     auto* status_area_widget = GetPrimaryShelf()->status_area_widget();
@@ -70,16 +56,9 @@
     return status_area_widget->notification_center_tray()
         ->notification_icons_controller_->quiet_mode_view();
   }
-
- private:
-  std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
 };
 
-INSTANTIATE_TEST_SUITE_P(All,
-                         NotificationCounterViewTest,
-                         testing::Bool() /* IsQsRevampEnabled() */);
-
-TEST_P(NotificationCounterViewTest, CountForDisplay) {
+TEST_F(NotificationCounterViewTest, CountForDisplay) {
   // Not visible when count == 0.
   GetNotificationCounterView()->Update();
   EXPECT_EQ(0, GetNotificationCounterView()->count_for_display_for_testing());
@@ -102,7 +81,7 @@
   EXPECT_TRUE(GetNotificationCounterView()->GetVisible());
 }
 
-TEST_P(NotificationCounterViewTest, HiddenNotificationCount) {
+TEST_F(NotificationCounterViewTest, HiddenNotificationCount) {
   // Not visible when count == 0.
   GetNotificationCounterView()->Update();
   EXPECT_EQ(0, GetNotificationCounterView()->count_for_display_for_testing());
@@ -133,7 +112,7 @@
   EXPECT_EQ(1, GetNotificationCounterView()->count_for_display_for_testing());
 }
 
-TEST_P(NotificationCounterViewTest, DisplayChanged) {
+TEST_F(NotificationCounterViewTest, DisplayChanged) {
   AddNotification("1", true /* is_pinned */);
   GetNotificationCounterView()->Update();
 
@@ -165,7 +144,7 @@
   EXPECT_FALSE(GetNotificationCounterView()->GetVisible());
 }
 
-TEST_P(NotificationCounterViewTest, DoNotDisturbIconVisibility) {
+TEST_F(NotificationCounterViewTest, DoNotDisturbIconVisibility) {
   ASSERT_FALSE(GetDoNotDisturbIconView()->GetVisible());
 
   // Turn on Do not disturb mode.
@@ -181,12 +160,7 @@
   EXPECT_TRUE(GetDoNotDisturbIconView()->GetVisible());
 }
 
-TEST_P(NotificationCounterViewTest, LockScreenCounter) {
-  // This behavior is only applicable when QsRevamp is enabled.
-  if (!IsQsRevampEnabled()) {
-    return;
-  }
-
+TEST_F(NotificationCounterViewTest, LockScreenCounter) {
   for (size_t i = 0; i < kTrayNotificationMaxCount; i++) {
     AddNotification(base::NumberToString(i));
   }
@@ -198,12 +172,7 @@
             GetNotificationCounterView()->count_for_display_for_testing());
 }
 
-TEST_P(NotificationCounterViewTest, LockScreenCounterInDoNotDisturbMode) {
-  // This behavior is only applicable when QsRevamp is enabled.
-  if (!IsQsRevampEnabled()) {
-    return;
-  }
-
+TEST_F(NotificationCounterViewTest, LockScreenCounterInDoNotDisturbMode) {
   for (size_t i = 0; i < kTrayNotificationMaxCount; i++) {
     AddNotification(base::NumberToString(i));
   }
diff --git a/ash/system/unified/quick_settings_metrics_util.cc b/ash/system/unified/quick_settings_metrics_util.cc
index a892fa1..c13b93a 100644
--- a/ash/system/unified/quick_settings_metrics_util.cc
+++ b/ash/system/unified/quick_settings_metrics_util.cc
@@ -4,16 +4,12 @@
 
 #include "ash/system/unified/quick_settings_metrics_util.h"
 
-#include "ash/constants/ash_features.h"
 #include "ash/constants/quick_settings_catalogs.h"
 #include "base/metrics/histogram_functions.h"
-#include "ui/events/event.h"
 
 namespace ash {
 
 namespace {
-
-// For the revamped view:
 constexpr char kQuickSettingsButton[] = "Ash.QuickSettings.Button.Activated";
 constexpr char kQuickSettingsFeaturePodEnabled[] =
     "Ash.QuickSettings.FeaturePod.ToggledOn";
@@ -35,118 +31,69 @@
     "Ash.QuickSettings.Slider.EnableFeature";
 constexpr char kQuickSettingsSliderDisable[] =
     "Ash.QuickSettings.Slider.DisableFeature";
-
-// For the old view:
-constexpr char kUnifiedViewButton[] = "Ash.UnifiedSystemView.Button.Activated";
-constexpr char kUnifiedViewFeaturePodEnabled[] =
-    "Ash.UnifiedSystemView.FeaturePod.ToggledOn";
-constexpr char kUnifiedViewFeaturePodDisabled[] =
-    "Ash.UnifiedSystemView.FeaturePod.ToggledOff";
-constexpr char kUnifiedViewFeaturePodDiveIn[] =
-    "Ash.UnifiedSystemView.FeaturePod.DiveIn";
-constexpr char kUnifiedViewFeaturePodVisible[] =
-    "Ash.UnifiedSystemView.FeaturePod.Visible";
-constexpr char kUnifiedViewFeaturePodCount[] =
-    "Ash.UnifiedSystemView.Clamshell.FeaturePodCountOnOpen";
-constexpr char kUnifiedViewTabletFeaturePodCount[] =
-    "Ash.UnifiedSystemView.Tablet.FeaturePodCountOnOpen";
-constexpr char kUnifiedSystemViewSliderUp[] = "Ash.UnifiedSystemView.Slider.Up";
-constexpr char kUnifiedSystemViewSliderDown[] =
-    "Ash.UnifiedSystemView.Slider.Down";
-constexpr char kUnifiedSystemViewSliderEnable[] =
-    "Ash.UnifiedSystemView.Slider.EnableFeature";
-constexpr char kUnifiedSystemViewSliderDisable[] =
-    "Ash.UnifiedSystemView.Slider.DisableFeature";
-
 }  // namespace
 
 namespace quick_settings_metrics_util {
 
 void RecordQsButtonActivated(QsButtonCatalogName button_catalog_name) {
-  base::UmaHistogramEnumeration(
-      features::IsQsRevampEnabled() ? kQuickSettingsButton : kUnifiedViewButton,
-      button_catalog_name);
+  base::UmaHistogramEnumeration(kQuickSettingsButton, button_catalog_name);
 }
 
 void RecordQsFeatureToggle(QsFeatureCatalogName feature_catalog_name,
                            bool enable) {
   if (enable) {
-    base::UmaHistogramEnumeration(features::IsQsRevampEnabled()
-                                      ? kQuickSettingsFeaturePodEnabled
-                                      : kUnifiedViewFeaturePodEnabled,
+    base::UmaHistogramEnumeration(kQuickSettingsFeaturePodEnabled,
                                   feature_catalog_name);
     return;
   }
 
-  base::UmaHistogramEnumeration(features::IsQsRevampEnabled()
-                                    ? kQuickSettingsFeaturePodDisabled
-                                    : kUnifiedViewFeaturePodDisabled,
+  base::UmaHistogramEnumeration(kQuickSettingsFeaturePodDisabled,
                                 feature_catalog_name);
 }
 
 void RecordQsFeatureDiveIn(QsFeatureCatalogName feature_catalog_name) {
-  base::UmaHistogramEnumeration(features::IsQsRevampEnabled()
-                                    ? kQuickSettingsFeaturePodDiveIn
-                                    : kUnifiedViewFeaturePodDiveIn,
+  base::UmaHistogramEnumeration(kQuickSettingsFeaturePodDiveIn,
                                 feature_catalog_name);
 }
 
 void RecordVisibleQsFeature(QsFeatureCatalogName feature_catalog_name) {
-  base::UmaHistogramEnumeration(features::IsQsRevampEnabled()
-                                    ? kQuickSettingsFeaturePodVisible
-                                    : kUnifiedViewFeaturePodVisible,
+  base::UmaHistogramEnumeration(kQuickSettingsFeaturePodVisible,
                                 feature_catalog_name);
 }
 
 void RecordQsFeaturePodCount(int feature_pod_count, bool is_tablet) {
   if (is_tablet) {
-    base::UmaHistogramCounts100(features::IsQsRevampEnabled()
-                                    ? kQuickSettingsTabletFeaturePodCount
-                                    : kUnifiedViewTabletFeaturePodCount,
+    base::UmaHistogramCounts100(kQuickSettingsTabletFeaturePodCount,
                                 feature_pod_count);
     return;
   }
 
-  base::UmaHistogramCounts100(features::IsQsRevampEnabled()
-                                  ? kQuickSettingsFeaturePodCount
-                                  : kUnifiedViewFeaturePodCount,
-                              feature_pod_count);
+  base::UmaHistogramCounts100(kQuickSettingsFeaturePodCount, feature_pod_count);
 }
 
 void RecordQsSliderValueChange(QsSliderCatalogName slider_catalog_name,
                                bool going_up) {
   if (going_up) {
-    base::UmaHistogramEnumeration(features::IsQsRevampEnabled()
-                                      ? kQuickSettingsSliderUp
-                                      : kUnifiedSystemViewSliderUp,
-                                  slider_catalog_name);
+    base::UmaHistogramEnumeration(kQuickSettingsSliderUp, slider_catalog_name);
     return;
   }
 
-  base::UmaHistogramEnumeration(features::IsQsRevampEnabled()
-                                    ? kQuickSettingsSliderDown
-                                    : kUnifiedSystemViewSliderDown,
-                                slider_catalog_name);
+  base::UmaHistogramEnumeration(kQuickSettingsSliderDown, slider_catalog_name);
 }
 
 void RecordQsSliderToggle(QsSliderCatalogName slider_catalog_name,
                           bool enable) {
   if (enable) {
-    base::UmaHistogramEnumeration(features::IsQsRevampEnabled()
-                                      ? kQuickSettingsSliderEnable
-                                      : kUnifiedSystemViewSliderEnable,
+    base::UmaHistogramEnumeration(kQuickSettingsSliderEnable,
                                   slider_catalog_name);
     return;
   }
 
-  base::UmaHistogramEnumeration(features::IsQsRevampEnabled()
-                                    ? kQuickSettingsSliderDisable
-                                    : kUnifiedSystemViewSliderDisable,
+  base::UmaHistogramEnumeration(kQuickSettingsSliderDisable,
                                 slider_catalog_name);
 }
 
 void RecordQsPageCountOnClose(int page_count) {
-  CHECK(features::IsQsRevampEnabled());
   base::UmaHistogramCounts100(kQuickSettingsPageCountOnClose, page_count);
 }
 
diff --git a/ash/system/unified/quick_settings_metrics_util.h b/ash/system/unified/quick_settings_metrics_util.h
index d23b635..4fb84f9 100644
--- a/ash/system/unified/quick_settings_metrics_util.h
+++ b/ash/system/unified/quick_settings_metrics_util.h
@@ -47,7 +47,6 @@
 // because the number of feature tiles, and thus the number of settings pages,
 // may not be accurately represented upon opening (e.g. a feature tile's
 // visibility may only be known after some data is fetched asynchronously).
-// Should only be called when QsRevamp is enabled.
 void RecordQsPageCountOnClose(int page_count);
 
 }  // namespace ash::quick_settings_metrics_util
diff --git a/ash/system/unified/unified_slider_bubble_controller.cc b/ash/system/unified/unified_slider_bubble_controller.cc
index d2d6787..4da71d0 100644
--- a/ash/system/unified/unified_slider_bubble_controller.cc
+++ b/ash/system/unified/unified_slider_bubble_controller.cc
@@ -255,8 +255,10 @@
 
   if (IsAnyMainBubbleShown()) {
     // If a detailed view is showing, first transit to the main view.
-    tray_->bubble()->unified_system_tray_controller()->TransitionToMainView(
-        false);
+    if (tray_->bubble() && tray_->bubble()->GetBubbleWidget()) {
+      tray_->bubble()->unified_system_tray_controller()->TransitionToMainView(
+          false);
+    }
 
     // Unlike VOLUME and BRIGHTNESS, which are shown in the main bubble view,
     // MIC slider is shown in the audio details view.
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc
index 7b59169..08780d41 100644
--- a/ash/system/unified/unified_system_tray_controller.cc
+++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -321,6 +321,10 @@
 }
 
 void UnifiedSystemTrayController::TransitionToMainView(bool restore_focus) {
+  if (!detailed_view_controller_) {
+    return;
+  }
+
   if (showing_calendar_view_) {
     showing_calendar_view_ = false;
     for (auto& observer : observers_) {
diff --git a/ash/webui/personalization_app/resources/common/icons.html b/ash/webui/personalization_app/resources/common/icons.html
index 009f506..f8a02117 100644
--- a/ash/webui/personalization_app/resources/common/icons.html
+++ b/ash/webui/personalization_app/resources/common/icons.html
@@ -167,3 +167,13 @@
     </defs>
   </svg>
 </iron-iconset-svg>
+
+<iron-iconset-svg name="sea-pen">
+  <svg>
+    <defs>
+      <g id="photo-spark" width="24" height="24" viewBox="0 -960 960 960">
+        <path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h320v80H200v560h560v-320h80v320q0 33-23.5 56.5T760-120H200Zm40-160 120-160 90 120 120-160 150 200H240Zm460-200q0-92-64-156t-156-64q92 0 156-64t64-156q0 92 64 156t156 64q-92 0-156 64t-64 156Z"></path>
+      </g>
+    </defs>
+  </svg>
+</iron-iconset-svg>
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_input_query_element.html b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_input_query_element.html
index 7eca8d8f..12a2565 100644
--- a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_input_query_element.html
+++ b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_input_query_element.html
@@ -1,8 +1,41 @@
-<cr-input maxlength="[[maxTextLength_]]"
-    placeholder="describe"
-    type="text"
-    value="{{textValue_}}">
-</cr-input>
-<cr-button id="searchButton" disabled$="[[thumbnailsLoading_]]" on-click="onClickInputQuerySearchButton_">
-  <div class="text">Search</div>
-</cr-button>
\ No newline at end of file
+<style include="wallpaper common cros-button-style">
+  #container {
+    align-items: center;
+    display: flex;
+    flex-direction: column;
+    height: 100%;
+  }
+
+  #queryInput {
+    margin-block-start: 20px;
+    text-align: center;
+    --cr-input-error-display: none;
+  }
+
+  #buttonContainer {
+    margin-block-start: 12px;
+  }
+
+  #searchButton .text {
+    margin-inline-start: 8px;
+  }
+</style>
+
+<div id="container">
+  <cr-input id="queryInput"
+      maxlength="[[maxTextLength_]]"
+      placeholder="Describe your wallpaper"
+      type="text"
+      value="{{textValue_}}">
+  </cr-input>
+  <div id="buttonContainer">
+    <cr-button
+        id="searchButton"
+        class="action-button"
+        disabled$="[[thumbnailsLoading_]]"
+        on-click="onClickInputQuerySearchButton_">
+      <iron-icon icon="sea-pen:photo-spark"></iron-icon>
+      <div class="text">Search Wallpaper</div>
+    </cr-button>
+  </div>
+</div>
diff --git a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_input_query_element.ts b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_input_query_element.ts
index a01663b..955b224c 100644
--- a/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_input_query_element.ts
+++ b/ash/webui/personalization_app/resources/js/wallpaper/sea_pen/sea_pen_input_query_element.ts
@@ -8,7 +8,12 @@
  */
 
 import 'chrome://resources/cr_elements/cr_button/cr_button.js';
+import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
+import 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js';
 import 'chrome://resources/cr_elements/cr_input/cr_input.js';
+import '../../../common/icons.html.js';
+import '../../../css/wallpaper.css.js';
+import '../../../css/cros_button_style.css.js';
 
 import {assert} from 'chrome://resources/js/assert.js';
 
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_edit_dialog.html b/ash/webui/shortcut_customization_ui/resources/js/accelerator_edit_dialog.html
index 31f60c1d..dcc9339d 100644
--- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_edit_dialog.html
+++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_edit_dialog.html
@@ -28,6 +28,10 @@
     padding-top: 16px;
   }
 
+  #emptyStateContainer {
+    padding-block-start: 8px;
+  }
+
   #pendingAccelerator {
     padding-top: 8px;
   }
@@ -73,11 +77,16 @@
     padding-block-end: 8px;
   }
 
-  #shortcutDescription {
+  #shortcutDescription, #noShortcutAssigned {
     font: var(--cros-body-2-font);
     color: var(--cros-text-color-secondary);
   }
 
+  #noShortcutAssigned {
+    padding-block: 16px;
+    padding-inline-start: 8px;
+  }
+
   [slot='button-container'] {
     display: flex;
     justify-content: space-between;
@@ -119,6 +128,15 @@
             on-edit-action-completed="onEditActionCompleted">
         </accelerator-edit-view>
       </template>
+      <template id="emptyState" is="dom-if"
+          if="[[isEmptyState(pendingNewAcceleratorState, acceleratorInfos)]]"
+          restamp>
+        <div id="emptyStateContainer">
+          <div id="noShortcutAssigned">
+            [[i18n('noShortcutAssigned')]]
+          </div>
+        </div>
+      </template>
     </div>
     <div id="addAcceleratorContainer"
         hidden="[[!showAddButton(pendingNewAcceleratorState, acceleratorInfos,
diff --git a/ash/webui/shortcut_customization_ui/resources/js/accelerator_edit_dialog.ts b/ash/webui/shortcut_customization_ui/resources/js/accelerator_edit_dialog.ts
index 2815d35..5215ac6 100644
--- a/ash/webui/shortcut_customization_ui/resources/js/accelerator_edit_dialog.ts
+++ b/ash/webui/shortcut_customization_ui/resources/js/accelerator_edit_dialog.ts
@@ -257,6 +257,11 @@
         this.defaultAcceleratorsWithConflict.size === 0;
   }
 
+  protected isEmptyState(): boolean {
+    return this.pendingNewAcceleratorState === ViewState.VIEW &&
+        this.getSortedFilteredAccelerators(this.acceleratorInfos).length === 0;
+  }
+
   protected acceleratorLimitNotReached(): boolean {
     let originalAcceleratorsCount = 0;
     for (const acceleratorInfo of this.acceleratorInfos) {
diff --git a/ash/wm/gestures/wm_gesture_handler.cc b/ash/wm/gestures/wm_gesture_handler.cc
index 5ae0071b..44ad12e 100644
--- a/ash/wm/gestures/wm_gesture_handler.cc
+++ b/ash/wm/gestures/wm_gesture_handler.cc
@@ -167,13 +167,15 @@
     return false;
   }
 
-  // Ignore scrolls beyond the upward threshold. Note that we already clamped
-  // `scroll_y` to `kVerticalThresholdDp`. If the threshold has been met but the
-  // scroll is in progress, we will need to do the final placement before we
-  // mark the scroll as finished.
+  // Consume overscroll after continuous scroll has
+  // completed progress. This prevents the scroll from propagating to another
+  // view and triggering additional behavior.
+  // Note that we already clamped `scroll_y` to `kVerticalThresholdDp`. If the
+  // threshold has been met but the scroll is in progress, we will need to do
+  // the final placement before we mark the scroll as finished.
   if (scroll_y == WmGestureHandler::kVerticalThresholdDp &&
       !overview_controller->is_continuous_scroll_in_progress()) {
-    return false;
+    return true;
   }
 
   // Prevent accidental swipes from triggering the continuous animation.
diff --git a/ash/wm/multi_display/persistent_window_controller.cc b/ash/wm/multi_display/persistent_window_controller.cc
index bfd982a..d84f9a7 100644
--- a/ash/wm/multi_display/persistent_window_controller.cc
+++ b/ash/wm/multi_display/persistent_window_controller.cc
@@ -199,8 +199,7 @@
   }
 }
 
-void PersistentWindowController::OnDidProcessDisplayChanges(
-    const DisplayConfigurationChange& configuration_change) {
+void PersistentWindowController::OnDidProcessDisplayChanges() {
   if (display_added_restore_callback_) {
     std::move(display_added_restore_callback_).Run();
   }
diff --git a/ash/wm/multi_display/persistent_window_controller.h b/ash/wm/multi_display/persistent_window_controller.h
index ffff9bf..fe5b684 100644
--- a/ash/wm/multi_display/persistent_window_controller.h
+++ b/ash/wm/multi_display/persistent_window_controller.h
@@ -86,8 +86,7 @@
 
   // display::DisplayManagerObserver:
   void OnWillProcessDisplayChanges() override;
-  void OnDidProcessDisplayChanges(
-      const DisplayConfigurationChange& configuration_change) override;
+  void OnDidProcessDisplayChanges() override;
 
   // SessionObserver:
   void OnFirstSessionStarted() override;
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc
index 69adfc3..4084487 100644
--- a/ash/wm/overview/overview_session_unittest.cc
+++ b/ash/wm/overview/overview_session_unittest.cc
@@ -15,6 +15,7 @@
 #include "ash/accessibility/magnifier/docked_magnifier_controller.h"
 #include "ash/accessibility/test_accessibility_controller_client.h"
 #include "ash/app_list/app_list_controller_impl.h"
+#include "ash/app_list/test/app_list_test_helper.h"
 #include "ash/constants/app_types.h"
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
@@ -23,11 +24,13 @@
 #include "ash/frame_throttler/frame_throttling_controller.h"
 #include "ash/frame_throttler/mock_frame_throttling_observer.h"
 #include "ash/public/cpp/shelf_config.h"
+#include "ash/public/cpp/shelf_prefs.h"
 #include "ash/public/cpp/test/shell_test_api.h"
 #include "ash/public/cpp/window_properties.h"
 #include "ash/root_window_controller.h"
 #include "ash/screen_util.h"
 #include "ash/shelf/shelf.h"
+#include "ash/shelf/shelf_view.h"
 #include "ash/shelf/shelf_view_test_api.h"
 #include "ash/shell.h"
 #include "ash/style/close_button.h"
@@ -87,7 +90,6 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/to_vector.h"
 #include "base/time/time.h"
-#include "chromeos/constants/chromeos_features.h"
 #include "chromeos/ui/base/window_state_type.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/test/test_window_delegate.h"
@@ -5842,7 +5844,7 @@
   void SetUp() override {
     scoped_feature_list_.InitWithFeatures(
         /*enabled_features=*/{features::kContinuousOverviewScrollAnimation,
-                              chromeos::features::kJelly},
+                              features::kDeskButton},
         /*disabled_features=*/{});
     OverviewTestBase::SetUp();
 
@@ -5856,9 +5858,12 @@
 
   // If `complete_scroll` is false, end the scroll with the fingers still on the
   // trackpad.
-  void ThreeFingerScroll(float x_offset, float y_offset, bool complete_scroll) {
+  void ThreeFingerScroll(float x_offset,
+                         float y_offset,
+                         bool complete_scroll,
+                         const gfx::Point& start = gfx::Point()) {
     GetEventGenerator()->ScrollSequence(
-        gfx::Point(), base::Milliseconds(5), x_offset, y_offset,
+        start, base::Milliseconds(5), x_offset, y_offset,
         /*steps=*/100, /*fingers=*/3,
         /*end_state=*/
         complete_scroll
@@ -5866,10 +5871,52 @@
             : ui::test::EventGenerator::ScrollSequenceType::ScrollOnly);
   }
 
+  void SetShowDeskButton(bool visible) {
+    SetShowDeskButtonInShelfPref(
+        Shell::Get()->session_controller()->GetActivePrefService(), visible);
+  }
+
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
+// Verifies that 3 finger scroll while hovering the desk button does not open
+// the app list.
+TEST_P(ContinuousOverviewAnimationTest, ScrollOnDeskButtonDoesNotOpenAppList) {
+  ShelfViewTestAPI test_api(GetPrimaryShelf()->GetShelfViewForTesting());
+
+  SetShowDeskButton(true);
+  // The button should be visible.
+  EXPECT_TRUE(test_api.shelf_view()
+                  ->shelf_widget()
+                  ->desk_button_widget()
+                  ->GetLayer()
+                  ->GetTargetVisibility());
+
+  std::unique_ptr<aura::Window> window1(CreateTestWindow());
+  std::unique_ptr<aura::Window> window2(CreateTestWindow());
+
+  // Perform a very long swipe up gesture from the center of the desk button.
+  const float long_scroll = WmGestureHandler::kVerticalThresholdDp + 200.f;
+  ThreeFingerScroll(0, long_scroll, /*complete_scroll=*/true,
+                    test_api.shelf_view()
+                        ->shelf_widget()
+                        ->desk_button_widget()
+                        ->GetLayer()
+                        ->bounds()
+                        .CenterPoint());
+  // We should be in overview mode.
+  ASSERT_TRUE(InOverviewSession());
+  // Desk button widget should be invisible in overview mode.
+  EXPECT_FALSE(test_api.shelf_view()
+                   ->shelf_widget()
+                   ->desk_button_widget()
+                   ->GetLayer()
+                   ->GetTargetVisibility());
+  // 3 finger scroll from the desk button widget should not show the app list.
+  GetAppListTestHelper()->CheckVisibility(false);
+}
+
 // Tests that continuous scrolls slowly shrink active windows and increase the
 // opacity of minimized windows, regardless of the state of `NaturalScroll`.
 TEST_P(ContinuousOverviewAnimationTest, WindowSizesAndOpacities) {
diff --git a/base/BUILD.gn b/base/BUILD.gn
index f25db5b..5411ac75 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -273,8 +273,6 @@
     "containers/cxx20_erase_map.h",
     "containers/cxx20_erase_set.h",
     "containers/cxx20_erase_string.h",
-    "containers/cxx20_erase_unordered_map.h",
-    "containers/cxx20_erase_unordered_set.h",
     "containers/cxx20_erase_vector.h",
     "containers/enum_set.h",
     "containers/extend.h",
diff --git a/base/android/build_info.cc b/base/android/build_info.cc
index d886ec8f..1ed5a340 100644
--- a/base/android/build_info.cc
+++ b/base/android/build_info.cc
@@ -85,7 +85,8 @@
       is_at_least_u_(GetIntParam(params, 27)),
       targets_at_least_u_(GetIntParam(params, 28)),
       codename_(StrDupParam(params, 29)),
-      vulkan_deqp_level_(GetIntParam(params, 30)) {}
+      vulkan_deqp_level_(GetIntParam(params, 30)),
+      is_foldable_(GetIntParam(params, 31)) {}
 
 // static
 BuildInfo* BuildInfo::GetInstance() {
diff --git a/base/android/build_info.h b/base/android/build_info.h
index add851e0..353006e5 100644
--- a/base/android/build_info.h
+++ b/base/android/build_info.h
@@ -160,6 +160,8 @@
 
   const char* codename() const { return codename_; }
 
+  bool is_foldable() const { return is_foldable_; }
+
   // Available only on Android T+.
   int32_t vulkan_deqp_level() const { return vulkan_deqp_level_; }
 
@@ -204,6 +206,7 @@
   const bool targets_at_least_u_;
   const char* const codename_;
   const int32_t vulkan_deqp_level_;
+  const bool is_foldable_;
 };
 
 }  // namespace base::android
diff --git a/base/android/java/src/org/chromium/base/BuildInfo.java b/base/android/java/src/org/chromium/base/BuildInfo.java
index f4247a0..bf35102 100644
--- a/base/android/java/src/org/chromium/base/BuildInfo.java
+++ b/base/android/java/src/org/chromium/base/BuildInfo.java
@@ -133,6 +133,7 @@
             targetsAtLeastU() ? "1" : "0",
             Build.VERSION.CODENAME,
             String.valueOf(vulkanDeqpLevel),
+            isFoldable ? "1" : "0",
         };
     }
 
diff --git a/base/base64.cc b/base/base64.cc
index 4b2fd19..e7afd318 100644
--- a/base/base64.cc
+++ b/base/base64.cc
@@ -47,11 +47,11 @@
 }
 
 void Base64Encode(StringPiece input, std::string* output) {
-  *output = Base64Encode(base::as_bytes(base::make_span(input)));
+  *output = Base64Encode(base::as_byte_span(input));
 }
 
 std::string Base64Encode(StringPiece input) {
-  return Base64Encode(base::as_bytes(base::make_span(input)));;
+  return Base64Encode(base::as_byte_span(input));
 }
 
 bool Base64Decode(StringPiece input,
diff --git a/base/base64url.cc b/base/base64url.cc
index ea09796..9f9f4e16 100644
--- a/base/base64url.cc
+++ b/base/base64url.cc
@@ -123,7 +123,7 @@
 void Base64UrlEncode(StringPiece input,
                      Base64UrlEncodePolicy policy,
                      std::string* output) {
-  Base64UrlEncode(base::as_bytes(base::make_span(input)), policy, output);
+  Base64UrlEncode(base::as_byte_span(input), policy, output);
 }
 
 bool Base64UrlDecode(StringPiece input,
diff --git a/base/big_endian.cc b/base/big_endian.cc
index bb4dee0..fe5ff2c 100644
--- a/base/big_endian.cc
+++ b/base/big_endian.cc
@@ -13,7 +13,7 @@
 
 BigEndianReader BigEndianReader::FromStringPiece(
     base::StringPiece string_piece) {
-  return BigEndianReader(base::as_bytes(base::make_span(string_piece)));
+  return BigEndianReader(base::as_byte_span(string_piece));
 }
 
 BigEndianReader::BigEndianReader(const uint8_t* buf, size_t len)
diff --git a/base/containers/cxx20_erase.h b/base/containers/cxx20_erase.h
index c92446b..449bcc75 100644
--- a/base/containers/cxx20_erase.h
+++ b/base/containers/cxx20_erase.h
@@ -11,8 +11,6 @@
 #include "base/containers/cxx20_erase_map.h"
 #include "base/containers/cxx20_erase_set.h"
 #include "base/containers/cxx20_erase_string.h"
-#include "base/containers/cxx20_erase_unordered_map.h"
-#include "base/containers/cxx20_erase_unordered_set.h"
 #include "base/containers/cxx20_erase_vector.h"
 
 // Erase/EraseIf are based on C++20's uniform container erasure API:
diff --git a/base/containers/cxx20_erase_unordered_map.h b/base/containers/cxx20_erase_unordered_map.h
deleted file mode 100644
index 853af97..0000000
--- a/base/containers/cxx20_erase_unordered_map.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2021 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_CONTAINERS_CXX20_ERASE_UNORDERED_MAP_H_
-#define BASE_CONTAINERS_CXX20_ERASE_UNORDERED_MAP_H_
-
-#include <unordered_map>
-
-#include "base/containers/cxx20_erase_internal.h"
-
-namespace base {
-
-// EraseIf is based on C++20's uniform container erasure API:
-// - https://eel.is/c++draft/libraryindex#:erase
-// - https://eel.is/c++draft/libraryindex#:erase_if
-// They provide a generic way to erase elements from a container.
-// The functions here implement these for the standard containers until those
-// functions are available in the C++ standard.
-// Note: there is no std::erase for standard associative containers so we don't
-// have it either.
-
-template <class Key,
-          class T,
-          class Hash,
-          class KeyEqual,
-          class Allocator,
-          class Predicate>
-size_t EraseIf(std::unordered_map<Key, T, Hash, KeyEqual, Allocator>& container,
-               Predicate pred) {
-  return internal::IterateAndEraseIf(container, pred);
-}
-
-template <class Key,
-          class T,
-          class Hash,
-          class KeyEqual,
-          class Allocator,
-          class Predicate>
-size_t EraseIf(
-    std::unordered_multimap<Key, T, Hash, KeyEqual, Allocator>& container,
-    Predicate pred) {
-  return internal::IterateAndEraseIf(container, pred);
-}
-
-}  // namespace base
-
-#endif  // BASE_CONTAINERS_CXX20_ERASE_UNORDERED_MAP_H_
diff --git a/base/containers/cxx20_erase_unordered_set.h b/base/containers/cxx20_erase_unordered_set.h
deleted file mode 100644
index a72be5c..0000000
--- a/base/containers/cxx20_erase_unordered_set.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2021 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_CONTAINERS_CXX20_ERASE_UNORDERED_SET_H_
-#define BASE_CONTAINERS_CXX20_ERASE_UNORDERED_SET_H_
-
-#include <unordered_set>
-
-#include "base/containers/cxx20_erase_internal.h"
-
-namespace base {
-
-// EraseIf is based on C++20's uniform container erasure API:
-// - https://eel.is/c++draft/libraryindex#:erase
-// - https://eel.is/c++draft/libraryindex#:erase_if
-// They provide a generic way to erase elements from a container.
-// The functions here implement these for the standard containers until those
-// functions are available in the C++ standard.
-// Note: there is no std::erase for standard associative containers so we don't
-// have it either.
-
-template <class Key,
-          class Hash,
-          class KeyEqual,
-          class Allocator,
-          class Predicate>
-size_t EraseIf(std::unordered_set<Key, Hash, KeyEqual, Allocator>& container,
-               Predicate pred) {
-  return internal::IterateAndEraseIf(container, pred);
-}
-
-template <class Key,
-          class Hash,
-          class KeyEqual,
-          class Allocator,
-          class Predicate>
-size_t EraseIf(
-    std::unordered_multiset<Key, Hash, KeyEqual, Allocator>& container,
-    Predicate pred) {
-  return internal::IterateAndEraseIf(container, pred);
-}
-
-}  // namespace base
-
-#endif  // BASE_CONTAINERS_CXX20_ERASE_UNORDERED_SET_H_
diff --git a/base/containers/erase_unittest.cc b/base/containers/erase_unittest.cc
index c95572c0..195cf1ea 100644
--- a/base/containers/erase_unittest.cc
+++ b/base/containers/erase_unittest.cc
@@ -156,23 +156,5 @@
   RunEraseIfTest<std::multiset<std::pair<int, int>, std::greater<>>>();
 }
 
-TEST(Erase, UnorderedMap) {
-  RunEraseIfTest<std::unordered_map<int, int>>();
-  RunEraseIfTest<std::unordered_map<int, int, CustomIntHash>>();
-}
-
-TEST(Erase, UnorderedMultimap) {
-  RunEraseIfTest<std::unordered_multimap<int, int>>();
-  RunEraseIfTest<std::unordered_multimap<int, int, CustomIntHash>>();
-}
-
-TEST(Erase, UnorderedSet) {
-  RunEraseIfTest<std::unordered_set<std::pair<int, int>, HashByFirst>>();
-}
-
-TEST(Erase, UnorderedMultiset) {
-  RunEraseIfTest<std::unordered_multiset<std::pair<int, int>, HashByFirst>>();
-}
-
 }  // namespace
 }  // namespace base
diff --git a/base/containers/span.h b/base/containers/span.h
index 45472d7..30c07190 100644
--- a/base/containers/span.h
+++ b/base/containers/span.h
@@ -228,6 +228,9 @@
 //   sized container (e.g. std::vector) requires an explicit conversion (in the
 //   C++20 draft this is simply UB)
 //
+// Additions beyond the C++20 draft
+// - as_byte_span() function.
+//
 // Furthermore, all constructors and methods are marked noexcept due to the lack
 // of exceptions in Chromium.
 //
@@ -561,6 +564,16 @@
   return span<T, N>(std::data(container), std::size(container));
 }
 
+// Convenience function for converting an object which is itself convertible
+// to span into a span of bytes (i.e. span of const uint8_t). Typically used
+// to convert std::string or string-objects holding chars, or std::vector
+// or vector-like objects holding other scalar types, prior to passing them
+// into an API that requires byte spans.
+template <typename T>
+inline span<const uint8_t> as_byte_span(const T& arg) {
+  return as_bytes(make_span(arg));
+}
+
 }  // namespace base
 
 // EXTENT returns the size of any type that can be converted to a |base::span|
diff --git a/base/containers/span_unittest.cc b/base/containers/span_unittest.cc
index 05d387c..87de1fe 100644
--- a/base/containers/span_unittest.cc
+++ b/base/containers/span_unittest.cc
@@ -1271,6 +1271,23 @@
   EXPECT_EQ(0, vec[0]);
 }
 
+TEST(SpanTest, AsByteSpan) {
+  {
+    constexpr int kArray[] = {2, 3, 5, 7, 11, 13};
+    auto byte_span = as_byte_span(kArray);
+    static_assert(std::is_same_v<decltype(byte_span), span<const uint8_t>>);
+    EXPECT_EQ(byte_span.data(), reinterpret_cast<const uint8_t*>(kArray));
+    EXPECT_EQ(byte_span.size(), sizeof(kArray));
+  }
+  {
+    int kMutArray[] = {2, 3, 5, 7};
+    auto byte_span = as_byte_span(kMutArray);
+    static_assert(std::is_same_v<decltype(byte_span), span<const uint8_t>>);
+    EXPECT_EQ(byte_span.data(), reinterpret_cast<const uint8_t*>(kMutArray));
+    EXPECT_EQ(byte_span.size(), sizeof(kMutArray));
+  }
+}
+
 TEST(SpanTest, MakeSpanFromDataAndSize) {
   int* nullint = nullptr;
   auto empty_span = make_span(nullint, 0u);
diff --git a/base/hash/sha1_unittest.cc b/base/hash/sha1_unittest.cc
index 3d15c66..77d2f60 100644
--- a/base/hash/sha1_unittest.cc
+++ b/base/hash/sha1_unittest.cc
@@ -68,8 +68,7 @@
   for (size_t i = 0; i < base::kSHA1Length; i++)
     EXPECT_EQ(kExpected[i], output[i]);
 
-  base::SHA1Digest output_array =
-      base::SHA1HashSpan(base::as_bytes(base::make_span(input)));
+  base::SHA1Digest output_array = base::SHA1HashSpan(base::as_byte_span(input));
   for (size_t i = 0; i < base::kSHA1Length; i++)
     EXPECT_EQ(kExpected[i], output_array[i]);
 }
@@ -89,8 +88,7 @@
   for (size_t i = 0; i < base::kSHA1Length; i++)
     EXPECT_EQ(kExpected[i], output[i]);
 
-  base::SHA1Digest output_array =
-      base::SHA1HashSpan(base::as_bytes(base::make_span(input)));
+  base::SHA1Digest output_array = base::SHA1HashSpan(base::as_byte_span(input));
   for (size_t i = 0; i < base::kSHA1Length; i++)
     EXPECT_EQ(kExpected[i], output_array[i]);
 }
@@ -109,8 +107,7 @@
   for (size_t i = 0; i < base::kSHA1Length; i++)
     EXPECT_EQ(kExpected[i], output[i]);
 
-  base::SHA1Digest output_array =
-      base::SHA1HashSpan(base::as_bytes(base::make_span(input)));
+  base::SHA1Digest output_array = base::SHA1HashSpan(base::as_byte_span(input));
   for (size_t i = 0; i < base::kSHA1Length; i++)
     EXPECT_EQ(kExpected[i], output_array[i]);
 }
@@ -155,4 +152,4 @@
   for (size_t i = 0; i < base::kSHA1Length; ++i) {
     EXPECT_EQ(kExpected[i], digest_array[i]);
   }
-}
\ No newline at end of file
+}
diff --git a/base/task/thread_pool/worker_thread.h b/base/task/thread_pool/worker_thread.h
index 1548d208..61e04e3c 100644
--- a/base/task/thread_pool/worker_thread.h
+++ b/base/task/thread_pool/worker_thread.h
@@ -70,15 +70,6 @@
     // Called by |worker|'s thread to get a TaskSource from which to run a Task.
     virtual RegisteredTaskSource GetWork(WorkerThread* worker) = 0;
 
-    // // Called by the WorkerThread after it ran a Task. Must only be passed a
-    // // task when ShouldExit() returns true, meaning that this worker should
-    // quit
-    // // immediately and relinquish any task sources it owns. If a task source
-    // // just run by this WorkerThread contains more work after
-    // // RunAndPopNextTask() and the worker is running as usual,
-    // // SwapProcessedTask() should be used instead.
-    // virtual void DidProcessTask(RegisteredTaskSource task_source) = 0;
-
     // Called by the worker thread to swap the task source that has just run for
     // another one, if available. |task_source| must not be null. The worker can
     // then run the task returned as if it was acquired via GetWork().
diff --git a/base/threading/sequence_local_storage_map.h b/base/threading/sequence_local_storage_map.h
index b58a992..fb559ee 100644
--- a/base/threading/sequence_local_storage_map.h
+++ b/base/threading/sequence_local_storage_map.h
@@ -57,7 +57,7 @@
 
     template <class T, class Deleter>
     void Destroy() {
-      Deleter()(&value_as<T>());
+      Deleter()(std::addressof(value_as<T>()));
     }
 
     template <typename T>
diff --git a/base/threading/sequence_local_storage_slot.h b/base/threading/sequence_local_storage_slot.h
index a26a90cc..168a492 100644
--- a/base/threading/sequence_local_storage_slot.h
+++ b/base/threading/sequence_local_storage_slot.h
@@ -93,7 +93,7 @@
     auto* value =
         internal::SequenceLocalStorageMap::GetForCurrentThread().Get(slot_id_);
     if (value) {
-      return &value->external_value.value_as<T>();
+      return std::addressof(value->external_value.value_as<T>());
     }
     return nullptr;
   }
diff --git a/base/threading/sequence_local_storage_slot_unittest.cc b/base/threading/sequence_local_storage_slot_unittest.cc
index 9444003..67ea786 100644
--- a/base/threading/sequence_local_storage_slot_unittest.cc
+++ b/base/threading/sequence_local_storage_slot_unittest.cc
@@ -10,6 +10,11 @@
 #include "base/threading/sequence_local_storage_map.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if BUILDFLAG(IS_WIN)
+#include <wrl/client.h>
+#include <wrl/implements.h>
+#endif
+
 namespace base {
 
 namespace {
@@ -176,4 +181,37 @@
   }
 }
 
+#if BUILDFLAG(IS_WIN)
+namespace {
+class MockComClass
+    : public Microsoft::WRL::RuntimeClass<
+          Microsoft::WRL::RuntimeClassFlags<Microsoft::WRL::ClassicCom>,
+          IUnknown> {
+ public:
+  MockComClass() = default;
+  ~MockComClass() override = default;
+};
+}  // namespace
+
+TEST(SequenceLocalStorageComPtrTest, TestComPtrCanBeStored) {
+  internal::SequenceLocalStorageMap sequence_local_storage_map;
+  internal::ScopedSetSequenceLocalStorageMapForCurrentThread
+      scoped_sequence_local_storage(&sequence_local_storage_map);
+  SequenceLocalStorageSlot<Microsoft::WRL::ComPtr<IUnknown>> slot;
+  {
+    Microsoft::WRL::ComPtr<IUnknown> mock_object =
+        Microsoft::WRL::Make<MockComClass>();
+    EXPECT_NE(mock_object.Get(), nullptr);
+    slot.emplace(mock_object);
+    mock_object = nullptr;
+  }
+  EXPECT_NE(slot.GetValuePointer(), nullptr);
+  // Microsoft::WRL::ComPtr overrides & operator to release the underlying
+  // pointer. If during the emplace or GetValuePointer call the & operator
+  // is invoked, the test will fail.
+  // https://learn.microsoft.com/en-us/cpp/cppcx/wrl/comptr-class?view=msvc-170#operator-ampersand
+  EXPECT_NE(slot.GetValuePointer()->Get(), nullptr);
+}
+#endif
+
 }  // namespace base
diff --git a/base/time/time.h b/base/time/time.h
index c891e45..06e3a7c 100644
--- a/base/time/time.h
+++ b/base/time/time.h
@@ -65,6 +65,7 @@
 #include <stdint.h>
 #include <time.h>
 
+#include <compare>
 #include <iosfwd>
 #include <limits>
 #include <ostream>
@@ -315,24 +316,8 @@
   }
 
   // Comparison operators.
-  constexpr bool operator==(TimeDelta other) const {
-    return delta_ == other.delta_;
-  }
-  constexpr bool operator!=(TimeDelta other) const {
-    return delta_ != other.delta_;
-  }
-  constexpr bool operator<(TimeDelta other) const {
-    return delta_ < other.delta_;
-  }
-  constexpr bool operator<=(TimeDelta other) const {
-    return delta_ <= other.delta_;
-  }
-  constexpr bool operator>(TimeDelta other) const {
-    return delta_ > other.delta_;
-  }
-  constexpr bool operator>=(TimeDelta other) const {
-    return delta_ >= other.delta_;
-  }
+  friend constexpr std::strong_ordering operator<=>(TimeDelta,
+                                                    TimeDelta) = default;
 
   // Returns this delta, ceiled/floored/rounded-away-from-zero to the nearest
   // multiple of |interval|.
@@ -482,24 +467,9 @@
   }
 
   // Comparison operators
-  constexpr bool operator==(const TimeBase<TimeClass>& other) const {
-    return us_ == other.us_;
-  }
-  constexpr bool operator!=(const TimeBase<TimeClass>& other) const {
-    return us_ != other.us_;
-  }
-  constexpr bool operator<(const TimeBase<TimeClass>& other) const {
-    return us_ < other.us_;
-  }
-  constexpr bool operator<=(const TimeBase<TimeClass>& other) const {
-    return us_ <= other.us_;
-  }
-  constexpr bool operator>(const TimeBase<TimeClass>& other) const {
-    return us_ > other.us_;
-  }
-  constexpr bool operator>=(const TimeBase<TimeClass>& other) const {
-    return us_ >= other.us_;
-  }
+  friend constexpr std::strong_ordering operator<=>(
+      const TimeBase<TimeClass>&,
+      const TimeBase<TimeClass>&) = default;
 
  protected:
   constexpr explicit TimeBase(int64_t us) : us_(us) {}
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 9bc8939..113b609 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -1025,8 +1025,17 @@
         deps = []
       }
       deps += [ ":$target_name$build_config_target_suffix" ]
-      metadata = {
-        target_type = [ "java_library" ]
+      if (is_cronet_build) {
+        _abs_deps = []
+        if (defined(invoker.deps)) {
+          foreach(dep, invoker.deps) {
+            _abs_deps += [ get_label_info(dep, "label_no_toolchain") ]
+          }
+        }
+        metadata = {
+          all_deps = _abs_deps
+          target_type = [ "java_library" ]
+        }
       }
     }
   }
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn
index 19d2685..9654489 100644
--- a/build/config/sanitizers/BUILD.gn
+++ b/build/config/sanitizers/BUILD.gn
@@ -476,12 +476,16 @@
       ubsan_ignorelist_path =
           rebase_path("//tools/ubsan/ignorelist.txt", root_build_dir)
     }
+    # TODO(crbug.com/1502579): Enable all of -fsanitize=undefined. Note that
+    # both this list and Clang's defaults omit -fsanitize=float-divide-by-zero.
+    # C and C++ leave it undefined to accommodate non-IEEE floating point, but
+    # we assume the compiler implements IEEE floating point, which does define
+    # division by zero.
     cflags += [
       "-fsanitize=alignment",
       "-fsanitize=bool",
       "-fsanitize=bounds",
       "-fsanitize=builtin",
-      "-fsanitize=float-divide-by-zero",
       "-fsanitize=integer-divide-by-zero",
       "-fsanitize=null",
       "-fsanitize=nonnull-attribute",
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 9a85e0b6..8f71e17 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -79,23 +79,11 @@
 LayerDebugInfo::LayerDebugInfo(const LayerDebugInfo&) = default;
 LayerDebugInfo::~LayerDebugInfo() = default;
 
-Layer::Inputs::Inputs()
-    : contents_opaque(false),
-      contents_opaque_for_text(false),
-      is_drawable(false),
-      double_sided(true),
-      background_color(SkColors::kTransparent) {}
+Layer::Inputs::Inputs() = default;
 
 Layer::Inputs::~Inputs() = default;
 
-Layer::LayerTreeInputs::LayerTreeInputs()
-    : masks_to_bounds(false),
-      is_fast_rounded_corner(false),
-      user_scrollable_horizontal(true),
-      user_scrollable_vertical(true),
-      trilinear_filtering(false),
-      hide_layer_and_subtree(false),
-      scrollable(false) {}
+Layer::LayerTreeInputs::LayerTreeInputs() = default;
 
 Layer::LayerTreeInputs::~LayerTreeInputs() = default;
 
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index efa74a4..786e347 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -1007,12 +1007,12 @@
 
     HitTestOpaqueness hit_test_opaqueness = HitTestOpaqueness::kTransparent;
 
-    bool contents_opaque : 1;
-    bool contents_opaque_for_text : 1;
-    bool is_drawable : 1;
-    bool double_sided : 1;
+    bool contents_opaque : 1 = false;
+    bool contents_opaque_for_text : 1 = false;
+    bool is_drawable : 1 = false;
+    bool double_sided : 1 = true;
 
-    SkColor4f background_color;
+    SkColor4f background_color = SkColors::kTransparent;
     TouchActionRegion touch_action_region;
 
     ElementId element_id;
@@ -1038,23 +1038,23 @@
     float opacity = 1.0f;
     SkBlendMode blend_mode = SkBlendMode::kSrcOver;
 
-    bool masks_to_bounds : 1;
+    bool masks_to_bounds : 1 = false;
 
     // If set, disables this layer's rounded corner from triggering a render
     // surface on itself if possible.
-    bool is_fast_rounded_corner : 1;
+    bool is_fast_rounded_corner : 1 = false;
 
-    bool user_scrollable_horizontal : 1;
-    bool user_scrollable_vertical : 1;
+    bool user_scrollable_horizontal : 1 = true;
+    bool user_scrollable_vertical : 1 = true;
 
-    bool trilinear_filtering : 1;
+    bool trilinear_filtering : 1 = false;
 
-    bool hide_layer_and_subtree : 1;
+    bool hide_layer_and_subtree : 1 = false;
 
     // Indicates that this layer will need a scroll property node and that this
     // layer's bounds correspond to the scroll node's bounds (both |bounds| and
     // |scroll_container_bounds|).
-    bool scrollable : 1;
+    bool scrollable : 1 = false;
 
     gfx::PointF position;
     gfx::Transform transform;
diff --git a/cc/layers/layer_impl.cc b/cc/layers/layer_impl.cc
index 0729eae..36de9e2b 100644
--- a/cc/layers/layer_impl.cc
+++ b/cc/layers/layer_impl.cc
@@ -60,27 +60,11 @@
     : layer_id_(id),
       layer_tree_impl_(tree_impl),
       will_always_push_properties_(will_always_push_properties),
-      scrollable_(false),
-      layer_property_changed_not_from_property_trees_(false),
-      layer_property_changed_from_property_trees_(false),
-      may_contain_video_(false),
-      contents_opaque_(false),
-      contents_opaque_for_text_(false),
-      should_check_backface_visibility_(false),
-      draws_content_(false),
-      contributes_to_drawn_render_surface_(false),
-      is_inner_viewport_scroll_layer_(false),
-      background_color_(SkColors::kTransparent),
-      safe_opaque_background_color_(SkColors::kTransparent),
       transform_tree_index_(kInvalidPropertyNodeId),
       effect_tree_index_(kInvalidPropertyNodeId),
       clip_tree_index_(kInvalidPropertyNodeId),
       scroll_tree_index_(kInvalidPropertyNodeId),
-      current_draw_mode_(DRAW_MODE_NONE),
-      needs_push_properties_(false),
-      needs_show_scrollbars_(false),
-      raster_even_if_not_drawn_(false),
-      has_transform_node_(false) {
+      current_draw_mode_(DRAW_MODE_NONE) {
   DCHECK_GT(layer_id_, 0);
 
   DCHECK(layer_tree_impl_);
diff --git a/cc/layers/layer_impl.h b/cc/layers/layer_impl.h
index a196bc7b..ed0a175 100644
--- a/cc/layers/layer_impl.h
+++ b/cc/layers/layer_impl.h
@@ -516,7 +516,7 @@
   // container layer. Remove scroll_container_bounds_ when we launch CAP.
   gfx::Size scroll_container_bounds_;
   gfx::Size scroll_contents_bounds_;
-  bool scrollable_ : 1;
+  bool scrollable_ : 1 = false;
 
   // Tracks if drawing-related properties have changed since last redraw.
   // TODO(wutao): We want to distinquish the sources of change so that we can
@@ -525,23 +525,23 @@
   // |layer_property_changed_from_property_trees_| does not mean the layer is
   // damaged from animation. We need better mechanism to explicitly capture
   // damage from animations. http://crbug.com/755828.
-  bool layer_property_changed_not_from_property_trees_ : 1;
-  bool layer_property_changed_from_property_trees_ : 1;
+  bool layer_property_changed_not_from_property_trees_ : 1 = false;
+  bool layer_property_changed_from_property_trees_ : 1 = false;
 
-  bool may_contain_video_ : 1;
-  bool contents_opaque_ : 1;
-  bool contents_opaque_for_text_ : 1;
-  bool should_check_backface_visibility_ : 1;
-  bool draws_content_ : 1;
-  bool contributes_to_drawn_render_surface_ : 1;
+  bool may_contain_video_ : 1 = false;
+  bool contents_opaque_ : 1 = false;
+  bool contents_opaque_for_text_ : 1 = false;
+  bool should_check_backface_visibility_ : 1 = false;
+  bool draws_content_ : 1 = false;
+  bool contributes_to_drawn_render_surface_ : 1 = false;
 
-  bool is_inner_viewport_scroll_layer_ : 1;
+  bool is_inner_viewport_scroll_layer_ : 1 = false;
 
   HitTestOpaqueness hit_test_opaqueness_ = HitTestOpaqueness::kTransparent;
   TouchActionRegion touch_action_region_;
 
-  SkColor4f background_color_;
-  SkColor4f safe_opaque_background_color_;
+  SkColor4f background_color_ = SkColors::kTransparent;
+  SkColor4f safe_opaque_background_color_ = SkColors::kTransparent;
 
   int transform_tree_index_;
   int effect_tree_index_;
@@ -578,21 +578,21 @@
   // |touch_action_region_|.
   mutable std::unique_ptr<Region> all_touch_action_regions_;
 
-  bool needs_push_properties_ : 1;
+  bool needs_push_properties_ : 1 = false;
 
   // The needs_show_scrollbars_ bit tracks a pending request to show the overlay
   // scrollbars. It's set by UpdateScrollable() on the scroll layer (not the
   // scrollbar layers) and consumed by LayerTreeImpl::PushPropertiesTo() and
   // LayerTreeImpl::HandleScrollbarShowRequests().
-  bool needs_show_scrollbars_ : 1;
+  bool needs_show_scrollbars_ : 1 = false;
 
   // This is set for layers that have a property because of which they are not
   // drawn (singular transforms), but they can become visible soon (the property
   // is being animated). For this reason, while these layers are not drawn, they
   // are still rasterized.
-  bool raster_even_if_not_drawn_ : 1;
+  bool raster_even_if_not_drawn_ : 1 = false;
 
-  bool has_transform_node_ : 1;
+  bool has_transform_node_ : 1 = false;
 };
 
 }  // namespace cc
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index 7bf17fd..63ff7e82 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -98,13 +98,7 @@
 }  // namespace
 
 PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id)
-    : LayerImpl(tree_impl, id, /*will_always_push_properties=*/true),
-      is_backdrop_filter_mask_(false),
-      was_screen_space_transform_animating_(false),
-      only_used_low_res_last_append_quads_(false),
-      nearest_neighbor_(false),
-      raster_source_size_changed_(false),
-      directly_composited_image_default_raster_scale_changed_(false) {
+    : LayerImpl(tree_impl, id, /*will_always_push_properties=*/true) {
   layer_tree_impl()->RegisterPictureLayerImpl(this);
 }
 
diff --git a/cc/layers/picture_layer_impl.h b/cc/layers/picture_layer_impl.h
index 7715e93..0319425 100644
--- a/cc/layers/picture_layer_impl.h
+++ b/cc/layers/picture_layer_impl.h
@@ -280,19 +280,19 @@
     return std::max(raster_contents_scale_.x(), raster_contents_scale_.y());
   }
 
-  bool is_backdrop_filter_mask_ : 1;
+  bool is_backdrop_filter_mask_ : 1 = false;
 
-  bool was_screen_space_transform_animating_ : 1;
-  bool only_used_low_res_last_append_quads_ : 1;
+  bool was_screen_space_transform_animating_ : 1 = false;
+  bool only_used_low_res_last_append_quads_ : 1 = false;
 
-  bool nearest_neighbor_ : 1;
+  bool nearest_neighbor_ : 1 = false;
 
   // This is set by UpdateRasterSource() on change of raster source size. It's
   // used to recalculate raster scale for will-chagne:transform. It's reset to
   // false after raster scale update.
-  bool raster_source_size_changed_ : 1;
+  bool raster_source_size_changed_ : 1 = false;
 
-  bool directly_composited_image_default_raster_scale_changed_ : 1;
+  bool directly_composited_image_default_raster_scale_changed_ : 1 = false;
 
   LCDTextDisallowedReason lcd_text_disallowed_reason_ =
       LCDTextDisallowedReason::kNoText;
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc
index f667c9d..1026083 100644
--- a/cc/layers/render_surface_impl.cc
+++ b/cc/layers/render_surface_impl.cc
@@ -37,15 +37,7 @@
                                      ElementId id)
     : layer_tree_impl_(layer_tree_impl),
       id_(id),
-      effect_tree_index_(kInvalidPropertyNodeId),
-      num_contributors_(0),
-      has_contributing_layer_that_escapes_clip_(false),
-      surface_property_changed_(false),
-      ancestor_property_changed_(false),
-      contributes_to_drawn_surface_(false),
-      is_render_surface_list_member_(false),
-      intersects_damage_under_(true),
-      nearest_occlusion_immune_ancestor_(nullptr) {
+      effect_tree_index_(kInvalidPropertyNodeId) {
   DCHECK(id);
   damage_tracker_ = DamageTracker::Create();
 }
@@ -72,10 +64,7 @@
     return this;
 }
 
-RenderSurfaceImpl::DrawProperties::DrawProperties() {
-  draw_opacity = 1.f;
-  is_clipped = false;
-}
+RenderSurfaceImpl::DrawProperties::DrawProperties() = default;
 
 RenderSurfaceImpl::DrawProperties::~DrawProperties() = default;
 
diff --git a/cc/layers/render_surface_impl.h b/cc/layers/render_surface_impl.h
index 2dfe1f35..ce8cd42b 100644
--- a/cc/layers/render_surface_impl.h
+++ b/cc/layers/render_surface_impl.h
@@ -293,7 +293,7 @@
     DrawProperties();
     ~DrawProperties();
 
-    float draw_opacity;
+    float draw_opacity = 1.0f;
 
     // Transforms from the surface's own space to the space of its target
     // surface.
@@ -308,7 +308,7 @@
     gfx::Rect clip_rect;
 
     // True if the surface needs to be clipped by clip_rect.
-    bool is_clipped : 1;
+    bool is_clipped : 1 = false;
 
     // Contains a mask information applied to the layer. The coordinates is in
     // the target space of the render surface. The root render surface will
@@ -327,7 +327,7 @@
 
   // Is used to calculate the content rect from property trees.
   gfx::Rect accumulated_content_rect_;
-  int num_contributors_;
+  int num_contributors_ = 0;
 
   // If this is not kInvalidPropertyNodeId, it means that some contributing
   // layer escaping the effect's clip node, and this is the the lowest common
@@ -337,21 +337,21 @@
   // Is used to decide if the surface is clipped.
   // TODO(wangxianzhu): Remove this when removing the
   // RenderSurfaceCommonAncestorClip feature.
-  bool has_contributing_layer_that_escapes_clip_ : 1;
+  bool has_contributing_layer_that_escapes_clip_ : 1 = false;
 
-  bool surface_property_changed_ : 1;
-  bool ancestor_property_changed_ : 1;
+  bool surface_property_changed_ : 1 = false;
+  bool ancestor_property_changed_ : 1 = false;
 
-  bool contributes_to_drawn_surface_ : 1;
-  bool is_render_surface_list_member_ : 1;
-  bool intersects_damage_under_ : 1;
+  bool contributes_to_drawn_surface_ : 1 = false;
+  bool is_render_surface_list_member_ : 1 = false;
+  bool intersects_damage_under_ : 1 = true;
 
   Occlusion occlusion_in_content_space_;
 
   // The nearest ancestor target surface that will contain the contents of this
   // surface, and that ignores outside occlusion. This can point to itself.
   raw_ptr<const RenderSurfaceImpl, AcrossTasksDanglingUntriaged>
-      nearest_occlusion_immune_ancestor_;
+      nearest_occlusion_immune_ancestor_ = nullptr;
 
   std::unique_ptr<DamageTracker> damage_tracker_;
 };
diff --git a/cc/paint/paint_op_buffer.cc b/cc/paint/paint_op_buffer.cc
index 82dd6404..965d6d0 100644
--- a/cc/paint/paint_op_buffer.cc
+++ b/cc/paint/paint_op_buffer.cc
@@ -87,14 +87,7 @@
   DCHECK(scratch_buffer);
 }
 
-PaintOpBuffer::PaintOpBuffer()
-    : has_non_aa_paint_(false),
-      has_discardable_images_(false),
-      has_draw_ops_(false),
-      has_draw_text_ops_(false),
-      has_save_layer_ops_(false),
-      has_save_layer_alpha_ops_(false),
-      has_effects_preventing_lcd_text_for_save_layer_alpha_(false) {}
+PaintOpBuffer::PaintOpBuffer() = default;
 
 PaintOpBuffer::PaintOpBuffer(PaintOpBuffer&& other) {
   *this = std::move(other);
diff --git a/cc/paint/paint_op_buffer.h b/cc/paint/paint_op_buffer.h
index e8304e9..054b180 100644
--- a/cc/paint/paint_op_buffer.h
+++ b/cc/paint/paint_op_buffer.h
@@ -373,13 +373,13 @@
   // required for an MSAA sample count for raster.
   int num_slow_paths_up_to_min_for_MSAA_ = 0;
 
-  bool has_non_aa_paint_ : 1;
-  bool has_discardable_images_ : 1;
-  bool has_draw_ops_ : 1;
-  bool has_draw_text_ops_ : 1;
-  bool has_save_layer_ops_ : 1;
-  bool has_save_layer_alpha_ops_ : 1;
-  bool has_effects_preventing_lcd_text_for_save_layer_alpha_ : 1;
+  bool has_non_aa_paint_ : 1 = false;
+  bool has_discardable_images_ : 1 = false;
+  bool has_draw_ops_ : 1 = false;
+  bool has_draw_text_ops_ : 1 = false;
+  bool has_save_layer_ops_ : 1 = false;
+  bool has_save_layer_alpha_ops_ : 1 = false;
+  bool has_effects_preventing_lcd_text_for_save_layer_alpha_ : 1 = false;
 };
 
 }  // namespace cc
diff --git a/cc/resources/ui_resource_manager.cc b/cc/resources/ui_resource_manager.cc
index b40f50c5..f4d9811 100644
--- a/cc/resources/ui_resource_manager.cc
+++ b/cc/resources/ui_resource_manager.cc
@@ -4,11 +4,11 @@
 
 #include "cc/resources/ui_resource_manager.h"
 
+#include <unordered_map>
 #include <utility>
 
 #include "base/check.h"
 #include "base/containers/contains.h"
-#include "base/containers/cxx20_erase.h"
 #include "cc/resources/scoped_ui_resource.h"
 
 namespace cc {
@@ -83,7 +83,7 @@
 
   // Evict all UIResources whose bitmaps are no longer referenced outside of the
   // map.
-  base::EraseIf(owned_shared_resources_,
+  std::erase_if(owned_shared_resources_,
                 [](auto& pair) { return pair.second->IsUniquelyOwned(); });
 
   // Max capacity of `owned_shared_resources_`. A DCHECK() would fire if cache
diff --git a/cc/slim/layer.cc b/cc/slim/layer.cc
index 50c2fd8..77633785 100644
--- a/cc/slim/layer.cc
+++ b/cc/slim/layer.cc
@@ -52,17 +52,8 @@
   }
   return base::AdoptRef(new Layer(std::move(cc_layer)));
 }
-
 Layer::Layer(scoped_refptr<cc::Layer> cc_layer)
-    : cc_layer_(std::move(cc_layer)),
-      id_(g_next_id.GetNext() + 1),
-      is_drawable_(false),
-      contents_opaque_(false),
-      draws_content_(false),
-      hide_layer_and_subtree_(false),
-      masks_to_bounds_(false),
-      property_changed_(false),
-      subtree_property_changed_(false) {}
+    : cc_layer_(std::move(cc_layer)), id_(g_next_id.GetNext() + 1) {}
 
 Layer::~Layer() {
   RemoveAllChildren();
diff --git a/cc/slim/layer.h b/cc/slim/layer.h
index 5b6a582..ec90869 100644
--- a/cc/slim/layer.h
+++ b/cc/slim/layer.h
@@ -302,18 +302,18 @@
 
   SkColor4f background_color_ = SkColors::kTransparent;
   float opacity_ = 1.0f;
-  bool is_drawable_ : 1;
-  bool contents_opaque_ : 1;
-  bool draws_content_ : 1;
-  bool hide_layer_and_subtree_ : 1;
-  bool masks_to_bounds_ : 1;
+  bool is_drawable_ : 1 = false;
+  bool contents_opaque_ : 1 = false;
+  bool draws_content_ : 1 = false;
+  bool hide_layer_and_subtree_ : 1 = false;
+  bool masks_to_bounds_ : 1 = false;
 
   // Indicates there is damage for this layer.
-  bool property_changed_ : 1;
+  bool property_changed_ : 1 = false;
   // Indicates there is damage for the entire subtree. This is tracked
   // only at the root of the subtree, and is applied recursively to the entire
   // subtree at draw time.
-  bool subtree_property_changed_ : 1;
+  bool subtree_property_changed_ : 1 = false;
 };
 
 }  // namespace cc::slim
diff --git a/cc/tiles/tile.cc b/cc/tiles/tile.cc
index 1f145501..5ee868a 100644
--- a/cc/tiles/tile.cc
+++ b/cc/tiles/tile.cc
@@ -34,11 +34,7 @@
       flags_(flags),
       tiling_i_index_(info.tiling_i_index),
       tiling_j_index_(info.tiling_j_index),
-      required_for_activation_(false),
-      required_for_draw_(false),
-      is_solid_color_analysis_performed_(false),
       can_use_lcd_text_(info.can_use_lcd_text),
-      raster_task_scheduled_with_checker_images_(false),
       id_(tile_manager->GetUniqueTileId()) {
   raster_rects_.emplace_back(info.content_rect, info.raster_transform);
 }
diff --git a/cc/tiles/tile.h b/cc/tiles/tile.h
index 3b72783..7b371f29 100644
--- a/cc/tiles/tile.h
+++ b/cc/tiles/tile.h
@@ -180,14 +180,14 @@
 
   unsigned scheduled_priority_ = 0;
 
-  bool required_for_activation_ : 1;
-  bool required_for_draw_ : 1;
-  bool is_solid_color_analysis_performed_ : 1;
+  bool required_for_activation_ : 1 = false;
+  bool required_for_draw_ : 1 = false;
+  bool is_solid_color_analysis_performed_ : 1 = false;
   const bool can_use_lcd_text_ : 1;
 
   // Set to true if there is a raster task scheduled for this tile that will
   // rasterize a resource with checker images.
-  bool raster_task_scheduled_with_checker_images_ : 1;
+  bool raster_task_scheduled_with_checker_images_ : 1 = false;
 
   Id id_;
 
diff --git a/cc/trees/sticky_position_constraint.cc b/cc/trees/sticky_position_constraint.cc
index ce4bf733..16dbd07 100644
--- a/cc/trees/sticky_position_constraint.cc
+++ b/cc/trees/sticky_position_constraint.cc
@@ -6,16 +6,7 @@
 
 namespace cc {
 
-StickyPositionConstraint::StickyPositionConstraint()
-    : is_anchored_left(false),
-      is_anchored_right(false),
-      is_anchored_top(false),
-      is_anchored_bottom(false),
-      left_offset(0.f),
-      right_offset(0.f),
-      top_offset(0.f),
-      bottom_offset(0.f) {}
-
+StickyPositionConstraint::StickyPositionConstraint() = default;
 StickyPositionConstraint::StickyPositionConstraint(
     const StickyPositionConstraint& other) = default;
 
diff --git a/cc/trees/sticky_position_constraint.h b/cc/trees/sticky_position_constraint.h
index c7ea5f8..706a7f1 100644
--- a/cc/trees/sticky_position_constraint.h
+++ b/cc/trees/sticky_position_constraint.h
@@ -19,17 +19,17 @@
   StickyPositionConstraint(const StickyPositionConstraint& other);
   StickyPositionConstraint& operator=(const StickyPositionConstraint& other);
 
-  bool is_anchored_left : 1;
-  bool is_anchored_right : 1;
-  bool is_anchored_top : 1;
-  bool is_anchored_bottom : 1;
+  bool is_anchored_left : 1 = false;
+  bool is_anchored_right : 1 = false;
+  bool is_anchored_top : 1 = false;
+  bool is_anchored_bottom : 1 = false;
 
   // The offset from each edge of the ancestor scroller (or the viewport) to
   // try to maintain to the sticky box as we scroll.
-  float left_offset;
-  float right_offset;
-  float top_offset;
-  float bottom_offset;
+  float left_offset = 0;
+  float right_offset = 0;
+  float top_offset = 0;
+  float bottom_offset = 0;
 
   // The rectangle in which the sticky box is able to be positioned. This may be
   // smaller than the scroller viewport due to things like padding.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 78e1ef8..b3c849b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -132,6 +132,7 @@
 import org.chromium.chrome.browser.multiwindow.MultiInstanceChromeTabbedActivity;
 import org.chromium.chrome.browser.multiwindow.MultiInstanceManager;
 import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
+import org.chromium.chrome.browser.multiwindow.MultiWindowUtils.InstanceAllocationType;
 import org.chromium.chrome.browser.native_page.NativePageAssassin;
 import org.chromium.chrome.browser.navigation_predictor.NavigationPredictorBridge;
 import org.chromium.chrome.browser.new_tab_url.DseNewTabUrlManager;
@@ -2288,9 +2289,11 @@
             // |allocInstanceId| doesn't do any disk I/O that would add a long-running task
             // to pre-inflation startup.
             boolean preferNew = getExtraPreferNewFromIntent(intent);
-            mWindowId = mMultiInstanceManager.allocInstanceId(
-                    windowId, ApplicationStatus.getTaskId(this), preferNew);
-            logIntentInfo(intent, mWindowId);
+            Pair<Integer, Integer> instanceIdInfo =
+                    mMultiInstanceManager.allocInstanceId(
+                            windowId, ApplicationStatus.getTaskId(this), preferNew);
+            mWindowId = instanceIdInfo.first;
+            logIntentInfo(intent, instanceIdInfo);
         }
         if (mWindowId == INVALID_WINDOW_ID) {
             Log.i(TAG, "Window ID not allocated. Finishing the activity");
@@ -2310,12 +2313,14 @@
         return super.isStartedUpCorrectly(intent);
     }
 
-    private void logIntentInfo(Intent intent, int windowId) {
+    private void logIntentInfo(Intent intent, Pair<Integer, Integer> instanceIdInfo) {
         boolean willUseNewInstance = MultiWindowUtils.willUseNewInstance();
         boolean isFromOs =
                 getReferrer() != null
                         && getReferrer().toString().equals(SOURCE_ACTIVITY_REFERRER_OS);
         boolean isFromChrome = IntentHandler.wasIntentSenderChrome(intent);
+        int windowId = instanceIdInfo.first;
+        @InstanceAllocationType int windowAllocationType = instanceIdInfo.second;
 
         var logMessage =
                 "Intent action: "
@@ -2325,6 +2330,8 @@
                                 intent,
                                 IntentHandler.EXTRA_LAUNCHED_VIA_CHROME_LAUNCHER_ACTIVITY,
                                 false)
+                        + "\nReferrer: "
+                        + getReferrer()
                         + "\nIntent contains LAUNCHER category: "
                         + intent.hasCategory(Intent.CATEGORY_LAUNCHER)
                         + "\nIntent contains FLAG_ACTIVITY_MULTIPLE_TASK: "
@@ -2339,8 +2346,10 @@
                         + isFromOs
                         + "\n@ExternalAppId of intent source: "
                         + IntentHandler.determineExternalIntentSource(intent)
-                        + "\nIs new instanceId allocated: "
-                        + willUseNewInstance;
+                        + "\nAre all instances running: "
+                        + willUseNewInstance
+                        + "\nWindow allocation type: "
+                        + windowAllocationType;
         Log.i(TAG_MULTI_INSTANCE, logMessage);
         // Only crash-report if a valid window ID is allocated to launch the intent.
         if (windowId == INVALID_WINDOW_ID) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java
index 092ab88..106b401 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/CompositorButton.java
@@ -78,8 +78,8 @@
     private boolean mIsVisible;
     private boolean mIsIncognito;
     private boolean mIsEnabled;
-    private String mAccessibilityDescription;
-    private String mAccessibilityDescriptionIncognito;
+    private String mAccessibilityDescription = "";
+    private String mAccessibilityDescriptionIncognito = "";
 
     /**
      * Default constructor for {@link CompositorButton}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
index 893b0cb..fee7385 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -158,7 +158,6 @@
     private static final float NEW_TAB_BUTTON_DEFAULT_PRESSED_OPACITY = 0.2f;
     private static final float NEW_TAB_BUTTON_HOVER_BACKGROUND_PRESSED_OPACITY = 0.12f;
     private static final float NEW_TAB_BUTTON_HOVER_BACKGROUND_DEFAULT_OPACITY = 0.08f;
-    private static final float NEW_TAB_BUTTON_DARK_DETACHED_OPACITY = 0.15f;
     static final float TAB_OPACITY_HIDDEN = 0.f;
     static final float TAB_OPACITY_VISIBLE_BACKGROUND = 0.55f;
     static final float TAB_OPACITY_VISIBLE_FOREGROUND = 1.f;
@@ -184,9 +183,6 @@
     private static final String PLACEHOLDER_VISIBLE_DURATION_HISTOGRAM_NAME =
             "Android.TabStrip.PlaceholderStripVisibleDuration";
 
-    // The max width of the tab hover card in terms of the enclosing window width percent.
-    static final float HOVER_CARD_MAX_WIDTH_PERCENT = 0.9f;
-
     // External influences
     private final LayoutUpdateHost mUpdateHost;
     private final LayoutRenderHost mRenderHost;
@@ -523,11 +519,6 @@
         return mStripTabsToRender;
     }
 
-    @VisibleForTesting
-    public int getTabCount() {
-        return mStripTabs.length;
-    }
-
     /**
      * @return A {@link TintedCompositorButton} that represents the positioning of the new tab
      *         button.
@@ -1059,21 +1050,19 @@
 
         // 1. Replace the placeholder tabs by updating the relevant properties.
         for (int i = 0; i < numTabsToCopy; i++) {
-            final StripLayoutTab tab = mStripTabs[i];
+            final StripLayoutTab stripTab = mStripTabs[i];
+            final Tab tab = mModel.getTabAt(i);
 
-            tab.setId(mModel.getTabAt(i).getId());
-            tab.setIsPlaceholder(false);
-            tab.setContainerOpacity(TAB_OPACITY_HIDDEN);
+            pushPropertiesToPlaceholder(stripTab, tab);
         }
         if (!needPlaceholdersBeforeActiveTab) mActiveTabReplaced = true;
 
         // 2. If a new tab was created on startup (e.g. through intent), copy it over now.
         if (mCreatedTabOnStartup) {
-            final StripLayoutTab tab = mStripTabs[mStripTabs.length - 1];
+            final StripLayoutTab stripTab = mStripTabs[mStripTabs.length - 1];
+            final Tab tab = mModel.getTabAt(mModel.getCount() - 1);
 
-            tab.setId(mModel.getTabAt(mModel.getCount() - 1).getId());
-            tab.setIsPlaceholder(false);
-            tab.setContainerOpacity(TAB_OPACITY_HIDDEN);
+            pushPropertiesToPlaceholder(stripTab, tab);
         }
 
         // 3. If the active tab could not be copied earlier, copy it over now at the correct index.
@@ -1082,11 +1071,10 @@
             if (mCreatedTabOnStartup) prevActiveIndex--;
 
             if (prevActiveIndex >= 0) {
-                final StripLayoutTab tab = mStripTabs[mActiveTabIndexOnStartup];
+                final StripLayoutTab stripTab = mStripTabs[mActiveTabIndexOnStartup];
+                final Tab tab = mModel.getTabAt(prevActiveIndex);
 
-                tab.setId(mModel.getTabAt(prevActiveIndex).getId());
-                tab.setIsPlaceholder(false);
-                tab.setContainerOpacity(TAB_OPACITY_HIDDEN);
+                pushPropertiesToPlaceholder(stripTab, tab);
 
                 mActiveTabReplaced = true;
             }
@@ -1133,9 +1121,9 @@
 
         if (replaceIndex >= 0 && replaceIndex < mStripTabs.length) {
             final StripLayoutTab placeholderTab = mStripTabs[replaceIndex];
-            placeholderTab.setId(id);
-            placeholderTab.setIsPlaceholder(false);
-            placeholderTab.setContainerOpacity(TAB_OPACITY_HIDDEN);
+            final Tab tab = getTabById(id);
+
+            pushPropertiesToPlaceholder(placeholderTab, tab);
 
             if (placeholderTab.isVisible()) {
                 mRenderHost.requestRender();
@@ -2110,6 +2098,12 @@
         tab.setIsPlaceholder(true);
         tab.setContainerOpacity(TAB_OPACITY_VISIBLE_FOREGROUND);
 
+        // TODO(https://crbug.com/1502238): Added placeholder a11y descriptions to prevent crash due
+        //  to invalid a11y node. Replace with official strings when available.
+        String description = "Placeholder Tab";
+        String title = "Placeholder";
+        tab.setAccessibilityDescription(description, title);
+
         pushPropertiesToTab(tab);
 
         return tab;
@@ -2130,6 +2124,14 @@
         return tab;
     }
 
+    private void pushPropertiesToPlaceholder(StripLayoutTab placeholderTab, Tab tab) {
+        placeholderTab.setId(tab.getId());
+        placeholderTab.setIsPlaceholder(false);
+        placeholderTab.setContainerOpacity(TAB_OPACITY_HIDDEN);
+
+        setAccessibilityDescription(placeholderTab, tab);
+    }
+
     private void pushPropertiesToTab(StripLayoutTab tab) {
         // The close button is visible by default. If it should be hidden on tab creation, do not
         // animate the fade-out. See (https://crbug.com/1342654).
@@ -3510,10 +3512,6 @@
         mLastOffsetX = 0.f;
     }
 
-    protected void setActiveClickedTabForTesting(StripLayoutTab tab) {
-        mActiveClickedTab = tab;
-    }
-
     StripLayoutTab getActiveClickedTabForTesting() {
         return mActiveClickedTab;
     }
@@ -3591,17 +3589,6 @@
                 });
     }
 
-    void selectTabAtIndex(int atIndex) {
-        if (!MultiWindowUtils.isMultiInstanceApi31Enabled()) return;
-        if (!TabUiFeatureUtilities.isTabDragEnabled()) return;
-
-        TabModelUtils.setIndex(mModel, atIndex, true);
-    }
-
-    int getCurrentTabIndexForTesting() {
-        return findIndexForTab(TabModelUtils.getCurrentTabId(mModel));
-    }
-
     void sendMoveWindowBroadcast(View view, float startXInView, float startYInView) {
         if (!MultiWindowUtils.isMultiInstanceApi31Enabled()) return;
         if (!TabUiFeatureUtilities.isTabDragEnabled()) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java
index afc10ce..c5aea61 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java
@@ -149,6 +149,7 @@
     private CompositorButton mModelSelectorButton;
     private Context mContext;
     private boolean mBrowserScrimShowing;
+    private boolean mIsHidden;
     private int mTabStripFadeShort;
     private int mTabStripFadeLong;
     private float mTabStripFadeShortWidth;
@@ -525,6 +526,11 @@
         mTabDragSource = null;
     }
 
+    /** Mark whether tab strip |isHidden|. */
+    public void setIsTabStripHidden(boolean isHidden) {
+        mIsHidden = isHidden;
+    }
+
     @Override
     public void onResumeWithNative() {
         Tab currentTab = mTabModelSelector.getCurrentTab();
@@ -567,6 +573,11 @@
         int hoveredTabId = getActiveStripLayoutHelper().getLastHoveredTab() == null
                 ? TabModel.INVALID_TAB_INDEX
                 : getActiveStripLayoutHelper().getLastHoveredTab().getId();
+        if (mIsHidden) {
+            // When tab strip is hidden, the stable offset of this scene layer should be a negative
+            // value.
+            yOffset -= mHeight;
+        }
         mTabStripTreeProvider.pushAndUpdateStrip(this, mLayerTitleCacheSupplier.get(),
                 resourceManager, getActiveStripLayoutHelper().getStripLayoutTabsToRender(), yOffset,
                 selectedTabId, hoveredTabId);
@@ -931,6 +942,9 @@
         };
 
         mTabModelSelector.addObserver(mTabModelSelectorObserver);
+        if (mTabDragSource != null) {
+            mTabDragSource.setTabModelSelector(mTabModelSelector);
+        }
     }
 
     private void updateTitleForTab(Tab tab) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
index 4dd2ba9..af1a847d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
@@ -227,7 +227,7 @@
     private float mContainerOpacity;
     private float mLeftInset;
     private float mRightInset;
-    private String mAccessibilityDescription;
+    private String mAccessibilityDescription = "";
 
     // Ideal intermediate parameters
     private float mIdealX;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java
index aca7b575..9857593 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSource.java
@@ -19,6 +19,7 @@
 import android.widget.ImageView;
 
 import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.Log;
@@ -32,6 +33,8 @@
 import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabUtils;
+import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities;
 import org.chromium.ui.base.LocalizationUtils;
 import org.chromium.ui.dragdrop.DragAndDropDelegate;
@@ -62,6 +65,7 @@
     private float mLastXDp;
     private float mLastYDp;
     private int mLastAction;
+    @Nullable private TabModelSelector mTabModelSelector;
 
     /**
      * Prepares the toolbar view to listen to the drag events and data drop after the drag is
@@ -174,6 +178,11 @@
         return res;
     }
 
+    /** Sets @{@link TabModelSelector} to retrieve model info. */
+    public void setTabModelSelector(TabModelSelector tabModelSelector) {
+        mTabModelSelector = tabModelSelector;
+    }
+
     private boolean didOccurInTabStrip(float yPx) {
         return yPx <= mTabStripHeightPx;
     }
@@ -216,16 +225,18 @@
             // dragged. Return the original payload drop for next in line to receive the
             // drop to handle.
             Tab tabBeingDragged = DragDropGlobalState.getInstance().tabBeingDragged;
-            if (tabBeingDragged == null || sourceTabId != tabBeingDragged.getId()) {
+            if (tabBeingDragged == null
+                    || sourceTabId != tabBeingDragged.getId()
+                    || mTabModelSelector == null) {
                 Log.w(TAG, "DnD: Received an invalid tab drop.");
                 return false;
             }
-            int tabPositionIndex = getTabPositionIndex(xPx * mPxToDp);
+            int tabPositionIndex =
+                    getTabPositionIndex(xPx * mPxToDp, tabBeingDragged.isIncognito());
             // TODO(crbug.com/1497784): Pass the Activity explicitly in place of casting the
             // context handle.
             mMultiInstanceManager.moveTabToWindow(
                     (Activity) view.getContext(), tabBeingDragged, tabPositionIndex);
-            mStripLayoutHelperSupplier.get().selectTabAtIndex(tabPositionIndex);
         }
         return true;
     }
@@ -282,12 +293,18 @@
         return numberText.isEmpty() ? Tab.INVALID_TAB_ID : Integer.parseInt(numberText);
     }
 
-    private int getTabPositionIndex(float dropXDp) {
+    private int getTabPositionIndex(float dropXDp, boolean isDraggedTabIncognito) {
+        StripLayoutHelper activeStripHelper = mStripLayoutHelperSupplier.get();
+        // If dragged tab and drop target strip don't belong to same model,
+        // drop tab at corresponding model at end of strip.
+        if (mTabModelSelector.getCurrentModel().isIncognito() != isDraggedTabIncognito) {
+            TabModel model = mTabModelSelector.getModel(isDraggedTabIncognito);
+            return model.getCount();
+        }
         // Based on the location of the drop determine the position index where the tab will be
         // placed.
-        StripLayoutHelper activeStripHelper = mStripLayoutHelperSupplier.get();
         StripLayoutTab droppedOn = activeStripHelper.getTabAtPosition(dropXDp);
-        int tabPositionIndex = activeStripHelper.getTabCount();
+        int tabPositionIndex = mTabModelSelector.getCurrentModel().getCount();
         // If not dropped on any existing tabs then simply add it at the end.
         if (droppedOn != null) {
             tabPositionIndex = activeStripHelper.findIndexForTab(droppedOn.getId());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbar.java
index 70199f8c..cfb05b4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbar.java
@@ -518,7 +518,7 @@
     }
 
     @Override
-    protected int getTabStripHeight() {
+    protected int getTabStripHeightFromResource() {
         return 0;
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/BrowserControlsManager.java b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/BrowserControlsManager.java
index d83fbb7..f46f31e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/BrowserControlsManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/BrowserControlsManager.java
@@ -603,6 +603,7 @@
                         TraceEvent.scoped("BrowserControlsManager.notifyControlOffsetChanged")) {
             scheduleVisibilityUpdate();
             if (shouldShowAndroidControls()) {
+                // TODO(crbug.com/1501445): Fix frame mismatch between Android view with cc layer.
                 mControlContainer.getView().setTranslationY(getTopControlOffset());
             }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManager.java b/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManager.java
index b57ce8a..6a02a5b6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManager.java
@@ -12,6 +12,7 @@
 import android.content.res.Configuration;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
+import android.util.Pair;
 import android.view.Display;
 
 import androidx.annotation.Nullable;
@@ -34,6 +35,7 @@
 import org.chromium.chrome.browser.lifecycle.NativeInitObserver;
 import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver;
 import org.chromium.chrome.browser.lifecycle.RecreateObserver;
+import org.chromium.chrome.browser.multiwindow.MultiWindowUtils.InstanceAllocationType;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabModelObserver;
@@ -518,13 +520,14 @@
 
     /**
      * Assigned an ID for the current activity instance.
+     *
      * @param windowId Instance ID explicitly given for assignment.
      * @param taskId Task ID of the activity.
-     * @param preferNew Boolean indicating a fresh new instance is preferred
-     *        over the one that will load previous tab files from disk.
+     * @param preferNew Boolean indicating a fresh new instance is preferred over the one that will
+     *     load previous tab files from disk.
      */
-    public int allocInstanceId(int windowId, int taskId, boolean preferNew) {
-        return 0; // Use a default index 0.
+    public Pair<Integer, Integer> allocInstanceId(int windowId, int taskId, boolean preferNew) {
+        return Pair.create(0, InstanceAllocationType.DEFAULT); // Use a default index 0.
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java b/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java
index 6ff4413..0fddd14 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31.java
@@ -12,6 +12,7 @@
 import android.os.Bundle;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
+import android.util.Pair;
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 
@@ -34,6 +35,7 @@
 import org.chromium.chrome.browser.app.tabmodel.TabWindowManagerSingleton;
 import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
+import org.chromium.chrome.browser.multiwindow.MultiWindowUtils.InstanceAllocationType;
 import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.ChromeSharedPreferences;
 import org.chromium.chrome.browser.profiles.Profile;
@@ -242,7 +244,7 @@
     }
 
     @Override
-    public int allocInstanceId(int windowId, int taskId, boolean preferNew) {
+    public Pair<Integer, Integer> allocInstanceId(int windowId, int taskId, boolean preferNew) {
         removeInvalidInstanceData();
 
         int instanceId = getInstanceByTask(taskId);
@@ -252,7 +254,7 @@
         // When out of range, ignore the ID and apply the normal allocation logic below.
         if (windowId >= 0 && windowId < mMaxInstances && instanceId == INVALID_INSTANCE_ID) {
             Log.i(TAG_MULTI_INSTANCE, "Existing Instance - selected Id allocated: " + windowId);
-            return windowId;
+            return Pair.create(windowId, InstanceAllocationType.EXISTING_INSTANCE_UNMAPPED_TASK);
         }
 
         // First, see if we have instance-task ID mapping. If we do, use the instance id. This
@@ -260,7 +262,7 @@
         // new one. We pair them again.
         if (instanceId != INVALID_INSTANCE_ID) {
             Log.i(TAG_MULTI_INSTANCE, "Existing Instance - mapped Id allocated: " + instanceId);
-            return instanceId;
+            return Pair.create(instanceId, InstanceAllocationType.EXISTING_INSTANCE_MAPPED_TASK);
         }
 
         // If asked to always create a fresh new instance, not from persistent state, do it here.
@@ -268,10 +270,11 @@
             for (int i = 0; i < mMaxInstances; ++i) {
                 if (!instanceEntryExists(i)) {
                     logNewInstanceId(i);
-                    return i;
+                    return Pair.create(i, InstanceAllocationType.PREFER_NEW_INSTANCE_NEW_TASK);
                 }
             }
-            return INVALID_INSTANCE_ID;
+            return Pair.create(
+                    INVALID_INSTANCE_ID, InstanceAllocationType.PREFER_NEW_INVALID_INSTANCE);
         }
 
         // Search for an unassigned ID. The index is available for the assignment if:
@@ -281,6 +284,7 @@
         // for |readLastAccessedTime|, so can be regarded as the least favored.
         int id = INVALID_INSTANCE_ID;
         boolean newInstanceIdAllocated = false;
+        @InstanceAllocationType int allocationType = InstanceAllocationType.INVALID_INSTANCE;
         for (int i = 0; i < mMaxInstances; ++i) {
             int taskIdFromMap = getTaskFromMap(i);
             if (taskIdFromMap != INVALID_TASK_ID) {
@@ -289,17 +293,21 @@
             if (id == INVALID_INSTANCE_ID || readLastAccessedTime(i) > readLastAccessedTime(id)) {
                 id = i;
                 newInstanceIdAllocated = !instanceEntryExists(i);
+                allocationType =
+                        newInstanceIdAllocated
+                                ? InstanceAllocationType.NEW_INSTANCE_NEW_TASK
+                                : InstanceAllocationType.EXISTING_INSTANCE_NEW_TASK;
             }
         }
 
         if (newInstanceIdAllocated) {
             logNewInstanceId(id);
-        } else {
+        } else if (id != INVALID_INSTANCE_ID) {
             Log.i(TAG_MULTI_INSTANCE,
                     "Existing Instance - persisted and unmapped Id allocated: " + id);
         }
 
-        return id;
+        return Pair.create(id, allocationType);
     }
 
     private void logNewInstanceId(int i) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtils.java
index a11529f..91f89f7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtils.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtils.java
@@ -88,6 +88,28 @@
         int MULTI_WINDOW = 1;
     }
 
+    @IntDef({
+        InstanceAllocationType.DEFAULT,
+        InstanceAllocationType.EXISTING_INSTANCE_UNMAPPED_TASK,
+        InstanceAllocationType.EXISTING_INSTANCE_MAPPED_TASK,
+        InstanceAllocationType.PREFER_NEW_INSTANCE_NEW_TASK,
+        InstanceAllocationType.PREFER_NEW_INVALID_INSTANCE,
+        InstanceAllocationType.NEW_INSTANCE_NEW_TASK,
+        InstanceAllocationType.EXISTING_INSTANCE_NEW_TASK,
+        InstanceAllocationType.INVALID_INSTANCE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InstanceAllocationType {
+        int DEFAULT = 0;
+        int EXISTING_INSTANCE_UNMAPPED_TASK = 1;
+        int EXISTING_INSTANCE_MAPPED_TASK = 2;
+        int PREFER_NEW_INSTANCE_NEW_TASK = 3;
+        int PREFER_NEW_INVALID_INSTANCE = 4;
+        int NEW_INSTANCE_NEW_TASK = 5;
+        int EXISTING_INSTANCE_NEW_TASK = 6;
+        int INVALID_INSTANCE = 7;
+    }
+
     protected MultiWindowUtils() {
         mMultiInstanceApi31Enabled = isMultiInstanceApi31Enabled();
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
index 1507b103..2f9852f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -136,7 +136,7 @@
  * A {@link RootUiCoordinator} variant that controls tabbed-mode specific UI.
  */
 public class TabbedRootUiCoordinator extends RootUiCoordinator {
-    private static boolean sDisableStatusIndicatorAnimationsForTesting;
+    private static boolean sDisableTopControlsAnimationForTesting;
     private final RootUiTabObserver mRootUiTabObserver;
     private TabbedSystemUiCoordinator mSystemUiCoordinator;
 
@@ -526,6 +526,7 @@
         PwaBottomSheetControllerFactory.attach(mWindowAndroid, mPwaBottomSheetController);
         initCommerceSubscriptionsService();
         initUndoGroupSnackbarController();
+        initTabStripTransitionCoordinator();
     }
 
     /**
@@ -829,11 +830,13 @@
         }
     }
 
-    private void updateTopControlsHeight(boolean animate) {
+    private void updateTopControlsHeight() {
+        final boolean animate = !sDisableTopControlsAnimationForTesting;
         final BrowserControlsSizer browserControlsSizer = mBrowserControlsManager;
-        final int resourceId = mControlContainerHeightResource;
         final int topControlsNewHeight =
-                mActivity.getResources().getDimensionPixelSize(resourceId) + mStatusIndicatorHeight;
+                mToolbarManager.getToolbar().getHeight()
+                        + mToolbarManager.getToolbar().getTabStripHeight()
+                        + mStatusIndicatorHeight;
 
         browserControlsSizer.setAnimateBrowserControlsHeightChanges(animate);
         browserControlsSizer.setTopControlsHeight(topControlsNewHeight, mStatusIndicatorHeight);
@@ -866,14 +869,14 @@
                 mStatusBarColorController::getStatusBarColorWithoutStatusIndicator,
                 mCanAnimateBrowserControls, layoutManager::requestUpdate);
         layoutManager.addSceneOverlay(mStatusIndicatorCoordinator.getSceneLayer());
-        mStatusIndicatorObserver = new StatusIndicatorCoordinator.StatusIndicatorObserver() {
-            @Override
-            public void onStatusIndicatorHeightChanged(int indicatorHeight) {
-                mStatusIndicatorHeight = indicatorHeight;
-                boolean animate = !sDisableStatusIndicatorAnimationsForTesting;
-                updateTopControlsHeight(animate);
-            }
-        };
+        mStatusIndicatorObserver =
+                new StatusIndicatorCoordinator.StatusIndicatorObserver() {
+                    @Override
+                    public void onStatusIndicatorHeightChanged(int indicatorHeight) {
+                        mStatusIndicatorHeight = indicatorHeight;
+                        updateTopControlsHeight();
+                    }
+                };
         mStatusIndicatorCoordinator.addObserver(mStatusIndicatorObserver);
         mStatusIndicatorCoordinator.addObserver(mStatusBarColorController);
 
@@ -903,6 +906,12 @@
         }
     }
 
+    private void initTabStripTransitionCoordinator() {
+        mToolbarManager
+                .getTabStripHeightSupplier()
+                .addObserver((height) -> updateTopControlsHeight());
+    }
+
     @Override
     protected boolean supportsEdgeToEdge() {
         return true;
@@ -1003,8 +1012,8 @@
                 mActivity, mModalDialogManagerSupplier, () -> ApplicationLifetime.terminate(true));
     }
 
-    public static void setDisableStatusIndicatorAnimationsForTesting(boolean disable) {
-        sDisableStatusIndicatorAnimationsForTesting = disable;
-        ResettersForTesting.register(() -> sDisableStatusIndicatorAnimationsForTesting = false);
+    public static void setDisableTopControlsAnimationsForTesting(boolean disable) {
+        sDisableTopControlsAnimationForTesting = disable;
+        ResettersForTesting.register(() -> sDisableTopControlsAnimationForTesting = false);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
index 01814e1..855ed42b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -306,6 +306,8 @@
     private OverlayPanelManagerObserver mOverlayPanelManagerObserver;
     private ObservableSupplierImpl<Boolean> mOverlayPanelVisibilitySupplier =
             new ObservableSupplierImpl<>();
+    private final ObservableSupplierImpl<Integer> mTabStripHeightSupplier =
+            new ObservableSupplierImpl<>();
 
     private TabGroupUi mTabGroupUi;
 
@@ -681,7 +683,6 @@
                 initializeWithIncognitoColors, startSurfaceLogoClickedCallback, mConstraintsProxy);
         mActionModeController =
                 new ActionModeController(mActivity, mActionBarDelegate, toolbarActionModeCallback);
-
         mActionModeController.setTabStripHeight(mToolbar.getTabStripHeight());
 
         tabObscuringHandler.addObserver(this);
@@ -1533,6 +1534,7 @@
                 newTabClickHandler, bookmarkClickHandler, customTabsBackClickHandler,
                 mAppMenuDelegate, layoutManager, mActivityTabProvider, mBrowserControlsSizer,
                 mTopUiThemeColorProvider);
+        mTabStripHeightSupplier.set(mToolbar.getTabStripHeight());
 
         mAttachStateChangeListener = new OnAttachStateChangeListener() {
             @Override
@@ -1555,6 +1557,12 @@
         if (stripLayoutHelperManager != null) {
             mControlContainer.setToolbarContainerDragListener(
                     stripLayoutHelperManager.getDragListener());
+            stripLayoutHelperManager.setIsTabStripHidden(mToolbar.getTabStripHeight() == 0);
+            mToolbar.addTabStripHeightObserver(
+                    newHeight -> {
+                        mTabStripHeightSupplier.set(newHeight);
+                        stripLayoutHelperManager.setIsTabStripHidden(newHeight == 0);
+                    });
         }
 
         if (mMenuStateObserver != null) {
@@ -1891,6 +1899,11 @@
         mUrlFocusChangedCallback.onResult(hasFocus);
     }
 
+    /** Get the supplier for the current height of the tab strip. */
+    public ObservableSupplier<Integer> getTabStripHeightSupplier() {
+        return mTabStripHeightSupplier;
+    }
+
     /**
      * Updates the primary color used by the model to the given color.
      * @param color The primary color for the current tab.
@@ -1962,8 +1975,12 @@
     private int getToolbarExtraYOffset() {
         int toolbarHairlineHeight =
                 mControlContainer.findViewById(R.id.toolbar_hairline).getHeight();
-        return mBrowserControlsSizer.getTopControlsHeight()
-                - (mControlContainer.getHeight() - toolbarHairlineHeight);
+        int extraYOffset =
+                mBrowserControlsSizer.getTopControlsHeight()
+                        - (mControlContainer.getHeight() - toolbarHairlineHeight);
+        // There are cases where extraYOffset can be negative e.g. during tab strip transitioning
+        // from invisible -> visible.
+        return Math.max(0, extraYOffset);
     }
 
     /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java
index 7bb1003..adef0e4 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java
@@ -1375,10 +1375,6 @@
 
         if (activeModel.isIncognito() == incognito) {
             Assert.assertEquals("TabStrip is not in the right visible state", strip, activeStrip);
-            Assert.assertEquals(
-                    "TabStrip does not have the same number of views as the model",
-                    strip.getTabCount(),
-                    model.getCount());
         } else {
             Assert.assertTrue("TabStrip is not in the right visible state", model != activeModel);
         }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/WebsitePreferenceBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/WebsitePreferenceBridgeTest.java
index 4bbebdb..6fa36d5 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/WebsitePreferenceBridgeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/WebsitePreferenceBridgeTest.java
@@ -6,8 +6,6 @@
 
 import static org.junit.Assert.assertEquals;
 
-import static org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge.SITE_WILDCARD;
-
 import androidx.test.filters.SmallTest;
 
 import org.junit.After;
@@ -15,11 +13,6 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
-import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
-import org.chromium.base.test.params.ParameterProvider;
-import org.chromium.base.test.params.ParameterSet;
-import org.chromium.base.test.params.ParameterizedRunner;
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CommandLineFlags;
@@ -29,7 +22,7 @@
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.test.ChromeBrowserTestRule;
-import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.browser_ui.site_settings.WebsitePreferenceBridge;
 import org.chromium.components.content_settings.ContentSettingValues;
 import org.chromium.components.content_settings.ContentSettingsType;
@@ -37,28 +30,15 @@
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.url.GURL;
 
-import java.util.Arrays;
-import java.util.List;
 import java.util.concurrent.TimeoutException;
 
 /** Tests for WebsitePreferenceBridgeTest. */
-@RunWith(ParameterizedRunner.class)
-@UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
+@RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
 @Batch(Batch.PER_CLASS)
 public class WebsitePreferenceBridgeTest {
     @Rule public final ChromeBrowserTestRule mBrowserTestRule = new ChromeBrowserTestRule();
 
-    /** Class to parameterize the params for {@link }. */
-    public static class EmbargoedParams implements ParameterProvider {
-        @Override
-        public List<ParameterSet> getParameters() {
-            return Arrays.asList(
-                    new ParameterSet().value(true).name("Embargoed"),
-                    new ParameterSet().value(false).name("Normal"));
-        }
-    }
-
     @After
     public void tearDown() throws TimeoutException {
         // Clean up content settings.
@@ -97,51 +77,4 @@
                                     browserContext, ContentSettingsType.JAVASCRIPT, url, url));
                 });
     }
-
-    @Test
-    @SmallTest
-    @UseMethodParameter(EmbargoedParams.class)
-    public void testModifyContentSettingsCustomScope(boolean isEmbargoed) {
-
-        TestThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    BrowserContextHandle browserContext = Profile.getLastUsedRegularProfile();
-                    String primary = "https://primary.com";
-                    String secondary = isEmbargoed ? SITE_WILDCARD : "https://secondary.com";
-                    assertEquals(
-                            ContentSettingValues.ASK,
-                            WebsitePreferenceBridge.getContentSetting(
-                                    browserContext,
-                                    ContentSettingsType.STORAGE_ACCESS,
-                                    new GURL(primary),
-                                    new GURL(secondary)));
-                    WebsitePreferenceBridge.setContentSettingCustomScope(
-                            browserContext,
-                            ContentSettingsType.STORAGE_ACCESS,
-                            primary,
-                            secondary,
-                            ContentSettingValues.ALLOW);
-                    assertEquals(
-                            ContentSettingValues.ALLOW,
-                            WebsitePreferenceBridge.getContentSetting(
-                                    browserContext,
-                                    ContentSettingsType.STORAGE_ACCESS,
-                                    new GURL(primary),
-                                    new GURL(secondary)));
-                });
-    }
-
-    @SmallTest
-    @Test(expected = AssertionError.class)
-    public void testFailModifyContentSettingsCustomScope() {
-        BrowserContextHandle browserContext = Profile.getLastUsedRegularProfile();
-        String primary = SITE_WILDCARD;
-        String secondary = "https://secondary.com";
-        WebsitePreferenceBridge.setContentSettingCustomScope(
-                browserContext,
-                ContentSettingsType.STORAGE_ACCESS,
-                primary,
-                secondary,
-                ContentSettingValues.BLOCK);
-    }
 }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java
index 21ed9ae..6200ba8 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/status_indicator/StatusIndicatorTest.java
@@ -73,7 +73,7 @@
 
     @Before
     public void setUp() throws InterruptedException {
-        TabbedRootUiCoordinator.setDisableStatusIndicatorAnimationsForTesting(true);
+        TabbedRootUiCoordinator.setDisableTopControlsAnimationsForTesting(true);
         mActivityTestRule.startMainActivityOnBlankPage();
         mStatusIndicatorCoordinator =
                 ((TabbedRootUiCoordinator)
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java
index 54c90a5..caaf93202 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/ToolbarTest.java
@@ -48,6 +48,8 @@
 import org.chromium.chrome.browser.layouts.LayoutTestUtils;
 import org.chromium.chrome.browser.layouts.LayoutType;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tabbed_mode.TabbedRootUiCoordinator;
+import org.chromium.chrome.browser.toolbar.top.TabStripTransitionCoordinator;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.R;
@@ -74,6 +76,7 @@
 
     @Before
     public void setUp() throws InterruptedException {
+        TabbedRootUiCoordinator.setDisableTopControlsAnimationsForTesting(true);
         mActivityTestRule.startMainActivityOnBlankPage();
     }
 
@@ -243,4 +246,40 @@
                             Matchers.is(true));
                 });
     }
+
+    @Test
+    @MediumTest
+    @EnableFeatures(ChromeFeatureList.DYNAMIC_TOP_CHROME)
+    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
+    public void testToggleTabStripVisibility() {
+        ChromeTabbedActivity activity = mActivityTestRule.getActivity();
+        int tabStripHeightResource =
+                activity.getResources().getDimensionPixelSize(R.dimen.tab_strip_height);
+        checkTabStripHeightOnUiThread(tabStripHeightResource);
+
+        // Set the screen width bucket and trigger an configuration change to force toggle tab strip
+        // visibility. This is an test only strategy, as we don't want to vastly change the
+        // configuration which might result in an activity restart.
+        TabStripTransitionCoordinator.setMinScreenWidthForTesting(Integer.MAX_VALUE);
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> activity.onConfigurationChanged(new Configuration()));
+        checkTabStripHeightOnUiThread(0);
+
+        TabStripTransitionCoordinator.setMinScreenWidthForTesting(599);
+        TestThreadUtils.runOnUiThreadBlocking(
+                () -> activity.onConfigurationChanged(new Configuration()));
+        checkTabStripHeightOnUiThread(tabStripHeightResource);
+    }
+
+    private void checkTabStripHeightOnUiThread(int tabStripHeight) {
+        ChromeTabbedActivity activity = mActivityTestRule.getActivity();
+        CriteriaHelper.pollUiThread(
+                () -> {
+                    Criteria.checkThat(activity.getToolbarManager(), Matchers.notNullValue());
+                    Criteria.checkThat(
+                            "Tab strip height is different",
+                            activity.getToolbarManager().getTabStripHeightSupplier().get(),
+                            Matchers.equalTo(tabStripHeight));
+                });
+    }
 }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
index d1d4413..ce91758 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
@@ -2908,27 +2908,6 @@
     @Test
     @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID)
     @Config(sdk = Build.VERSION_CODES.R)
-    public void testDrag_selectTabAtIndex_success() {
-        // Setup with 10 tabs and select first tab.
-        int selectedTabIndex = 0;
-        setTabDragSourceMock();
-        initializeTest(false, false, false, selectedTabIndex, 10);
-
-        // Act and verify.
-        assertTrue(
-                "The initial selected tab index should be " + selectedTabIndex + ".",
-                mStripLayoutHelper.getCurrentTabIndexForTesting() == selectedTabIndex);
-        int nextSelectedTabIndex = 5;
-        mStripLayoutHelper.selectTabAtIndex(nextSelectedTabIndex);
-        assertTrue(
-                "The selected tab index should now be " + nextSelectedTabIndex + ".",
-                mStripLayoutHelper.getCurrentTabIndexForTesting() == nextSelectedTabIndex);
-
-    }
-
-    @Test
-    @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID)
-    @Config(sdk = Build.VERSION_CODES.R)
     public void testDrag_sendMoveWindowBroadcast_success() {
         // Setup with tabs and select first tab.
         setTabDragSourceMock();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java
index 24839e1..edafedd0 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/TabDragSourceTest.java
@@ -50,6 +50,8 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.tab.MockTab;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tabmodel.TabModelSelector;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
@@ -76,6 +78,8 @@
     @Mock private BrowserControlsStateProvider mBrowserControlsStateProvider;
     @Mock private StripLayoutHelper mStripLayoutHelper;
     @Mock private Profile mProfile;
+    @Mock private TabModelSelector mTabModelSelector;
+    @Mock private TestTabModel mTabModel;
 
     private Activity mActivity;
     private TabDragSource mTabDragSource;
@@ -109,6 +113,8 @@
                         mMultiInstanceManager,
                         mDragDropDelegate,
                         mBrowserControlsStateProvider);
+        when(mTabModelSelector.getCurrentModel()).thenReturn(mTabModel);
+        mTabDragSource.setTabModelSelector(mTabModelSelector);
     }
 
     @After
@@ -331,7 +337,7 @@
         when(mMultiInstanceManager.getCurrentInstanceId()).thenReturn(CURR_INSTANCE_ID + 1);
         // Mock strip actions.
         when(mStripLayoutHelper.getTabAtPosition(POS_X)).thenReturn(null);
-        when(mStripLayoutHelper.getTabCount()).thenReturn(10);
+        when(mTabModel.getCount()).thenReturn(10);
 
         // Trigger drop in tab strip.
         triggerDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY);
@@ -362,6 +368,34 @@
     }
 
     @Test
+    public void test_DropInDestinationWithDifferentModel_MoveTabToDestinationAtEnd() {
+        // Set selector
+        mTabDragSource.setTabModelSelector(mTabModelSelector);
+        // Set state - tab created in standard model.
+        mTabDragSource.setGlobalState(mTabBeingDragged);
+        // Simulate destination instance.
+        when(mMultiInstanceManager.getCurrentInstanceId()).thenReturn(CURR_INSTANCE_ID + 1);
+        // Destination tab model is incognito.
+        when(mTabModel.isIncognito()).thenReturn(true);
+        TabModel standardModelDestination = mock(TabModel.class);
+        when(mTabModelSelector.getModel(false)).thenReturn(standardModelDestination);
+        when(standardModelDestination.getCount()).thenReturn(5);
+
+        // Mock strip actions - tab exists at drop position.
+        StripLayoutTab stripTab = mock(StripLayoutTab.class);
+        when(mStripLayoutHelper.getTabAtPosition(POS_X)).thenReturn(stripTab);
+
+        // Trigger drop in tab strip.
+        triggerDragEvent(DragEvent.ACTION_DRAG_STARTED, POS_X, mPosY);
+        triggerDragEvent(DragEvent.ACTION_DROP, POS_X, mPosY);
+        triggerDragEvent(DragEvent.ACTION_DRAG_ENDED, POS_X, mPosY);
+
+        // Verify - Tab moved to destination window at end.
+        verify(mMultiInstanceManager, times(1)).moveTabToWindow(any(), eq(mTabBeingDragged), eq(5));
+        verify(mMultiInstanceManager, times(0)).moveTabToNewWindow(mTabBeingDragged);
+    }
+
+    @Test
     @EnableFeatures(ChromeFeatureList.TAB_DRAG_DROP_ANDROID)
     @DisableFeatures(ChromeFeatureList.TAB_LINK_DRAG_DROP_ANDROID)
     public void test_onProvideShadowMetrics_WithDesiredStartPosition_ReturnsSuccess() {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31UnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31UnitTest.java
index 74741c5..13752ae 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31UnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/multiwindow/MultiInstanceManagerApi31UnitTest.java
@@ -881,8 +881,9 @@
     }
 
     private int allocInstanceIndex(int passedId, Activity activity, boolean preferNew) {
-        int index =
+        Pair<Integer, Integer> instanceIdInfo =
                 mMultiInstanceManager.allocInstanceId(passedId, activity.getTaskId(), preferNew);
+        int index = instanceIdInfo.first;
 
         // Does what TabModelOrchestrator.createTabModels() would do to simulate production code.
         Pair<Integer, TabModelSelector> pair =
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index eda957f..59d80bd 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -7679,6 +7679,9 @@
       <message name="IDS_NTP_CUSTOMIZE_YOUR_UPLOADED_IMAGE_LABEL" desc="The label for the 'Your uploaded image' button in the customization menu on the New Tab Page side panel.">
         Your uploaded image
       </message>
+      <message name="IDS_NTP_CUSTOMIZE_YOUR_SEARCHED_IMAGE_LABEL" desc="The label for the 'Your searched image' button in the customization menu on the New Tab Page side panel." translateable="false">
+        Your searched image
+      </message>
       <message name="IDS_NTP_CUSTOMIZE_UPLOAD_FROM_DEVICE_LABEL" desc="The label for the 'Upload from device' tile in the customization menu on the New Tab Page">
         Upload from device
       </message>
@@ -16486,6 +16489,14 @@
     <message name="IDS_IWA_INSTALLER_VERIFICATION_ERROR_SUBTITLE" desc="Subtitle of an error popup during the verification step of the Isolated Web App installer">
       This bundle might be broken or compromised. Please close this window and download it again
     </message>
+
+    <!-- Common WebUI elements. -->
+    <message name="IDS_THUMBS_DOWN" desc="Accessibility label for a thumbs down icon that a user can click to provide negative feedback about a feature." translateable="false">
+      Thumbs down
+    </message>
+    <message name="IDS_THUMBS_UP" desc="Accessibility label for a thumbs up icon that a user can click to provide positive feedback about a feature." translateable="false">
+      Thumbs up
+    </message>
   </messages>
 </release>
 </grit>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 1143ca80..e16be62f 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -7422,6 +7422,11 @@
      flag_descriptions::kReadAnythingWebUIToolbarDescription, kOsDesktop,
      FEATURE_VALUE_TYPE(features::kReadAnythingWebUIToolbar)},
 
+    {"read-anything-omnibox-icon",
+     flag_descriptions::kReadAnythingOmniboxIconName,
+     flag_descriptions::kReadAnythingOmniboxIconDescription, kOsDesktop,
+     FEATURE_VALUE_TYPE(features::kReadAnythingOmniboxIcon)},
+
     {"support-tool", flag_descriptions::kSupportTool,
      flag_descriptions::kSupportToolDescription, kOsDesktop,
      FEATURE_VALUE_TYPE(features::kSupportTool)},
@@ -8854,6 +8859,12 @@
      flag_descriptions::kEnableRedInterstitialFaceliftDescription, kOsAll,
      FEATURE_VALUE_TYPE(safe_browsing::kRedInterstitialFacelift)},
 
+    {"enable-suspicious-site-detection-rt-lookups",
+     flag_descriptions::kEnableSuspiciousSiteDetectionRTLookupsName,
+     flag_descriptions::kEnableSuspiciousSiteDetectionRTLookupsDescription,
+     kOsDesktop | kOsAndroid,
+     FEATURE_VALUE_TYPE(safe_browsing::kSuspiciousSiteDetectionRTLookups)},
+
     {"enable-tailored-security-retry-for-sync-users",
      flag_descriptions::kTailoredSecurityRetryForSyncUsersName,
      flag_descriptions::kTailoredSecurityRetryForSyncUsersDescription, kOsAll,
@@ -11311,6 +11322,11 @@
      FEATURE_VALUE_TYPE(chrome::android::kBoardingPassDetector)},
 #endif  // BUILDFLAG(IS_ANDROID)
 
+    {"autofill-enable-card-benefits",
+     flag_descriptions::kAutofillEnableCardBenefitsName,
+     flag_descriptions::kAutofillEnableCardBenefitsDescription, kOsAll,
+     FEATURE_VALUE_TYPE(autofill::features::kAutofillEnableCardBenefits)},
+
     // NOTE: Adding a new flag requires adding a corresponding entry to enum
     // "LoginCustomFlags" in tools/metrics/histograms/enums.xml. See "Flag
     // Histograms" in tools/metrics/histograms/README.md (run the
diff --git a/chrome/browser/apps/app_service/launch_utils.cc b/chrome/browser/apps/app_service/launch_utils.cc
index 31700cd..ebb84a5 100644
--- a/chrome/browser/apps/app_service/launch_utils.cc
+++ b/chrome/browser/apps/app_service/launch_utils.cc
@@ -327,6 +327,7 @@
     case LaunchSource::kFromReparenting:
     case LaunchSource::kFromProfileMenu:
     case LaunchSource::kFromSysTrayCalendar:
+    case LaunchSource::kFromInstaller:
       return extensions::AppLaunchSource::kSourceNone;
   }
 }
diff --git a/chrome/browser/apps/app_service/metrics/app_service_metrics.cc b/chrome/browser/apps/app_service/metrics/app_service_metrics.cc
index 41e72c2..8249d125 100644
--- a/chrome/browser/apps/app_service/metrics/app_service_metrics.cc
+++ b/chrome/browser/apps/app_service/metrics/app_service_metrics.cc
@@ -152,6 +152,10 @@
       base::UmaHistogramEnumeration("Apps.DefaultAppLaunch.FromSysTrayCalendar",
                                     default_app_name);
       break;
+    case apps::LaunchSource::kFromInstaller:
+      base::UmaHistogramEnumeration("Apps.DefaultAppLaunch.FromInstaller",
+                                    default_app_name);
+      break;
     case apps::LaunchSource::kFromCommandLine:
     case apps::LaunchSource::kFromBackgroundMode:
     case apps::LaunchSource::kFromAppHomePage:
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_base.cc b/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
index d6092db7..a9f6b1b 100644
--- a/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
+++ b/chrome/browser/apps/app_service/publishers/extension_apps_base.cc
@@ -349,6 +349,7 @@
     case apps::LaunchSource::kFromReparenting:
     case apps::LaunchSource::kFromProfileMenu:
     case apps::LaunchSource::kFromSysTrayCalendar:
+    case apps::LaunchSource::kFromInstaller:
       break;
   }
 
diff --git a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
index 75afe98..ff9d301 100644
--- a/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
+++ b/chrome/browser/apps/app_service/publishers/extension_apps_chromeos.cc
@@ -170,6 +170,7 @@
     case apps::LaunchSource::kFromReparenting:
     case apps::LaunchSource::kFromProfileMenu:
     case apps::LaunchSource::kFromSysTrayCalendar:
+    case apps::LaunchSource::kFromInstaller:
       return ash::LAUNCH_FROM_UNKNOWN;
   }
 }
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 1978a85..0c901a4 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -1924,6 +1924,25 @@
             unattached_guest->web_contents()->GetResponsibleWebContents());
 }
 
+// Creates a guest in a unattached state, then confirms that calling
+// the various view methods return null.
+IN_PROC_BROWSER_TEST_P(WebViewNewWindowTest,
+                       NewWindow_UnattachedVerifyViewMethods) {
+  TestHelper("testNewWindowDeferredAttachmentIndefinitely",
+             "web_view/newwindow", NEEDS_TEST_SERVER);
+  GetGuestViewManager()->WaitForNumGuestsCreated(2);
+
+  content::WebContents* embedder = GetEmbedderWebContents();
+  auto* unattached_guest = GetGuestViewManager()->GetLastGuestViewCreated();
+  ASSERT_TRUE(unattached_guest);
+  ASSERT_EQ(embedder, unattached_guest->owner_web_contents());
+  ASSERT_FALSE(unattached_guest->attached());
+  ASSERT_FALSE(unattached_guest->embedder_web_contents());
+  ASSERT_FALSE(unattached_guest->web_contents()->GetNativeView());
+  ASSERT_FALSE(unattached_guest->web_contents()->GetContentNativeView());
+  ASSERT_FALSE(unattached_guest->web_contents()->GetTopLevelNativeWindow());
+}
+
 IN_PROC_BROWSER_TEST_F(WebViewTest, Shim_TestContentLoadEvent) {
   TestHelper("testContentLoadEvent", "web_view/shim", NO_TEST_SERVER);
 }
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index f9b39a3e..12b6684 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -626,6 +626,8 @@
     "arc/tracing/arc_value_event.h",
     "arc/tracing/arc_value_event_trimmer.cc",
     "arc/tracing/arc_value_event_trimmer.h",
+    "arc/tracing/present_frames_tracer.cc",
+    "arc/tracing/present_frames_tracer.h",
     "arc/tts/arc_tts_service.cc",
     "arc/tts/arc_tts_service.h",
     "arc/user_session/arc_user_session_service.cc",
@@ -1377,6 +1379,8 @@
     "geolocation/system_geolocation_source.h",
     "growth/campaigns_manager_client_impl.cc",
     "growth/campaigns_manager_client_impl.h",
+    "growth/install_web_app_action_performer.cc",
+    "growth/install_web_app_action_performer.h",
     "guest_os/guest_id.cc",
     "guest_os/guest_id.h",
     "guest_os/guest_os_diagnostics_builder.cc",
@@ -5468,6 +5472,7 @@
     "game_mode/testing/game_mode_controller_test_base.h",
     "geolocation/system_geolocation_source_unittest.cc",
     "growth/campaigns_manager_client_unittest.cc",
+    "growth/install_web_app_action_unittest.cc",
     "guest_os/guest_id_unittest.cc",
     "guest_os/guest_os_diagnostics_builder_unittest.cc",
     "guest_os/guest_os_dlc_helper_unittest.cc",
diff --git a/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.cc b/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.cc
index 66e51125..3aaca70 100644
--- a/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.cc
+++ b/chrome/browser/ash/app_list/app_service/app_service_promise_app_icon_loader.cc
@@ -62,7 +62,7 @@
     return;
   }
   CallLoadIcon(apps::PackageId::FromString(id).value(),
-               apps::IconEffects::kCrOsStandardMask);
+               apps::IconEffects::kCrOsStandardIcon);
 }
 
 void AppServicePromiseAppIconLoader::ClearImage(const std::string& id) {
diff --git a/chrome/browser/ash/app_list/app_service/app_service_promise_app_item.cc b/chrome/browser/ash/app_list/app_service/app_service_promise_app_item.cc
index fadc4a5..f603d3e4 100644
--- a/chrome/browser/ash/app_list/app_service/app_service_promise_app_item.cc
+++ b/chrome/browser/ash/app_list/app_service/app_service_promise_app_item.cc
@@ -84,7 +84,7 @@
   apps::AppServiceProxyFactory::GetForProfile(profile())->LoadPromiseIcon(
       package_id_,
       ash::SharedAppListConfig::instance().default_grid_icon_dimension(),
-      apps::IconEffects::kCrOsStandardMask,
+      apps::IconEffects::kCrOsStandardIcon,
       base::BindOnce(&AppServicePromiseAppItem::OnLoadIcon,
                      weak_ptr_factory_.GetWeakPtr()));
 }
diff --git a/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.cc b/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.cc
index 79ce2013..72ca3bd 100644
--- a/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.cc
+++ b/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.cc
@@ -29,6 +29,7 @@
 #include "chrome/browser/ash/arc/tracing/arc_tracing_event.h"
 #include "chrome/browser/ash/arc/tracing/arc_tracing_event_matcher.h"
 #include "chrome/browser/ash/arc/tracing/arc_tracing_model.h"
+#include "chrome/browser/ash/arc/tracing/present_frames_tracer.h"
 
 namespace arc {
 
@@ -441,24 +442,12 @@
   return task_id == other.task_id && activity == other.activity;
 }
 
-TraceTimestamps::TraceTimestamps() = default;
-
-TraceTimestamps::~TraceTimestamps() = default;
-
-void TraceTimestamps::AddCommit(base::TimeTicks commit_ts) {
-  commits.emplace_back((commit_ts - base::TimeTicks()).InMicroseconds());
-}
-
-void TraceTimestamps::AddPresent(base::TimeTicks present_ts) {
-  presents.emplace_back((present_ts - base::TimeTicks()).InMicroseconds());
-}
-
 ArcTracingGraphicsModel::ArcTracingGraphicsModel() = default;
 
 ArcTracingGraphicsModel::~ArcTracingGraphicsModel() = default;
 
 bool ArcTracingGraphicsModel::Build(const ArcTracingModel& common_model,
-                                    const TraceTimestamps& timestamps) {
+                                    const PresentFramesTracer& present_frames) {
   Reset();
 
   // TODO(b/296595454): Remove the mapping mechanism as it was only needed
@@ -471,10 +460,10 @@
   auto& buffer_events =
       view_buffers_[ViewId(1 /* task_id */, kUnknownActivity)].buffer_events();
   buffer_events.emplace_back();
-  for (int64_t ticks : timestamps.commits) {
+  for (int64_t ticks : present_frames.commits()) {
     buffer_events[0].emplace_back(EventType::kExoSurfaceCommit, ticks);
   }
-  for (int64_t ticks : timestamps.presents) {
+  for (int64_t ticks : present_frames.presents()) {
     chrome_top_level_.global_events().emplace_back(
         EventType::kChromeOSPresentationDone, ticks);
   }
diff --git a/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.h b/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.h
index e9848b9..b3a1f2b 100644
--- a/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.h
+++ b/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.h
@@ -5,10 +5,7 @@
 #ifndef CHROME_BROWSER_ASH_ARC_TRACING_ARC_TRACING_GRAPHICS_MODEL_H_
 #define CHROME_BROWSER_ASH_ARC_TRACING_ARC_TRACING_GRAPHICS_MODEL_H_
 
-#include <deque>
 #include <map>
-#include <memory>
-#include <set>
 #include <string>
 #include <vector>
 
@@ -19,22 +16,7 @@
 namespace arc {
 
 class ArcTracingModel;
-
-// Timestamps in tick counts (ms) accumulated over the course of a trace. Backed
-// by deques to give O(1) non-amortized insertion time.
-struct TraceTimestamps {
-  TraceTimestamps();
-  ~TraceTimestamps();
-
-  // Prevent accidental copying.
-  TraceTimestamps(const TraceTimestamps&) = delete;
-  TraceTimestamps& operator=(const TraceTimestamps&) = delete;
-
-  void AddCommit(base::TimeTicks commit_ts);
-  void AddPresent(base::TimeTicks present_ts);
-
-  std::deque<int64_t> commits, presents;
-};
+class PresentFramesTracer;
 
 // Graphic buffers events model. It is build from the generic |ArcTracingModel|
 // and contains only events that describe life-cycle of graphics buffers across
@@ -175,7 +157,7 @@
 
   // Builds the model from the common tracing model |common_model|.
   bool Build(const ArcTracingModel& common_model,
-             const TraceTimestamps& commits);
+             const PresentFramesTracer& present_frames);
 
   // Serializes the model to |base::Value::Dict|, this can be passed to
   // javascript for rendering.
diff --git a/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model_unittest.cc b/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model_unittest.cc
index 1de92b6..ad2f4b7 100644
--- a/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model_unittest.cc
+++ b/chrome/browser/ash/arc/tracing/arc_tracing_graphics_model_unittest.cc
@@ -7,6 +7,7 @@
 #include <initializer_list>
 
 #include "chrome/browser/ash/arc/tracing/arc_tracing_model.h"
+#include "chrome/browser/ash/arc/tracing/present_frames_tracer.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace arc {
@@ -17,12 +18,12 @@
 
   ArcTracingGraphicsModel model;
   ArcTracingModel common;
-  TraceTimestamps timestamps;
+  PresentFramesTracer present_frames;
 
   for (int commit_ts : kCommitsAbsoluteMs) {
-    timestamps.AddCommit(base::TimeTicks::FromUptimeMillis(commit_ts));
+    present_frames.AddCommit(base::TimeTicks::FromUptimeMillis(commit_ts));
   }
-  model.Build(common, std::move(timestamps));
+  model.Build(common, present_frames);
 
   ASSERT_EQ(model.view_buffers().size(), 1ul);
   auto& buffer_events = model.view_buffers().begin()->second.buffer_events();
diff --git a/chrome/browser/ash/arc/tracing/arc_tracing_model_unittest.cc b/chrome/browser/ash/arc/tracing/arc_tracing_model_unittest.cc
index 9c8cf5e..ce7da1a 100644
--- a/chrome/browser/ash/arc/tracing/arc_tracing_model_unittest.cc
+++ b/chrome/browser/ash/arc/tracing/arc_tracing_model_unittest.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/ash/arc/tracing/arc_tracing_event.h"
 #include "chrome/browser/ash/arc/tracing/arc_tracing_event_matcher.h"
 #include "chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.h"
+#include "chrome/browser/ash/arc/tracing/present_frames_tracer.h"
 #include "chrome/common/chrome_paths.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/zlib/google/compression_utils.h"
@@ -190,9 +191,9 @@
   // Continue in this test to avoid heavy calculations for building base model.
   // Make sure we can create graphics model.
   ArcTracingGraphicsModel graphics_model;
-  TraceTimestamps timestamps;
-  timestamps.AddCommit(base::TimeTicks::FromUptimeMillis(42));
-  ASSERT_TRUE(graphics_model.Build(model, timestamps));
+  PresentFramesTracer present_frames;
+  present_frames.AddCommit(base::TimeTicks::FromUptimeMillis(42));
+  ASSERT_TRUE(graphics_model.Build(model, present_frames));
 
   EXPECT_EQ(1U, graphics_model.chrome_top_level().buffer_events().size());
   for (const auto& chrome_top_level_band :
diff --git a/chrome/browser/ash/arc/tracing/present_frames_tracer.cc b/chrome/browser/ash/arc/tracing/present_frames_tracer.cc
new file mode 100644
index 0000000..c4b6c4a7
--- /dev/null
+++ b/chrome/browser/ash/arc/tracing/present_frames_tracer.cc
@@ -0,0 +1,37 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/arc/tracing/present_frames_tracer.h"
+
+#include "components/exo/surface.h"
+
+namespace arc {
+
+PresentFramesTracer::PresentFramesTracer() : weak_ptr_factory_(this) {}
+
+PresentFramesTracer::~PresentFramesTracer() = default;
+
+void PresentFramesTracer::AddCommit(base::TimeTicks commit_ts) {
+  commits_.emplace_back((commit_ts - base::TimeTicks()).InMicroseconds());
+}
+
+void PresentFramesTracer::ListenForPresent(exo::Surface* surface) {
+  surface->RequestPresentationCallback(
+      base::BindRepeating(&PresentFramesTracer::RecordPresentedFrame,
+                          weak_ptr_factory_.GetWeakPtr()));
+}
+
+void PresentFramesTracer::RecordPresentedFrame(
+    const gfx::PresentationFeedback& frame) {
+  if (frame.failed()) {
+    VLOG(5) << "Presentation failed";
+  } else if (frame.timestamp == base::TimeTicks()) {
+    VLOG(5) << "Discarded frame";
+  } else {
+    presents_.emplace_back(
+        (frame.timestamp - base::TimeTicks()).InMicroseconds());
+  }
+}
+
+}  // namespace arc
diff --git a/chrome/browser/ash/arc/tracing/present_frames_tracer.h b/chrome/browser/ash/arc/tracing/present_frames_tracer.h
new file mode 100644
index 0000000..f034e0e
--- /dev/null
+++ b/chrome/browser/ash/arc/tracing/present_frames_tracer.h
@@ -0,0 +1,53 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ASH_ARC_TRACING_PRESENT_FRAMES_TRACER_H_
+#define CHROME_BROWSER_ASH_ARC_TRACING_PRESENT_FRAMES_TRACER_H_
+
+#include <deque>
+
+#include "base/memory/weak_ptr.h"
+#include "base/time/time.h"
+#include "components/exo/surface_observer.h"
+#include "ui/gfx/presentation_feedback.h"
+
+namespace exo {
+class Surface;
+}  // namespace exo
+
+namespace arc {
+
+// Traces commits and, more importantly, frame presentation events, which
+// enables perceived FPS measurement.
+// Stores timestamps in tick counts (microseconds) accumulated over the course
+// of a trace. Backed by deques to give O(1) non-amortized insertion time.
+class PresentFramesTracer {
+ public:
+  PresentFramesTracer();
+  ~PresentFramesTracer();
+
+  // Prevent accidental copying.
+  PresentFramesTracer(const PresentFramesTracer&) = delete;
+  PresentFramesTracer& operator=(const PresentFramesTracer&) = delete;
+
+  // Record a commit as having occurred at the given time.
+  void AddCommit(base::TimeTicks commit_ts);
+
+  // Record the next frame presented event on the given surface. This can be
+  // called from within SurfaceObserver::OnCommit.
+  void ListenForPresent(exo::Surface* surface);
+
+  const std::deque<int64_t>& commits() const { return commits_; }
+  const std::deque<int64_t>& presents() const { return presents_; }
+
+ private:
+  void RecordPresentedFrame(const gfx::PresentationFeedback& frame);
+
+  std::deque<int64_t> commits_, presents_;
+  base::WeakPtrFactory<PresentFramesTracer> weak_ptr_factory_;
+};
+
+}  // namespace arc
+
+#endif  // CHROME_BROWSER_ASH_ARC_TRACING_PRESENT_FRAMES_TRACER_H_
diff --git a/chrome/browser/ash/growth/campaigns_manager_client_impl.cc b/chrome/browser/ash/growth/campaigns_manager_client_impl.cc
index a742a35..6188534 100644
--- a/chrome/browser/ash/growth/campaigns_manager_client_impl.cc
+++ b/chrome/browser/ash/growth/campaigns_manager_client_impl.cc
@@ -11,6 +11,7 @@
 #include "base/files/file_path.h"
 #include "base/no_destructor.h"
 #include "base/version.h"
+#include "chrome/browser/ash/growth/install_web_app_action_performer.h"
 #include "chrome/browser/ash/login/demo_mode/demo_components.h"
 #include "chrome/browser/ash/login/demo_mode/demo_mode_dimensions.h"
 #include "chrome/browser/ash/login/demo_mode/demo_session.h"
@@ -88,6 +89,14 @@
   return version.value();
 }
 
+growth::ActionMap CampaignsManagerClientImpl::GetCampaignsActions() const {
+  growth::ActionMap action_map;
+  action_map.emplace(
+      make_pair(growth::ActionType::kInstallWebApp,
+                std::make_unique<InstallWebAppActionPerformer>()));
+  return action_map;
+}
+
 void CampaignsManagerClientImpl::OnComponentDownloaded(
     growth::CampaignComponentLoadedCallback loaded_callback,
     component_updater::CrOSComponentManager::Error error,
diff --git a/chrome/browser/ash/growth/campaigns_manager_client_impl.h b/chrome/browser/ash/growth/campaigns_manager_client_impl.h
index ebd7cd62..87647d79 100644
--- a/chrome/browser/ash/growth/campaigns_manager_client_impl.h
+++ b/chrome/browser/ash/growth/campaigns_manager_client_impl.h
@@ -35,6 +35,7 @@
   bool IsFeatureAwareDevice() const override;
   const std::string& GetApplicationLocale() const override;
   const base::Version& GetDemoModeAppVersion() const override;
+  growth::ActionMap GetCampaignsActions() const override;
 
  private:
   void OnComponentDownloaded(
diff --git a/chrome/browser/ash/growth/install_web_app_action_performer.cc b/chrome/browser/ash/growth/install_web_app_action_performer.cc
new file mode 100644
index 0000000..e4e4eff
--- /dev/null
+++ b/chrome/browser/ash/growth/install_web_app_action_performer.cc
@@ -0,0 +1,150 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/growth/install_web_app_action_performer.h"
+
+#include "base/functional/bind.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h"
+#include "chrome/browser/web_applications/web_app_command_scheduler.h"
+#include "chrome/browser/web_applications/web_app_constants.h"
+#include "chrome/browser/web_applications/web_app_install_info.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "components/services/app_service/public/cpp/icon_info.h"
+#include "components/webapps/browser/install_result_code.h"
+#include "components/webapps/browser/installable/installable_metrics.h"
+
+namespace {
+
+inline constexpr char kInstallWebAppParams[] = "installWebAppParams";
+inline constexpr char kLaunchInStandaloneWindow[] = "launchInStandaloneWindow";
+inline constexpr char kAppTitle[] = "appTitle";
+inline constexpr char kUrl[] = "url";
+inline constexpr char kIconUrl[] = "iconPath";
+
+std::unique_ptr<web_app::WebAppInstallInfo> GetAppInstallInfo(
+    const base::Value::Dict& entry) {
+  absl::optional<bool> launch_in_standalone_window =
+      entry.FindBool(kLaunchInStandaloneWindow);
+  auto* app_title = entry.FindString(kAppTitle);
+  auto* url = entry.FindString(kUrl);
+  auto* icon_url = entry.FindString(kIconUrl);
+
+  // Ensure that the required fields are present.
+  if (!launch_in_standalone_window.has_value() || !app_title || !url) {
+    return nullptr;
+  }
+
+  GURL url_parsed = GURL(*url);
+  if (!url_parsed.is_valid()) {
+    return nullptr;
+  }
+
+  auto info = std::make_unique<web_app::WebAppInstallInfo>(url_parsed);
+  info->start_url = url_parsed;
+  info->title = base::UTF8ToUTF16(*app_title);
+  if (icon_url && GURL(*icon_url).is_valid()) {
+    info->manifest_icons.push_back(apps::IconInfo(GURL(*icon_url), 32));
+  }
+
+  info->display_mode = launch_in_standalone_window.value()
+                           ? blink::mojom::DisplayMode::kStandalone
+                           : blink::mojom::DisplayMode::kBrowser;
+  return info;
+}
+
+std::unique_ptr<web_app::WebAppInstallInfo>
+ParseInstallWebAppActionPerformerParams(const base::Value::Dict* params) {
+  if (!params) {
+    LOG(ERROR) << "Empty parameter to InstallWebAction.";
+    return nullptr;
+  }
+
+  auto* install_params = params->FindDict(kInstallWebAppParams);
+  if (!install_params) {
+    LOG(ERROR) << kInstallWebAppParams << " parameter not found.";
+    return nullptr;
+  }
+
+  return GetAppInstallInfo(*install_params);
+}
+
+void InstallWebAppResult(growth::ActionPerformer::Callback callback,
+                         const std::string& app_id,
+                         webapps::InstallResultCode code) {
+  const std::array<webapps::InstallResultCode, 4> success_codes = {
+      webapps::InstallResultCode::kSuccessNewInstall,
+      webapps::InstallResultCode::kSuccessAlreadyInstalled,
+      webapps::InstallResultCode::kSuccessOfflineOnlyInstall,
+      webapps::InstallResultCode::kSuccessOfflineFallbackInstall};
+
+  if (std::find(success_codes.begin(), success_codes.end(), code) !=
+      success_codes.end()) {
+    std::move(callback).Run(growth::ActionResult::kSuccess,
+                            /* action_result_reason= */ absl::nullopt);
+    return;
+  }
+
+  // TODO(b/306023057): Record an UMA metric regarding why
+  // we were not able to successfully record the app.
+  std::move(callback).Run(
+      growth::ActionResult::kFailure,
+      growth::ActionResultReason::kWebAppInstallFailedOther);
+}
+
+void InstallWebAppImpl(web_app::WebAppProvider& provider,
+                       std::unique_ptr<web_app::WebAppInstallInfo> web_app_info,
+                       growth::ActionPerformer::Callback callback) {
+  provider.scheduler().InstallFromInfo(
+      std::move(web_app_info), /* overwrite_existing_manifest_fields= */ true,
+      webapps::WebappInstallSource::EXTERNAL_DEFAULT,
+      base::BindOnce(&InstallWebAppResult, std::move(callback)));
+}
+
+web_app::WebAppProvider* GetWebAppProvider() {
+  auto* profile = ProfileManager::GetPrimaryUserProfile();
+  return web_app::WebAppProvider::GetForWebApps(profile);
+}
+
+void TriggerWebAppInstall(std::unique_ptr<web_app::WebAppInstallInfo> info,
+                          growth::ActionPerformer::Callback callback) {
+  auto* provider = GetWebAppProvider();
+  CHECK(provider);
+  provider->on_registry_ready().Post(
+      FROM_HERE, base::BindOnce(InstallWebAppImpl, std::ref(*provider),
+                                std::move(info), std::move(callback)));
+}
+
+}  // namespace
+
+InstallWebAppActionPerformer::InstallWebAppActionPerformer() = default;
+InstallWebAppActionPerformer::~InstallWebAppActionPerformer() = default;
+
+void InstallWebAppActionPerformer::Run(
+    const base::Value::Dict* params,
+    growth::ActionPerformer::Callback callback) {
+  if (!GetWebAppProvider()) {
+    std::move(callback).Run(
+        growth::ActionResult::kFailure,
+        growth::ActionResultReason::kWebAppProviderNotAvailable);
+    return;
+  }
+
+  auto info = ParseInstallWebAppActionPerformerParams(params);
+  if (!info) {
+    // TODO(b/306023057): Record an UMA metric that parsing the params
+    // has failed.
+    std::move(callback).Run(growth::ActionResult::kFailure,
+                            growth::ActionResultReason::kParsingActionFailed);
+    return;
+  }
+
+  TriggerWebAppInstall(std::move(info), std::move(callback));
+}
+
+growth::ActionType InstallWebAppActionPerformer::ActionType() const {
+  return growth::ActionType::kInstallWebApp;
+}
diff --git a/chrome/browser/ash/growth/install_web_app_action_performer.h b/chrome/browser/ash/growth/install_web_app_action_performer.h
new file mode 100644
index 0000000..49f1a03
--- /dev/null
+++ b/chrome/browser/ash/growth/install_web_app_action_performer.h
@@ -0,0 +1,31 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ASH_GROWTH_INSTALL_WEB_APP_ACTION_PERFORMER_H_
+#define CHROME_BROWSER_ASH_GROWTH_INSTALL_WEB_APP_ACTION_PERFORMER_H_
+
+#include "base/functional/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "base/observer_list_types.h"
+#include "base/values.h"
+#include "chromeos/ash/components/growth/action_performer.h"
+#include "components/webapps/browser/install_result_code.h"
+
+// Implements Web App installation action for the growth framework.
+class InstallWebAppActionPerformer : public growth::ActionPerformer {
+ public:
+  InstallWebAppActionPerformer();
+  InstallWebAppActionPerformer(const InstallWebAppActionPerformer&) = delete;
+  InstallWebAppActionPerformer& operator=(const InstallWebAppActionPerformer&) =
+      delete;
+  ~InstallWebAppActionPerformer() override;
+
+  // growth::Action:
+  void Run(const base::Value::Dict* action_params,
+           growth::ActionPerformer::Callback callback) override;
+  growth::ActionType ActionType() const override;
+};
+
+#endif  // CHROME_BROWSER_ASH_GROWTH_INSTALL_WEB_APP_ACTION_PERFORMER_H_
diff --git a/chrome/browser/ash/growth/install_web_app_action_unittest.cc b/chrome/browser/ash/growth/install_web_app_action_unittest.cc
new file mode 100644
index 0000000..e770cbb0
--- /dev/null
+++ b/chrome/browser/ash/growth/install_web_app_action_unittest.cc
@@ -0,0 +1,189 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <memory>
+
+#include "base/json/json_reader.h"
+#include "base/test/bind.h"
+#include "chrome/browser/ash/growth/install_web_app_action_performer.h"
+#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/web_applications/test/fake_os_integration_manager.h"
+#include "chrome/browser/web_applications/test/fake_web_app_provider.h"
+#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/browser/web_applications/web_app_registrar.h"
+#include "chrome/common/chrome_constants.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_profile_manager.h"
+#include "components/user_manager/scoped_user_manager.h"
+#include "components/user_manager/user.h"
+#include "content/public/test/browser_task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace {
+constexpr char kTestProfileName[] = "user@gmail.com";
+
+constexpr char kAppInstallTemplate[] = R"(
+    {
+      "installWebAppParams": {
+          "appTitle": "Test App 1",
+          "%s": "%s",
+          "iconPath": "https://www.test.com/icon",
+          "launchInStandaloneWindow": true
+      }
+    }
+)";
+
+constexpr char kValidURL[] = "https://www.news.com";
+constexpr char kExpectedAppId[] = "pelbleffcebihhhneibojlacmlmlnjhm";
+constexpr char kInvalidURL[] = "www";
+constexpr char kValidURLKey[] = "url";
+constexpr char kInvalidURLKey[] = "urlInvalid";
+
+}  // namespace
+
+class InstallWebAppActionPerformerTest : public testing::Test {
+ public:
+  InstallWebAppActionPerformerTest() = default;
+  InstallWebAppActionPerformerTest(const InstallWebAppActionPerformerTest&) =
+      delete;
+  InstallWebAppActionPerformerTest& operator=(
+      const InstallWebAppActionPerformerTest&) = delete;
+  ~InstallWebAppActionPerformerTest() override = default;
+
+  void SetUp() override {
+    user_manager_.Reset(std::make_unique<ash::FakeChromeUserManager>());
+
+    profile_manager_ = std::make_unique<TestingProfileManager>(
+        TestingBrowserProcess::GetGlobal());
+    ASSERT_TRUE(profile_manager_->SetUp());
+
+    const user_manager::User* user =
+        user_manager_->AddUser(AccountId::FromUserEmail(kTestProfileName));
+    user_manager_->LoginUser(user->GetAccountId());
+    user_manager_->SwitchActiveUser(user->GetAccountId());
+
+    // Note that user profiles are created after user login in reality.
+    profile_ = profile_manager_->CreateTestingProfile(kTestProfileName);
+
+    auto* provider = web_app::FakeWebAppProvider::Get(profile_);
+    provider->SetOsIntegrationManager(
+        std::make_unique<web_app::FakeOsIntegrationManager>(
+            profile_,
+            /*app_shortcut_manager=*/nullptr,
+            /*file_handler_manager=*/nullptr,
+            /*protocol_handler_manager=*/nullptr,
+            /*url_handler_manager*/ nullptr));
+    web_app::test::AwaitStartWebAppProviderAndSubsystems(profile_);
+    install_action_ = std::make_unique<InstallWebAppActionPerformer>();
+  }
+
+  void TearDown() override {
+    profile_ = nullptr;
+    profile_manager_->DeleteAllTestingProfiles();
+    profile_manager_.reset();
+  }
+
+  bool EnsureWebAppInstalled(const std::string& url) {
+    apps_installed_run_loop_.Run();
+
+    // Let's verify that the pwa was installed.
+    web_app::WebAppProvider* provider =
+        web_app::WebAppProvider::GetForWebApps(profile_);
+
+    // note registrar_unsafe() is fine since we are just
+    // running a simple test here.
+    const auto& registrar = provider->registrar_unsafe();
+    return registrar.GetAppLaunchUrl(kExpectedAppId) == GURL(url);
+  }
+
+  bool EnsureAppsInstallActionFailed() {
+    action_failed_run_loop_.Run();
+    return true;
+  }
+
+  void InstallWebAppActionPerformerCallback(
+      growth::ActionResult result,
+      absl::optional<growth::ActionResultReason> reason) {
+    if (result == growth::ActionResult::kSuccess) {
+      std::move(app_installed_closure_).Run();
+    } else {
+      std::move(install_action_failed_closure_).Run();
+    }
+  }
+
+  InstallWebAppActionPerformer& action() { return *install_action_; }
+
+ private:
+  content::BrowserTaskEnvironment task_environment_;
+
+  base::RunLoop apps_installed_run_loop_;
+  base::RunLoop action_failed_run_loop_;
+
+  base::OnceClosure app_installed_closure_ =
+      apps_installed_run_loop_.QuitClosure();
+  base::OnceClosure install_action_failed_closure_ =
+      action_failed_run_loop_.QuitClosure();
+
+  raw_ptr<Profile> profile_ = nullptr;
+  user_manager::TypedScopedUserManager<ash::FakeChromeUserManager>
+      user_manager_;
+  std::unique_ptr<InstallWebAppActionPerformer> install_action_;
+  std::unique_ptr<TestingProfileManager> profile_manager_;
+};
+
+TEST_F(InstallWebAppActionPerformerTest, TestValidInstallation) {
+  const auto validInstallDictString =
+      base::StringPrintf(kAppInstallTemplate, kValidURLKey, kValidURL);
+  auto value = base::JSONReader::Read(validInstallDictString);
+  ASSERT_TRUE(value.has_value());
+  action().Run(&value->GetDict(),
+               base::BindOnce(&InstallWebAppActionPerformerTest::
+                                  InstallWebAppActionPerformerCallback,
+                              base::Unretained(this)));
+  EXPECT_TRUE(EnsureWebAppInstalled(kValidURL));
+}
+
+TEST_F(InstallWebAppActionPerformerTest, TestInvalidInstallationInvalidURL) {
+  const auto invalidInstallDictString =
+      base::StringPrintf(kAppInstallTemplate, kValidURLKey, kInvalidURL);
+  auto value = base::JSONReader::Read(invalidInstallDictString);
+  ASSERT_TRUE(value.has_value());
+
+  action().Run(&value->GetDict(),
+               base::BindOnce(&InstallWebAppActionPerformerTest::
+                                  InstallWebAppActionPerformerCallback,
+                              base::Unretained(this)));
+  EXPECT_TRUE(EnsureAppsInstallActionFailed());
+}
+
+TEST_F(InstallWebAppActionPerformerTest, TestInvalidUrlKey) {
+  const auto invalidInstallDictString =
+      base::StringPrintf(kAppInstallTemplate, kInvalidURLKey, kValidURL);
+  auto value = base::JSONReader::Read(invalidInstallDictString);
+  ASSERT_TRUE(value.has_value());
+
+  action().Run(&value->GetDict(),
+               base::BindOnce(&InstallWebAppActionPerformerTest::
+                                  InstallWebAppActionPerformerCallback,
+                              base::Unretained(this)));
+  EXPECT_TRUE(EnsureAppsInstallActionFailed());
+}
+
+TEST_F(InstallWebAppActionPerformerTest, InvalidRequest) {
+  constexpr char kInvalidParams[] = R"({
+      "invalidInstallWebAppParams" : {
+        "param" : "param"
+      }
+    })";
+  auto value = base::JSONReader::Read(kInvalidParams);
+  ASSERT_TRUE(value.has_value());
+  action().Run(&value->GetDict(),
+               base::BindOnce(&InstallWebAppActionPerformerTest::
+                                  InstallWebAppActionPerformerCallback,
+                              base::Unretained(this)));
+  EXPECT_TRUE(EnsureAppsInstallActionFailed());
+}
diff --git a/chrome/browser/ash/login/oobe_quick_start/second_device_auth_broker.cc b/chrome/browser/ash/login/oobe_quick_start/second_device_auth_broker.cc
index 400f3a79..1e231f4 100644
--- a/chrome/browser/ash/login/oobe_quick_start/second_device_auth_broker.cc
+++ b/chrome/browser/ash/login/oobe_quick_start/second_device_auth_broker.cc
@@ -14,7 +14,6 @@
 #include "base/functional/bind.h"
 #include "base/functional/callback_forward.h"
 #include "base/json/json_writer.h"
-#include "base/logging.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
@@ -26,6 +25,7 @@
 #include "chromeos/ash/components/attestation/attestation_flow.h"
 #include "chromeos/ash/components/dbus/attestation/keystore.pb.h"
 #include "chromeos/ash/components/dbus/constants/attestation_constants.h"
+#include "chromeos/ash/components/quick_start/logging.h"
 #include "chromeos/ash/components/quick_start/types.h"
 #include "components/account_id/account_id.h"
 #include "components/endpoint_fetcher/endpoint_fetcher.h"
@@ -220,8 +220,8 @@
 void HandleFetchChallengeBytesErrorResponse(
     SecondDeviceAuthBroker::ChallengeBytesCallback challenge_callback,
     std::unique_ptr<EndpointResponse> response) {
-  LOG(ERROR) << "Could not fetch challenge bytes. HTTP status code: "
-             << response->http_status_code;
+  QS_LOG(ERROR) << "Could not fetch challenge bytes. HTTP status code: "
+                << response->http_status_code;
   if (!response->error_type.has_value()) {
     std::move(challenge_callback)
         .Run(base::unexpected(
@@ -266,8 +266,9 @@
   switch (status) {
     case attestation::ATTESTATION_SUCCESS:
       if (pem_certificate_chain.empty()) {
-        LOG(ERROR) << "Got an empty certificate chain with a success response "
-                      "from attestation server";
+        QS_LOG(ERROR)
+            << "Got an empty certificate chain with a success response "
+               "from attestation server";
         std::move(callback).Run(base::unexpected(
             SecondDeviceAuthBroker::AttestationErrorType::kPermanentError));
         return;
@@ -383,8 +384,9 @@
       RefreshTokenRejectionResponse::Reason::kUnknownReason;
   std::string* rejection_reason = response->FindString(kRejectionReasonKey);
   if (!rejection_reason) {
-    LOG(ERROR) << "Could not fetch OAuth authorization code. Request rejected "
-                  "without providing a reason";
+    QS_LOG(ERROR)
+        << "Could not fetch OAuth authorization code. Request rejected "
+           "without providing a reason";
     std::move(refresh_token_callback).Run(rejection_response);
     return;
   }
@@ -392,8 +394,9 @@
   std::string rejection_reason_lowercase =
       base::ToLowerASCII(*rejection_reason);
   if (!kRejectionReasonErrorMap.contains(rejection_reason_lowercase)) {
-    LOG(ERROR) << "Could not fetch OAuth authorization code. Request rejected "
-                  "with unknown reason";
+    QS_LOG(ERROR)
+        << "Could not fetch OAuth authorization code. Request rejected "
+           "with unknown reason";
     std::move(refresh_token_callback).Run(rejection_response);
     return;
   }
@@ -413,8 +416,9 @@
   std::string* target_fallback_url =
       response->FindString(kTargetFallbackUrlKey);
   if (!target_fallback_url) {
-    LOG(ERROR) << "Could not fetch OAuth authorization code. Request required "
-                  "additional target challenges on unknown URL";
+    QS_LOG(ERROR)
+        << "Could not fetch OAuth authorization code. Request required "
+           "additional target challenges on unknown URL";
     std::move(refresh_token_callback)
         .Run(SecondDeviceAuthBroker::RefreshTokenParsingErrorResponse());
     return;
@@ -438,8 +442,9 @@
   std::string* source_device_fallback_url =
       response->FindString(kSourceDeviceFallbackUrlKey);
   if (!source_device_fallback_url) {
-    LOG(ERROR) << "Could not fetch OAuth authorization code. Request required "
-                  "additional source challenges on unknown URL";
+    QS_LOG(ERROR)
+        << "Could not fetch OAuth authorization code. Request required "
+           "additional source challenges on unknown URL";
     std::move(refresh_token_callback)
         .Run(SecondDeviceAuthBroker::RefreshTokenParsingErrorResponse());
     return;
@@ -478,8 +483,8 @@
     base::Value::Dict* response) {
   base::Value::Dict* credential_data = response->FindDict(kCredentialDataKey);
   if (!credential_data) {
-    LOG(ERROR) << "Could not fetch OAuth refresh token. Could not find "
-                  "credential_data";
+    QS_LOG(ERROR) << "Could not fetch OAuth refresh token. Could not find "
+                     "credential_data";
     std::move(refresh_token_callback)
         .Run(SecondDeviceAuthBroker::RefreshTokenParsingErrorResponse());
     return;
@@ -487,7 +492,7 @@
 
   std::string* auth_code = credential_data->FindString(kOauthTokenKey);
   if (!auth_code) {
-    LOG(ERROR)
+    QS_LOG(ERROR)
         << "Could not fetch OAuth refresh token. Could not find oauth_token";
     std::move(refresh_token_callback)
         .Run(SecondDeviceAuthBroker::RefreshTokenParsingErrorResponse());
@@ -520,15 +525,15 @@
       SecondDeviceAuthBroker::RefreshTokenRejectionResponse rejection_response;
       rejection_response.reason = SecondDeviceAuthBroker::
           RefreshTokenRejectionResponse::Reason::kUnknownReason;
-      LOG(ERROR) << "Could not fetch OAuth authorization code. Received an "
-                    "auth error from server";
+      QS_LOG(ERROR) << "Could not fetch OAuth authorization code. Received an "
+                       "auth error from server";
       std::move(refresh_token_callback).Run(rejection_response);
       return;
     }
 
     // We could not parse the response and it is not an auth error.
-    LOG(ERROR) << "Could not fetch OAuth authorization code. Error parsing "
-                  "response from server";
+    QS_LOG(ERROR) << "Could not fetch OAuth authorization code. Error parsing "
+                     "response from server";
     std::move(refresh_token_callback)
         .Run(SecondDeviceAuthBroker::RefreshTokenParsingErrorResponse());
     return;
@@ -537,8 +542,8 @@
   std::string* session_status =
       response->GetDict().FindString(kSessionStatusKey);
   if (!session_status) {
-    LOG(ERROR) << "Could not fetch OAuth authorization code. Error parsing "
-                  "session status";
+    QS_LOG(ERROR) << "Could not fetch OAuth authorization code. Error parsing "
+                     "session status";
     std::move(refresh_token_callback)
         .Run(SecondDeviceAuthBroker::RefreshTokenParsingErrorResponse());
     return;
@@ -685,8 +690,9 @@
   endpoint_fetcher_.reset();
 
   if (response->http_status_code != google_apis::ApiErrorCode::HTTP_SUCCESS) {
-    LOG(ERROR) << "Could not fetch OAuth authorization code. HTTP status code: "
-               << response->http_status_code;
+    QS_LOG(ERROR)
+        << "Could not fetch OAuth authorization code. HTTP status code: "
+        << response->http_status_code;
   }
 
   base::OnceCallback<void(const std::string&, RefreshTokenOrErrorCallback)>
@@ -723,7 +729,7 @@
     const GoogleServiceAuthError& error) {
   DCHECK(refresh_token_internal_callback_)
       << "Received an unexpected callback for refresh token";
-  LOG(ERROR) << "Could not fetch refresh token. Error: " << error.ToString();
+  QS_LOG(ERROR) << "Could not fetch refresh token. Error: " << error.ToString();
   std::move(refresh_token_internal_callback_).Run(base::unexpected(error));
 }
 
@@ -732,7 +738,7 @@
     AttestationCertificateCallback certificate_callback,
     const attestation::AttestationFeatures* attestation_features) {
   if (!attestation_features) {
-    LOG(ERROR) << "Failed to get AttestationFeatures";
+    QS_LOG(ERROR) << "Failed to get AttestationFeatures";
     std::move(certificate_callback)
         .Run(base::unexpected(
             SecondDeviceAuthBroker::AttestationErrorType::kPermanentError));
@@ -740,7 +746,7 @@
   }
 
   if (!attestation_features->IsAttestationAvailable()) {
-    LOG(ERROR) << "Attestation is not available";
+    QS_LOG(ERROR) << "Attestation is not available";
     std::move(certificate_callback)
         .Run(base::unexpected(
             SecondDeviceAuthBroker::AttestationErrorType::kPermanentError));
@@ -749,7 +755,7 @@
 
   if (!attestation_features->IsEccSupported() &&
       !attestation_features->IsRsaSupported()) {
-    LOG(ERROR) << "Could not find any supported attestation key type";
+    QS_LOG(ERROR) << "Could not find any supported attestation key type";
     std::move(certificate_callback)
         .Run(base::unexpected(
             SecondDeviceAuthBroker::AttestationErrorType::kPermanentError));
diff --git a/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller_ash_browsertest.cc b/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller_ash_browsertest.cc
index aac165d1..8c672bd 100644
--- a/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller_ash_browsertest.cc
+++ b/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller_ash_browsertest.cc
@@ -94,13 +94,13 @@
   }
 
   void NotifyBlockedPaste(
-      const ui::DataTransferEndpoint* const data_src,
-      const ui::DataTransferEndpoint* const data_dst) override {
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst) override {
     helper_->NotifyBlockedAction(data_src, data_dst);
   }
 
-  void WarnOnPaste(const ui::DataTransferEndpoint* const data_src,
-                   const ui::DataTransferEndpoint* const data_dst,
+  void WarnOnPaste(base::optional_ref<const ui::DataTransferEndpoint> data_src,
+                   base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                    base::RepeatingCallback<void()> reporting_cb) override {
     helper_->WarnOnPaste(data_src, data_dst, std::move(reporting_cb));
   }
@@ -109,10 +109,11 @@
     blink_quit_cb_ = std::move(cb);
   }
 
-  void WarnOnBlinkPaste(const ui::DataTransferEndpoint* const data_src,
-                        const ui::DataTransferEndpoint* const data_dst,
-                        content::WebContents* web_contents,
-                        base::OnceCallback<void(bool)> paste_cb) override {
+  void WarnOnBlinkPaste(
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      content::WebContents* web_contents,
+      base::OnceCallback<void(bool)> paste_cb) override {
     blink_data_dst_.emplace(*data_dst);
     helper_->WarnOnBlinkPaste(data_src, data_dst, web_contents,
                               std::move(paste_cb));
@@ -120,7 +121,7 @@
   }
 
   bool ShouldPasteOnWarn(
-      const ui::DataTransferEndpoint* const data_dst) override {
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst) override {
     if (force_paste_on_warn_) {
       return true;
     }
diff --git a/chrome/browser/ash/web_handwriting_integration_test.cc b/chrome/browser/ash/web_handwriting_integration_test.cc
new file mode 100644
index 0000000..2d7dce2
--- /dev/null
+++ b/chrome/browser/ash/web_handwriting_integration_test.cc
@@ -0,0 +1,100 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/containers/contains.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/threading/thread_restrictions.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/test/base/chromeos/crosier/chromeos_integration_test_mixin.h"
+#include "chrome/test/base/mixin_based_in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "chromeos/services/machine_learning/public/cpp/ml_switches.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/browser_test_utils.h"
+#include "url/gurl.h"
+
+namespace {
+
+// Returns whether the current device supports on-device handwriting, based on
+// the presence of a USE flag in tast_use_flags.txt.
+bool SupportsOndeviceHandwriting() {
+  base::ScopedAllowBlockingForTesting allow_blocking;
+  std::string use_flags;
+  CHECK(base::ReadFileToString(
+      base::FilePath("/usr/local/etc/tast_use_flags.txt"), &use_flags));
+  return base::Contains(use_flags, "ondevice_handwriting");
+}
+
+// TODO(jamescook): Support Lacros. This will require crosapi to be bootstrapped
+// for Lacros Crosier tests.
+class WebHandwritingIntegrationTest : public MixinBasedInProcessBrowserTest {
+ public:
+  WebHandwritingIntegrationTest()
+      : supports_ondevice_handwriting_(SupportsOndeviceHandwriting()) {}
+
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    MixinBasedInProcessBrowserTest::SetUpCommandLine(command_line);
+    if (supports_ondevice_handwriting_) {
+      command_line->AppendSwitchASCII(::switches::kOndeviceHandwritingSwitch,
+                                      "use_rootfs");
+    }
+  }
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+  void TearDownOnMainThread() override {
+    // Close the browser otherwise the test may hang on shutdown.
+    browser()->window()->Close();
+    MixinBasedInProcessBrowserTest::TearDownOnMainThread();
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+  ChromeOSIntegrationTestMixin chromeos_mixin_{&mixin_host_};
+
+  // Whether this board supports on-device handwriting.
+  bool supports_ondevice_handwriting_ = false;
+};
+
+IN_PROC_BROWSER_TEST_F(WebHandwritingIntegrationTest, Recognition) {
+  // Navigate to the appropriate test page, based on whether handwriting
+  // recognition is supported or not.
+  const char* test_file =
+      supports_ondevice_handwriting_
+          ? "web_handwriting_recognition.html"
+          : "web_handwriting_recognition_not_supported.html";
+  GURL url = ui_test_utils::GetTestUrl(
+      base::FilePath("chromeos/web_handwriting/"), base::FilePath(test_file));
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
+
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  // Wait for JS object window.resultPromise to exist in the test page.
+  bool object_exists = false;
+  int iterations = 0;
+  while (iterations < 10 && !object_exists) {
+    object_exists = content::EvalJs(web_contents, "'resultPromise' in window")
+                        .ExtractBool();
+    if (object_exists) {
+      break;
+    }
+    iterations++;
+    // Sleep for a short time.
+    base::RunLoop run_loop;
+    base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
+        FROM_HERE, run_loop.QuitClosure(), base::Milliseconds(100));
+    run_loop.Run();
+  }
+  EXPECT_TRUE(object_exists);
+
+  // The promise should have evaluated without errors. See the HTML files for
+  // details.
+  std::string result_error =
+      content::EvalJs(web_contents, "window.resultPromise").error;
+  EXPECT_TRUE(result_error.empty()) << result_error;
+}
+
+}  // namespace
diff --git a/chrome/browser/captive_portal/captive_portal_browsertest.cc b/chrome/browser/captive_portal/captive_portal_browsertest.cc
index da82625..be3709e 100644
--- a/chrome/browser/captive_portal/captive_portal_browsertest.cc
+++ b/chrome/browser/captive_portal/captive_portal_browsertest.cc
@@ -217,15 +217,10 @@
 // Tracks how many times each tab has been navigated since the Observer was
 // created.  The standard TestNavigationObserver can only watch specific
 // pre-existing tabs or loads in serial for all tabs.
-class MultiNavigationObserver : public TabStripModelObserver,
-                                public BrowserListObserver,
+class MultiNavigationObserver : public ui_test_utils::AllTabsObserver,
                                 public LoadObserver::Observer {
  public:
   MultiNavigationObserver();
-
-  MultiNavigationObserver(const MultiNavigationObserver&) = delete;
-  MultiNavigationObserver& operator=(const MultiNavigationObserver&) = delete;
-
   ~MultiNavigationObserver() override;
 
   // Waits for exactly |num_navigations_to_wait_for| LOAD_STOP
@@ -241,28 +236,16 @@
   int num_navigations() const { return num_navigations_; }
 
  private:
+  // AllTabsObserver
+  std::unique_ptr<base::CheckedObserver> ProcessOneContents(
+      WebContents* web_contents) override;
+
   // LoadObserver::Observer;
   void OnWebContentsDestroyed(WebContents* web_contents) override;
   void OnDidStopLoading(WebContents* web_contents) override;
 
-  // Record for every tab we're watching.
-  struct TabNavigationMapEntry {
-    std::unique_ptr<LoadObserver> load_observer;
-    int stop_loading_count = 0;
-  };
-  using TabNavigationMap = std::map<const WebContents*, TabNavigationMapEntry>;
-
-  // Add all tabs from `browser`, and start watching for changes.
-  void AddBrowser(Browser* browser);
-
-  // TabStripModelObserver:
-  void OnTabStripModelChanged(
-      TabStripModel* tab_strip_model,
-      const TabStripModelChange& change,
-      const TabStripSelectionChange& selection) override;
-
-  // BrowserListObserver
-  void OnBrowserAdded(Browser* browser) override { AddBrowser(browser); }
+  // [WebContents] == number of `DidStopLoading` events.
+  using TabNavigationMap = std::map<const WebContents*, int>;
 
   // Total number of `DidStopLoading` calls.  Might not match the sum of the
   // individual loading events in `tab_navigation_map_` if entries have been
@@ -272,54 +255,20 @@
   // Map of how many times each tab has navigated since |this| was created.
   TabNavigationMap tab_navigation_map_;
 
-  // Total number of navigations to wait for.  Value only matters when
-  // |waiting_for_navigation_| is true.
-  int num_navigations_to_wait_for_ = 0;
-
-  // True if WaitForNavigations has been called, until
-  // |num_navigations_to_wait_for_| have been observed.
-  bool waiting_for_navigation_ = false;
-  std::unique_ptr<base::RunLoop> run_loop_;
+  // Total number of navigations to wait for, if known.
+  std::optional<int> num_navigations_to_wait_for_;
 };
 
 MultiNavigationObserver::MultiNavigationObserver() {
-  // Watch all browsers.
-  for (Browser* browser : *BrowserList::GetInstance()) {
-    AddBrowser(browser);
-  }
-  BrowserList::GetInstance()->AddObserver(this);
+  AddAllBrowsers();
 }
 
-MultiNavigationObserver::~MultiNavigationObserver() {
-  BrowserList::GetInstance()->RemoveObserver(this);
-  // We're tracking all browsers, so remove us from all of all of them.
-  for (Browser* browser : *BrowserList::GetInstance()) {
-    browser->tab_strip_model()->RemoveObserver(this);
-  }
-}
+MultiNavigationObserver::~MultiNavigationObserver() = default;
 
-void MultiNavigationObserver::AddBrowser(Browser* browser) {
-  browser->tab_strip_model()->AddObserver(this);
-
-  // Add all the tabs.
-  for (int index = 0; index < browser->tab_strip_model()->count(); index++) {
-    auto* web_contents = browser->tab_strip_model()->GetWebContentsAt(index);
-    tab_navigation_map_[web_contents].load_observer =
-        std::make_unique<LoadObserver>(this, web_contents);
-  }
-}
-
-void MultiNavigationObserver::OnTabStripModelChanged(
-    TabStripModel* tab_strip_model,
-    const TabStripModelChange& change,
-    const TabStripSelectionChange& selection) {
-  if (change.type() != TabStripModelChange::kInserted) {
-    return;
-  }
-
-  auto* web_contents = change.GetInsert()->contents[0].contents.get();
-  tab_navigation_map_[web_contents].load_observer =
-      std::make_unique<LoadObserver>(this, web_contents);
+std::unique_ptr<base::CheckedObserver>
+MultiNavigationObserver::ProcessOneContents(WebContents* web_contents) {
+  tab_navigation_map_[web_contents] = 0;
+  return std::make_unique<LoadObserver>(this, web_contents);
 }
 
 void MultiNavigationObserver::OnWebContentsDestroyed(
@@ -332,29 +281,24 @@
 void MultiNavigationObserver::OnDidStopLoading(WebContents* web_contents) {
   auto iter = tab_navigation_map_.find(web_contents);
   CHECK(iter != tab_navigation_map_.end());
-  ++(iter->second.stop_loading_count);
+  ++(iter->second);
   ++num_navigations_;
 
-  if (waiting_for_navigation_ &&
-      num_navigations_to_wait_for_ == num_navigations_) {
-    waiting_for_navigation_ = false;
-    if (run_loop_) {
-      run_loop_->Quit();
-    }
+  if (num_navigations_to_wait_for_ &&
+      *num_navigations_to_wait_for_ == num_navigations_) {
+    ConditionMet();
   }
 }
 
 void MultiNavigationObserver::WaitForNavigations(
     int num_navigations_to_wait_for) {
-  // Shouldn't already be waiting for navigations.
-  EXPECT_FALSE(waiting_for_navigation_);
   EXPECT_LT(0, num_navigations_to_wait_for);
+  // Since we don't know how many navigations are going to be waited for, see
+  // how many we've seen so far.
   if (num_navigations_ < num_navigations_to_wait_for) {
+    // Let `OnDidStopLoading()` know when to stop waiting.
     num_navigations_to_wait_for_ = num_navigations_to_wait_for;
-    waiting_for_navigation_ = true;
-    run_loop_ = std::make_unique<base::RunLoop>();
-    run_loop_->Run();
-    EXPECT_FALSE(waiting_for_navigation_);
+    Wait();
   }
   EXPECT_EQ(num_navigations_, num_navigations_to_wait_for);
 }
@@ -362,9 +306,10 @@
 int MultiNavigationObserver::NumNavigationsForTab(
     WebContents* web_contents) const {
   auto tab_navigations = tab_navigation_map_.find(web_contents);
-  if (tab_navigations == tab_navigation_map_.end())
+  if (tab_navigations == tab_navigation_map_.end()) {
     return 0;
-  return tab_navigations->second.stop_loading_count;
+  }
+  return tab_navigations->second;
 }
 
 // This observer creates a list of loading tabs, and then waits for them all
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 63578b6..dedaa41 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1918,8 +1918,7 @@
     content::RenderProcessHost* host) {
   Profile* profile = Profile::FromBrowserContext(host->GetBrowserContext());
 
-  WebRtcLoggingController::AttachToRenderProcessHost(
-      host, g_browser_process->webrtc_log_uploader());
+  WebRtcLoggingController::AttachToRenderProcessHost(host);
 
   // The audio manager outlives the host, so it's safe to hand a raw pointer to
   // it to the AudioDebugRecordingsHandler, which is owned by the host.
diff --git a/chrome/browser/chrome_content_browser_client_browsertest.cc b/chrome/browser/chrome_content_browser_client_browsertest.cc
index 57b183e..43d4e56 100644
--- a/chrome/browser/chrome_content_browser_client_browsertest.cc
+++ b/chrome/browser/chrome_content_browser_client_browsertest.cc
@@ -92,7 +92,7 @@
 #include "ui/base/clipboard/clipboard_format_type.h"
 
 #if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
-#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h"  // nogncheck
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h"  // nogncheck
 #endif  // BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
 
 #endif  // BUILDFLAG(ENTERPRISE_CONTENT_ANALYSIS)
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.cc
index c22e85cf..3052fe06 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.cc
@@ -58,9 +58,9 @@
          endpoint->type() == ui::EndpointType::kDefault;
 }
 
-bool IsFilesApp(const ui::DataTransferEndpoint* const data_dst) {
+bool IsFilesApp(base::optional_ref<const ui::DataTransferEndpoint> data_dst) {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  if (!data_dst || !data_dst->IsUrlType()) {
+  if (!data_dst.has_value() || !data_dst->IsUrlType()) {
     return false;
   }
 
@@ -80,12 +80,16 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 }
 
-bool IsClipboardHistory(const ui::DataTransferEndpoint* const data_dst) {
-  return data_dst && data_dst->type() == ui::EndpointType::kClipboardHistory;
+bool IsClipboardHistory(
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst) {
+  return data_dst.has_value() &&
+         data_dst->type() == ui::EndpointType::kClipboardHistory;
 }
 
-bool ShouldNotifyOnPaste(const ui::DataTransferEndpoint* const data_dst) {
-  bool notify_on_paste = !data_dst || data_dst->notify_if_restricted();
+bool ShouldNotifyOnPaste(
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst) {
+  bool notify_on_paste =
+      !data_dst.has_value() || data_dst->notify_if_restricted();
 
   // Files Apps continuously reads the clipboard data which triggers a lot of
   // notifications while the user isn't actually initiating any copy/paste.
@@ -103,8 +107,8 @@
 
 DlpRulesManager::Level IsDataTransferAllowed(
     const DlpRulesManager& dlp_rules_manager,
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     const absl::optional<size_t> size,
     std::string* src_pattern,
     std::string* dst_pattern,
@@ -114,13 +118,14 @@
     return DlpRulesManager::Level::kAllow;
   }
 
-  if (!data_src || !data_src->IsUrlType()) {  // Currently we only handle URLs.
+  // Currently we only handle URLs.
+  if (!data_src.has_value() || !data_src->IsUrlType()) {
     return DlpRulesManager::Level::kAllow;
   }
 
   const GURL src_url = *data_src->GetURL();
   ui::EndpointType dst_type =
-      data_dst ? data_dst->type() : ui::EndpointType::kDefault;
+      data_dst.has_value() ? data_dst->type() : ui::EndpointType::kDefault;
 
   DlpRulesManager::Level level = DlpRulesManager::Level::kAllow;
 
@@ -286,12 +291,12 @@
 }
 
 void DataTransferDlpController::PasteIfAllowed(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     const absl::optional<size_t> size,
     content::RenderFrameHost* rfh,
     base::OnceCallback<void(bool)> paste_cb) {
-  DCHECK(data_dst);
+  DCHECK(data_dst.has_value());
   DCHECK(data_dst->IsUrlType());
 
   auto* web_contents = content::WebContents::FromRenderFrameHost(rfh);
@@ -324,9 +329,7 @@
 
   if (ShouldPasteOnWarn(data_dst)) {
     if (ShouldNotifyOnPaste(data_dst)) {
-      ReportWarningProceededEvent(base::OptionalFromPtr(data_src),
-                                  base::OptionalFromPtr(data_dst), src_pattern,
-                                  dst_pattern,
+      ReportWarningProceededEvent(data_src, data_dst, src_pattern, dst_pattern,
                                   /*is_clipboard_event=*/true, rule_metadata);
     }
     std::move(paste_cb).Run(true);
@@ -340,8 +343,8 @@
 
       auto reporting_cb = base::BindOnce(
           &DataTransferDlpController::ReportWarningProceededEvent,
-          weak_ptr_factory_.GetWeakPtr(), base::OptionalFromPtr(data_src),
-          base::OptionalFromPtr(data_dst), src_pattern, dst_pattern,
+          weak_ptr_factory_.GetWeakPtr(), data_src.CopyAsOptional(),
+          data_dst.CopyAsOptional(), src_pattern, dst_pattern,
           /*is_clipboard_event=*/true, rule_metadata);
 
       auto report_and_paste_cb =
@@ -358,7 +361,7 @@
 
 void DataTransferDlpController::DropIfAllowed(
     const ui::OSExchangeData* drag_data,
-    const ui::DataTransferEndpoint* data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     base::OnceClosure drop_cb) {
   DCHECK(drag_data);
 
@@ -370,16 +373,17 @@
       std::vector<ui::FileInfo> dropped_files;
       drag_data->GetFilenames(&dropped_files);
       files_controller->CheckIfDropAllowed(
-          dropped_files, data_dst,
+          dropped_files, data_dst.as_ptr(),
           base::BindOnce(&DataTransferDlpController::ContinueDropIfAllowed,
-                         weak_ptr_factory_.GetWeakPtr(), drag_data, data_dst,
+                         weak_ptr_factory_.GetWeakPtr(),
+                         *drag_data->GetSource(), data_dst,
                          std::move(drop_cb)));
       return;
     }
 #endif
     // TODO(b/269610458): Check dropped files in Lacros.
   }
-  ContinueDropIfAllowed(drag_data, data_dst, std::move(drop_cb),
+  ContinueDropIfAllowed(*drag_data->GetSource(), data_dst, std::move(drop_cb),
                         /*is_allowed=*/true);
 }
 
@@ -394,8 +398,8 @@
 }
 
 void DataTransferDlpController::ReportWarningProceededEvent(
-    const absl::optional<ui::DataTransferEndpoint> maybe_data_src,
-    const absl::optional<ui::DataTransferEndpoint> maybe_data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     const std::string& src_pattern,
     const std::string& dst_pattern,
     bool is_clipboard_event,
@@ -406,26 +410,20 @@
     return;
   }
 
-  const ui::DataTransferEndpoint* data_dst =
-      maybe_data_dst.has_value() ? &maybe_data_dst.value() : nullptr;
-
   if (is_clipboard_event) {
     base::TimeTicks curr_time = base::TimeTicks::Now();
 
-    const ui::DataTransferEndpoint* data_src =
-        maybe_data_src.has_value() ? &maybe_data_src.value() : nullptr;
-
     if (ShouldSkipReporting(data_src, data_dst, /*is_warning_proceeded=*/true,
                             curr_time)) {
       return;
     }
-    last_reported_.data_src = maybe_data_src;
-    last_reported_.data_dst = maybe_data_dst;
+    last_reported_.data_src = data_src.CopyAsOptional();
+    last_reported_.data_dst = data_dst.CopyAsOptional();
     last_reported_.time = curr_time;
     last_reported_.is_warning_proceeded = true;
   }
 
-  if (data_dst && IsVM(data_dst->type())) {
+  if (data_dst.has_value() && IsVM(data_dst->type())) {
     NOTREACHED();
   } else {
     reporting_manager->ReportWarningProceededEvent(
@@ -435,22 +433,22 @@
 }
 
 void DataTransferDlpController::NotifyBlockedPaste(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst) {
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst) {
   clipboard_notifier_.NotifyBlockedAction(data_src, data_dst);
 }
 
 void DataTransferDlpController::WarnOnPaste(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     base::RepeatingCallback<void()> reporting_cb) {
-  DCHECK(!(data_dst && data_dst->IsUrlType()));
+  DCHECK(!(data_dst.has_value() && data_dst->IsUrlType()));
   clipboard_notifier_.WarnOnPaste(data_src, data_dst, std::move(reporting_cb));
 }
 
 void DataTransferDlpController::WarnOnBlinkPaste(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     content::WebContents* web_contents,
     base::OnceCallback<void(bool)> paste_cb) {
   clipboard_notifier_.WarnOnBlinkPaste(data_src, data_dst, web_contents,
@@ -458,31 +456,31 @@
 }
 
 bool DataTransferDlpController::ShouldPasteOnWarn(
-    const ui::DataTransferEndpoint* const data_dst) {
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst) {
   return clipboard_notifier_.DidUserApproveDst(data_dst);
 }
 
 bool DataTransferDlpController::ShouldCancelOnWarn(
-    const ui::DataTransferEndpoint* const data_dst) {
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst) {
   return clipboard_notifier_.DidUserCancelDst(data_dst);
 }
 
 void DataTransferDlpController::NotifyBlockedDrop(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst) {
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst) {
   drag_drop_notifier_.NotifyBlockedAction(data_src, data_dst);
 }
 
 void DataTransferDlpController::WarnOnDrop(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     base::OnceClosure drop_cb) {
   drag_drop_notifier_.WarnOnDrop(data_src, data_dst, std::move(drop_cb));
 }
 
 bool DataTransferDlpController::ShouldSkipReporting(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     bool is_warning_proceeded,
     base::TimeTicks curr_time) {
   // Skip reporting for destination endpoints which don't notify the user
@@ -493,10 +491,12 @@
 
   // In theory, there is no need to check for data source and destination if
   // |kSkipReportingTimeout| is shorter than human reaction time.
-  bool is_same_src = data_src ? *data_src == last_reported_.data_src
-                              : IsNullEndpoint(last_reported_.data_src);
-  bool is_same_dst = data_dst ? *data_dst == last_reported_.data_dst
-                              : IsNullEndpoint(last_reported_.data_dst);
+  bool is_same_src = data_src.has_value()
+                         ? *data_src == last_reported_.data_src
+                         : IsNullEndpoint(last_reported_.data_src);
+  bool is_same_dst = data_dst.has_value()
+                         ? *data_dst == last_reported_.data_dst
+                         : IsNullEndpoint(last_reported_.data_dst);
   bool is_same_mode =
       last_reported_.is_warning_proceeded.has_value() &&
       is_warning_proceeded == last_reported_.is_warning_proceeded.value();
@@ -514,8 +514,8 @@
 }
 
 void DataTransferDlpController::ReportEvent(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     const std::string& src_pattern,
     const std::string& dst_pattern,
     DlpRulesManager::Level level,
@@ -532,16 +532,14 @@
                             curr_time)) {
       return;
     }
-    last_reported_.data_src =
-        base::OptionalFromPtr<ui::DataTransferEndpoint>(data_src);
-    last_reported_.data_dst =
-        base::OptionalFromPtr<ui::DataTransferEndpoint>(data_dst);
+    last_reported_.data_src = data_src.CopyAsOptional();
+    last_reported_.data_dst = data_dst.CopyAsOptional();
     last_reported_.time = curr_time;
     last_reported_.is_warning_proceeded = false;
   }
 
   ui::EndpointType dst_type =
-      data_dst ? data_dst->type() : ui::EndpointType::kDefault;
+      data_dst.has_value() ? data_dst->type() : ui::EndpointType::kDefault;
   switch (dst_type) {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
     case ui::EndpointType::kCrostini:
@@ -574,8 +572,8 @@
 }
 
 void DataTransferDlpController::MaybeReportEvent(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     const std::string& src_pattern,
     const std::string& dst_pattern,
     DlpRulesManager::Level level,
@@ -589,13 +587,10 @@
 }
 
 void DataTransferDlpController::ContinueDropIfAllowed(
-    const ui::OSExchangeData* drag_data,
-    const ui::DataTransferEndpoint* data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     base::OnceClosure drop_cb,
     bool is_allowed) {
-  DCHECK(drag_data);
-  auto* data_src = drag_data->GetSource();
-
   DlpRulesManager::Level level;
   if (!is_allowed) {
     level = DlpRulesManager::Level::kBlock;
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h
index 20a5f1f..cd3e104 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller.h
@@ -41,14 +41,16 @@
       base::optional_ref<const ui::DataTransferEndpoint> data_src,
       base::optional_ref<const ui::DataTransferEndpoint> data_dst,
       const absl::optional<size_t> size) override;
-  void PasteIfAllowed(const ui::DataTransferEndpoint* const data_src,
-                      const ui::DataTransferEndpoint* const data_dst,
-                      const absl::optional<size_t> size,
-                      content::RenderFrameHost* rfh,
-                      base::OnceCallback<void(bool)> paste_cb) override;
-  void DropIfAllowed(const ui::OSExchangeData* drag_data,
-                     const ui::DataTransferEndpoint* data_dst,
-                     base::OnceClosure drop_cb) override;
+  void PasteIfAllowed(
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      const absl::optional<size_t> size,
+      content::RenderFrameHost* rfh,
+      base::OnceCallback<void(bool)> paste_cb) override;
+  void DropIfAllowed(
+      const ui::OSExchangeData* drag_data,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      base::OnceClosure drop_cb) override;
 
  protected:
   explicit DataTransferDlpController(const DlpRulesManager& dlp_rules_manager);
@@ -61,8 +63,8 @@
 
   // Protected because it needs to be accessible from tests.
   void ReportWarningProceededEvent(
-      const absl::optional<ui::DataTransferEndpoint> maybe_data_src,
-      const absl::optional<ui::DataTransferEndpoint> maybe_data_dst,
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
       const std::string& src_pattern,
       const std::string& dst_pattern,
       bool is_clipboard_event,
@@ -70,57 +72,63 @@
 
  private:
   virtual void NotifyBlockedPaste(
-      const ui::DataTransferEndpoint* const data_src,
-      const ui::DataTransferEndpoint* const data_dst);
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst);
 
-  virtual void WarnOnPaste(const ui::DataTransferEndpoint* const data_src,
-                           const ui::DataTransferEndpoint* const data_dst,
-                           base::RepeatingCallback<void()> reporting_cb);
+  virtual void WarnOnPaste(
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      base::RepeatingCallback<void()> reporting_cb);
 
-  virtual void WarnOnBlinkPaste(const ui::DataTransferEndpoint* const data_src,
-                                const ui::DataTransferEndpoint* const data_dst,
-                                content::WebContents* web_contents,
-                                base::OnceCallback<void(bool)> paste_cb);
+  virtual void WarnOnBlinkPaste(
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      content::WebContents* web_contents,
+      base::OnceCallback<void(bool)> paste_cb);
 
   virtual bool ShouldPasteOnWarn(
-      const ui::DataTransferEndpoint* const data_dst);
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst);
 
   virtual bool ShouldCancelOnWarn(
-      const ui::DataTransferEndpoint* const data_dst);
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst);
 
   virtual void NotifyBlockedDrop(
-      const ui::DataTransferEndpoint* const data_src,
-      const ui::DataTransferEndpoint* const data_dst);
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst);
 
-  virtual void WarnOnDrop(const ui::DataTransferEndpoint* const data_src,
-                          const ui::DataTransferEndpoint* const data_dst,
-                          base::OnceClosure drop_cb);
+  virtual void WarnOnDrop(
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      base::OnceClosure drop_cb);
 
-  bool ShouldSkipReporting(const ui::DataTransferEndpoint* const data_src,
-                           const ui::DataTransferEndpoint* const data_dst,
-                           bool is_warning_proceeded,
-                           base::TimeTicks curr_time);
+  bool ShouldSkipReporting(
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      bool is_warning_proceeded,
+      base::TimeTicks curr_time);
 
-  void ReportEvent(const ui::DataTransferEndpoint* const data_src,
-                   const ui::DataTransferEndpoint* const data_dst,
+  void ReportEvent(base::optional_ref<const ui::DataTransferEndpoint> data_src,
+                   base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                    const std::string& src_pattern,
                    const std::string& dst_pattern,
                    DlpRulesManager::Level level,
                    bool is_clipboard_event,
                    const DlpRulesManager::RuleMetadata& rule_metadata);
 
-  void MaybeReportEvent(const ui::DataTransferEndpoint* const data_src,
-                        const ui::DataTransferEndpoint* const data_dst,
-                        const std::string& src_pattern,
-                        const std::string& dst_pattern,
-                        DlpRulesManager::Level level,
-                        bool is_clipboard_event,
-                        const DlpRulesManager::RuleMetadata& rule_metadata);
+  void MaybeReportEvent(
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      const std::string& src_pattern,
+      const std::string& dst_pattern,
+      DlpRulesManager::Level level,
+      bool is_clipboard_event,
+      const DlpRulesManager::RuleMetadata& rule_metadata);
 
-  void ContinueDropIfAllowed(const ui::OSExchangeData* drag_data,
-                             const ui::DataTransferEndpoint* data_dst,
-                             base::OnceClosure drop_cb,
-                             bool is_allowed);
+  void ContinueDropIfAllowed(
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      base::OnceClosure drop_cb,
+      bool is_allowed);
 
   // The solution for the issue of sending multiple reporting events for a
   // single user action. When a user triggers a paste (for instance by pressing
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
index 7ac5407..5aefa803 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
@@ -110,28 +110,29 @@
   }
 
   void NotifyBlockedPaste(
-      const ui::DataTransferEndpoint* const data_src,
-      const ui::DataTransferEndpoint* const data_dst) override {
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst) override {
     helper_->NotifyBlockedAction(data_src, data_dst);
   }
 
-  void WarnOnPaste(const ui::DataTransferEndpoint* const data_src,
-                   const ui::DataTransferEndpoint* const data_dst,
+  void WarnOnPaste(base::optional_ref<const ui::DataTransferEndpoint> data_src,
+                   base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                    base::RepeatingCallback<void()> reporting_cb) override {
     helper_->WarnOnPaste(data_src, data_dst, std::move(reporting_cb));
   }
 
-  void WarnOnBlinkPaste(const ui::DataTransferEndpoint* const data_src,
-                        const ui::DataTransferEndpoint* const data_dst,
-                        content::WebContents* web_contents,
-                        base::OnceCallback<void(bool)> paste_cb) override {
+  void WarnOnBlinkPaste(
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      content::WebContents* web_contents,
+      base::OnceCallback<void(bool)> paste_cb) override {
     blink_data_dst_.emplace(*data_dst);
     helper_->WarnOnBlinkPaste(data_src, data_dst, web_contents,
                               std::move(paste_cb));
   }
 
   bool ShouldPasteOnWarn(
-      const ui::DataTransferEndpoint* const data_dst) override {
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst) override {
     if (force_paste_on_warn_) {
       return true;
     }
@@ -148,15 +149,15 @@
   }
 
   void ReportWarningProceededEvent(
-      const ui::DataTransferEndpoint* const data_src,
-      const ui::DataTransferEndpoint* const data_dst,
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
       const std::string& src_pattern,
       const std::string& dst_pattern,
       const DlpRulesManager::RuleMetadata& rule_metadata,
       bool is_clipboard_event) {
     DataTransferDlpController::ReportWarningProceededEvent(
-        base::OptionalFromPtr(data_src), base::OptionalFromPtr(data_dst),
-        src_pattern, dst_pattern, is_clipboard_event, rule_metadata);
+        data_src, data_dst, src_pattern, dst_pattern, is_clipboard_event,
+        rule_metadata);
   }
 
   raw_ptr<FakeClipboardNotifier> helper_ = nullptr;
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
index dffd3b4c..bd9b84b 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_unittest.cc
@@ -56,34 +56,38 @@
   explicit MockDlpController(const DlpRulesManager& dlp_rules_manager)
       : DataTransferDlpController(dlp_rules_manager) {}
 
-  MOCK_METHOD2(NotifyBlockedPaste,
-               void(const ui::DataTransferEndpoint* const data_src,
-                    const ui::DataTransferEndpoint* const data_dst));
+  MOCK_METHOD2(
+      NotifyBlockedPaste,
+      void(base::optional_ref<const ui::DataTransferEndpoint> data_src,
+           base::optional_ref<const ui::DataTransferEndpoint> data_dst));
 
-  MOCK_METHOD2(NotifyBlockedDrop,
-               void(const ui::DataTransferEndpoint* const data_src,
-                    const ui::DataTransferEndpoint* const data_dst));
+  MOCK_METHOD2(
+      NotifyBlockedDrop,
+      void(base::optional_ref<const ui::DataTransferEndpoint> data_src,
+           base::optional_ref<const ui::DataTransferEndpoint> data_dst));
 
   MOCK_METHOD3(WarnOnPaste,
-               void(const ui::DataTransferEndpoint* const data_src,
-                    const ui::DataTransferEndpoint* const data_dst,
+               void(base::optional_ref<const ui::DataTransferEndpoint> data_src,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::RepeatingCallback<void()> reporting_cb));
 
   MOCK_METHOD4(WarnOnBlinkPaste,
-               void(const ui::DataTransferEndpoint* const data_src,
-                    const ui::DataTransferEndpoint* const data_dst,
+               void(base::optional_ref<const ui::DataTransferEndpoint> data_src,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     content::WebContents* web_contents,
                     base::OnceCallback<void(bool)> paste_cb));
 
-  MOCK_METHOD1(ShouldPasteOnWarn,
-               bool(const ui::DataTransferEndpoint* const data_dst));
+  MOCK_METHOD1(
+      ShouldPasteOnWarn,
+      bool(base::optional_ref<const ui::DataTransferEndpoint> data_dst));
 
-  MOCK_METHOD1(ShouldCancelOnWarn,
-               bool(const ui::DataTransferEndpoint* const data_dst));
+  MOCK_METHOD1(
+      ShouldCancelOnWarn,
+      bool(base::optional_ref<const ui::DataTransferEndpoint> data_dst));
 
   MOCK_METHOD3(WarnOnDrop,
-               void(const ui::DataTransferEndpoint* const data_src,
-                    const ui::DataTransferEndpoint* const data_dst,
+               void(base::optional_ref<const ui::DataTransferEndpoint> data_src,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::OnceClosure drop_cb));
 
  protected:
@@ -179,7 +183,7 @@
   EXPECT_CALL(callback, Run());
 
   auto drag_data = ui::OSExchangeData();
-  dlp_controller_->DropIfAllowed(&drag_data, nullptr, callback.Get());
+  dlp_controller_->DropIfAllowed(&drag_data, absl::nullopt, callback.Get());
 
   histogram_tester_.ExpectUniqueSample(
       data_controls::GetDlpHistogramPrefix() +
@@ -414,14 +418,12 @@
     absl::optional<ui::EndpointType> endpoint_type;
     std::tie(endpoint_type, do_notify_) = GetParam();
     data_dst_ = CreateEndpoint(base::OptionalToPtr(endpoint_type), do_notify_);
-    dst_ptr_ = base::OptionalToPtr(data_dst_);
   }
 
   ui::DataTransferEndpoint data_src_{ui::EndpointType::kDefault};
   bool do_notify_;
   absl::optional<ui::DataTransferEndpoint> data_dst_;
   ui::OSExchangeData drag_data_;
-  raw_ptr<ui::DataTransferEndpoint> dst_ptr_;
 };
 
 INSTANTIATE_TEST_SUITE_P(
@@ -451,7 +453,7 @@
   ::testing::StrictMock<base::MockOnceClosure> callback;
   EXPECT_CALL(callback, Run());
 
-  dlp_controller_->DropIfAllowed(&drag_data_, dst_ptr_, callback.Get());
+  dlp_controller_->DropIfAllowed(&drag_data_, data_dst_, callback.Get());
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
 
   histogram_tester_.ExpectUniqueSample(
@@ -467,7 +469,7 @@
 TEST_P(DlpControllerTest, Block_IsClipboardReadAllowed) {
   EXPECT_CALL(*rules_manager_, IsRestrictedDestination)
       .WillOnce(testing::Return(DlpRulesManager::Level::kBlock));
-  if (do_notify_ || !dst_ptr_) {
+  if (do_notify_ || !data_dst_.has_value()) {
     EXPECT_CALL(*dlp_controller_, NotifyBlockedPaste);
   }
 
@@ -498,7 +500,7 @@
   EXPECT_CALL(*dlp_controller_, NotifyBlockedDrop);
   ::testing::StrictMock<base::MockOnceClosure> callback;
 
-  dlp_controller_->DropIfAllowed(&drag_data_, dst_ptr_, callback.Get());
+  dlp_controller_->DropIfAllowed(&drag_data_, data_dst_, callback.Get());
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
 
   EXPECT_EQ(events_.size(), 1u);
@@ -540,7 +542,7 @@
   ::testing::StrictMock<base::MockOnceClosure> callback;
   EXPECT_CALL(callback, Run());
 
-  dlp_controller_->DropIfAllowed(&drag_data_, dst_ptr_, callback.Get());
+  dlp_controller_->DropIfAllowed(&drag_data_, data_dst_, callback.Get());
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
 
   EXPECT_EQ(events_.size(), 1u);
@@ -559,7 +561,8 @@
       .WillRepeatedly(testing::Return(false));
   EXPECT_CALL(*dlp_controller_, ShouldCancelOnWarn)
       .WillRepeatedly(testing::Return(false));
-  bool show_warning = dst_ptr_ ? (do_notify_ && !dst_ptr_->IsUrlType()) : true;
+  bool show_warning =
+      data_dst_.has_value() ? (do_notify_ && !data_dst_->IsUrlType()) : true;
   if (show_warning) {
     EXPECT_CALL(*dlp_controller_, WarnOnPaste);
   }
@@ -617,7 +620,7 @@
 
   ::testing::StrictMock<base::MockOnceClosure> callback;
 
-  dlp_controller_->DropIfAllowed(&drag_data_, dst_ptr_, callback.Get());
+  dlp_controller_->DropIfAllowed(&drag_data_, data_dst_, callback.Get());
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
 
   histogram_tester_.ExpectUniqueSample(
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
index cc99f60..1c2b4ff 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
@@ -42,9 +42,10 @@
 namespace {
 
 ui::DataTransferEndpoint CloneEndpoint(
-    const ui::DataTransferEndpoint* const data_endpoint) {
-  if (data_endpoint == nullptr)
+    base::optional_ref<const ui::DataTransferEndpoint> data_endpoint) {
+  if (!data_endpoint.has_value()) {
     return ui::DataTransferEndpoint(ui::EndpointType::kDefault);
+  }
 
   return ui::DataTransferEndpoint(*data_endpoint);
 }
@@ -91,9 +92,9 @@
 }
 
 bool HasEndpoint(const std::vector<ui::DataTransferEndpoint>& saved_endpoints,
-                 const ui::DataTransferEndpoint* const endpoint) {
+                 base::optional_ref<const ui::DataTransferEndpoint> endpoint) {
   const ui::EndpointType endpoint_type =
-      endpoint ? endpoint->type() : ui::EndpointType::kDefault;
+      endpoint.has_value() ? endpoint->type() : ui::EndpointType::kDefault;
 
   for (const auto& ept : saved_endpoints) {
     if (ept.type() == endpoint_type) {
@@ -126,14 +127,14 @@
 }
 
 void DlpClipboardNotifier::NotifyBlockedAction(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst) {
-  DCHECK(data_src);
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst) {
+  DCHECK(data_src.has_value());
   DCHECK(data_src->GetURL());
   const std::u16string host_name =
       base::UTF8ToUTF16(data_src->GetURL()->host());
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  if (data_dst) {
+  if (data_dst.has_value()) {
     if (data_dst->type() == ui::EndpointType::kCrostini) {
       ShowToast(kClipboardBlockCrostiniToastId,
                 ash::ToastCatalogName::kClipboardBlockedAction,
@@ -166,10 +167,10 @@
 }
 
 void DlpClipboardNotifier::WarnOnPaste(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     base::RepeatingCallback<void()> reporting_cb) {
-  DCHECK(data_src);
+  DCHECK(data_src.has_value());
   DCHECK(data_src->GetURL());
 
   CloseWidget(widget_.get(), views::Widget::ClosedReason::kUnspecified);
@@ -177,7 +178,7 @@
   const std::u16string host_name =
       base::UTF8ToUTF16(data_src->GetURL()->host());
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-  if (data_dst) {
+  if (data_dst.has_value()) {
     if (data_dst->type() == ui::EndpointType::kCrostini) {
       ShowToast(kClipboardWarnCrostiniToastId,
                 ash::ToastCatalogName::kClipboardWarnOnPaste,
@@ -231,11 +232,11 @@
 }
 
 void DlpClipboardNotifier::WarnOnBlinkPaste(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     content::WebContents* web_contents,
     base::OnceCallback<void(bool)> paste_cb) {
-  DCHECK(data_src);
+  DCHECK(data_src.has_value());
   DCHECK(data_src->GetURL());
 
   CloseWidget(widget_.get(), views::Widget::ClosedReason::kUnspecified);
@@ -258,12 +259,12 @@
 }
 
 bool DlpClipboardNotifier::DidUserApproveDst(
-    const ui::DataTransferEndpoint* const data_dst) {
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst) {
   return HasEndpoint(approved_dsts_, data_dst);
 }
 
 bool DlpClipboardNotifier::DidUserCancelDst(
-    const ui::DataTransferEndpoint* const data_dst) {
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst) {
   return HasEndpoint(cancelled_dsts_, data_dst);
 }
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.h b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.h
index cb0dcfc1..9663e20 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.h
@@ -38,29 +38,32 @@
   // If the type of `data_dst` is kCrostini, kPluginVm or kArc, it will show a
   // toast instead of a bubble.
   void NotifyBlockedAction(
-      const ui::DataTransferEndpoint* const data_src,
-      const ui::DataTransferEndpoint* const data_dst) override;
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst) override;
 
   // Warns the user that this paste action is not recommended and runs
   // `reporting_cb` if the action is proceeded. If the type of `data_dst` is
   // kCrostini, kPluginVm or kArc, it will show a toast instead of a bubble.
-  void WarnOnPaste(const ui::DataTransferEndpoint* const data_src,
-                   const ui::DataTransferEndpoint* const data_dst,
+  void WarnOnPaste(base::optional_ref<const ui::DataTransferEndpoint> data_src,
+                   base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                    base::RepeatingCallback<void()> reporting_cb);
 
   // Warns the user that this paste action in Blink is not recommended.
-  void WarnOnBlinkPaste(const ui::DataTransferEndpoint* const data_src,
-                        const ui::DataTransferEndpoint* const data_dst,
-                        content::WebContents* web_contents,
-                        base::OnceCallback<void(bool)> paste_cb);
+  void WarnOnBlinkPaste(
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      content::WebContents* web_contents,
+      base::OnceCallback<void(bool)> paste_cb);
 
   // Returns true if the user approved to paste the clipboard data to this
   // `data_dst` before.
-  bool DidUserApproveDst(const ui::DataTransferEndpoint* const data_dst);
+  bool DidUserApproveDst(
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst);
 
   // Returns true if the user cancelled pasting the clipboard data to this
   // `data_dst` before.
-  bool DidUserCancelDst(const ui::DataTransferEndpoint* const data_dst);
+  bool DidUserCancelDst(
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst);
 
  protected:
   // Exposed for tests to override.
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.h b/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.h
index a9abb77..82a8eec 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier.h
@@ -7,6 +7,7 @@
 
 #include "base/functional/callback_forward.h"
 #include "base/timer/timer.h"
+#include "base/types/optional_ref.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/views/widget/unique_widget_ptr.h"
 #include "ui/views/widget/widget.h"
@@ -28,8 +29,8 @@
 
   // Notifies the user that the data transfer action is not allowed.
   virtual void NotifyBlockedAction(
-      const ui::DataTransferEndpoint* const data_src,
-      const ui::DataTransferEndpoint* const data_dst) = 0;
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst) = 0;
 
  protected:
   // Virtual for tests to override.
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier_browsertest.cc b/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier_browsertest.cc
index 1152da6..1cf988eb 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_data_transfer_notifier_browsertest.cc
@@ -31,8 +31,8 @@
 
   // DlpDataTransferNotifier:
   void NotifyBlockedAction(
-      const ui::DataTransferEndpoint* const data_src,
-      const ui::DataTransferEndpoint* const data_dst) override {}
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst) override {}
 
   MOCK_METHOD(void, OnWidgetDestroying, (views::Widget*), (override));
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.cc b/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.cc
index 223cf8d8..908050d 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.cc
@@ -18,9 +18,9 @@
 DlpDragDropNotifier::~DlpDragDropNotifier() = default;
 
 void DlpDragDropNotifier::NotifyBlockedAction(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst) {
-  DCHECK(data_src);
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst) {
+  DCHECK(data_src.has_value());
   DCHECK(data_src->GetURL());
   const std::u16string host_name =
       base::UTF8ToUTF16(data_src->GetURL()->host());
@@ -30,10 +30,10 @@
 }
 
 void DlpDragDropNotifier::WarnOnDrop(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst,
+    base::optional_ref<const ui::DataTransferEndpoint> data_src,
+    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
     base::OnceClosure drop_cb) {
-  DCHECK(data_src);
+  DCHECK(data_src.has_value());
   DCHECK(data_src->GetURL());
 
   CloseWidget(widget_.get(), views::Widget::ClosedReason::kUnspecified);
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.h b/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.h
index f3317cb..b0162f56 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_drag_drop_notifier.h
@@ -19,12 +19,12 @@
 
   // DlpDataTransferNotifier::
   void NotifyBlockedAction(
-      const ui::DataTransferEndpoint* const data_src,
-      const ui::DataTransferEndpoint* const data_dst) override;
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst) override;
 
   // Warns the user that this drop action is not recommended.
-  void WarnOnDrop(const ui::DataTransferEndpoint* const data_src,
-                  const ui::DataTransferEndpoint* const data_dst,
+  void WarnOnDrop(base::optional_ref<const ui::DataTransferEndpoint> data_src,
+                  base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                   base::OnceClosure drop_cb);
 
  protected:
diff --git a/chrome/browser/client_hints/client_hints_browsertest.cc b/chrome/browser/client_hints/client_hints_browsertest.cc
index 0712740..89f9dd1 100644
--- a/chrome/browser/client_hints/client_hints_browsertest.cc
+++ b/chrome/browser/client_hints/client_hints_browsertest.cc
@@ -1874,7 +1874,7 @@
   EXPECT_EQ(main_frame_ua_platform_observed(), "\"" + ua.platform + "\"");
   EXPECT_EQ(main_frame_save_data_observed(), "");
 
-  // Second request: table override, all hints.
+  // Second request: tablet override, all hints.
   chrome::ToggleRequestTabletSite(browser());
   SetClientHintExpectationsOnMainFrame(true);
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), gurl));
@@ -1885,7 +1885,7 @@
   EXPECT_EQ(main_frame_ua_full_version_list_observed(),
             expected_full_version_list);
   EXPECT_EQ(main_frame_ua_mobile_observed(), "?1");
-  EXPECT_EQ(main_frame_ua_form_factor_observed(), "\"Mobile\"");
+  EXPECT_EQ(main_frame_ua_form_factor_observed(), "\"Tablet\"");
   EXPECT_EQ(main_frame_ua_platform_observed(), "\"Android\"");
   EXPECT_EQ(main_frame_save_data_observed(), "");
 }
diff --git a/chrome/browser/compose/compose_dialog_browsertest.cc b/chrome/browser/compose/compose_dialog_browsertest.cc
index 4487159..c52e52a0 100644
--- a/chrome/browser/compose/compose_dialog_browsertest.cc
+++ b/chrome/browser/compose/compose_dialog_browsertest.cc
@@ -39,7 +39,14 @@
   base::test::ScopedFeatureList feature_list_;
 };
 
-IN_PROC_BROWSER_TEST_F(ComposeSessionBrowserTest, LifetimeOfBubbleWrapper) {
+#if BUILDFLAG(IS_MAC)
+// Mac failures: b/311208586
+#define MAYBE_LifetimeOfBubbleWrapper DISABLED_LifetimeOfBubbleWrapper
+#else
+#define MAYBE_LifetimeOfBubbleWrapper LifetimeOfBubbleWrapper
+#endif
+IN_PROC_BROWSER_TEST_F(ComposeSessionBrowserTest,
+                       MAYBE_LifetimeOfBubbleWrapper) {
   ASSERT_TRUE(embedded_test_server()->Start());
   auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
diff --git a/chrome/browser/dips/dips_bounce_detector_browsertest.cc b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
index b61fd9a..8bc082c 100644
--- a/chrome/browser/dips/dips_bounce_detector_browsertest.cc
+++ b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
@@ -1930,6 +1930,9 @@
       web_contents, first_party_url));
   EndRedirectChain();
 
+  // Wait on async tasks for the grants to be created.
+  WaitOnStorage(GetDipsService(web_contents));
+
   // Expect some cookie grants on `first_party_url` based on flags and criteria.
   EXPECT_EQ(cookie_settings->GetCookieSetting(
                 aba_current_interaction_url, first_party_url,
@@ -1988,6 +1991,9 @@
       web_contents, first_party_url));
   EndRedirectChain();
 
+  // Wait on async tasks for the grants to be created.
+  WaitOnStorage(GetDipsService(web_contents));
+
   // Expect some cookie grants on `first_party_url` based on flags and criteria.
   EXPECT_EQ(cookie_settings->GetCookieSetting(
                 aba_past_interaction_url, first_party_url,
diff --git a/chrome/browser/enterprise/connectors/analysis/BUILD.gn b/chrome/browser/enterprise/connectors/analysis/BUILD.gn
index 3815046..6047c02 100644
--- a/chrome/browser/enterprise/connectors/analysis/BUILD.gn
+++ b/chrome/browser/enterprise/connectors/analysis/BUILD.gn
@@ -22,22 +22,3 @@
     "//third_party/content_analysis_sdk:liblcasdk",
   ]
 }
-
-source_set("test_support") {
-  testonly = true
-  sources = [
-    "fake_content_analysis_sdk_client.cc",
-    "fake_content_analysis_sdk_client.h",
-    "fake_content_analysis_sdk_manager.cc",
-    "fake_content_analysis_sdk_manager.h",
-  ]
-
-  # This data is needed so that the agent binary gets installed on test bots
-  # when it is not the same as the build bot.
-  data_deps = [ "//third_party/content_analysis_sdk:lca_agent" ]
-
-  public_deps = [
-    ":sdk_manager",
-    "//third_party/content_analysis_sdk:lca_agent",
-  ]
-}
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc
index f5f76b9..13e92fb 100644
--- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc
+++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_browsertest.cc
@@ -39,7 +39,7 @@
 #include "content/public/test/browser_test.h"
 
 #if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
-#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h"  // nogncheck
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h"  // nogncheck
 #endif
 
 using extensions::SafeBrowsingPrivateEventRouter;
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_unittest.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_unittest.cc
index bbe14f8..20503ee 100644
--- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_unittest.cc
+++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate_unittest.cc
@@ -46,7 +46,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
-#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h"  // nogncheck
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h"  // nogncheck
 #endif
 
 namespace enterprise_connectors {
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_sdk_manager_unittest.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_sdk_manager_unittest.cc
index ca5c481..b619798f 100644
--- a/chrome/browser/enterprise/connectors/analysis/content_analysis_sdk_manager_unittest.cc
+++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_sdk_manager_unittest.cc
@@ -4,8 +4,8 @@
 
 #include "chrome/browser/enterprise/connectors/analysis/content_analysis_sdk_manager.h"
 
-#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_client.h"
-#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h"
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_client.h"
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h"
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
diff --git a/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service_unittest.cc b/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service_unittest.cc
index dc7c6e1..3c7362e 100644
--- a/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service_unittest.cc
+++ b/chrome/browser/enterprise/connectors/analysis/local_binary_upload_service_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/task/sequenced_task_runner.h"
 #include "build/build_config.h"
 #include "chrome/browser/enterprise/connectors/analysis/analysis_settings.h"
-#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h"
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/device_signals/core/browser/mock_system_signals_service_host.h"
 #include "content/public/test/browser_task_environment.h"
diff --git a/chrome/browser/enterprise/connectors/analysis/print_content_analysis_utils_unittest.cc b/chrome/browser/enterprise/connectors/analysis/print_content_analysis_utils_unittest.cc
index 9cf71ac..bfb72e57 100644
--- a/chrome/browser/enterprise/connectors/analysis/print_content_analysis_utils_unittest.cc
+++ b/chrome/browser/enterprise/connectors/analysis/print_content_analysis_utils_unittest.cc
@@ -26,7 +26,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 
 #if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
-#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h"  // nogncheck
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h"  // nogncheck
 #endif
 
 namespace enterprise_connectors {
diff --git a/chrome/browser/enterprise/connectors/connectors_manager_unittest.cc b/chrome/browser/enterprise/connectors/connectors_manager_unittest.cc
index c06464c..6827c4c 100644
--- a/chrome/browser/enterprise/connectors/connectors_manager_unittest.cc
+++ b/chrome/browser/enterprise/connectors/connectors_manager_unittest.cc
@@ -37,7 +37,7 @@
 #endif
 
 #if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
-#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h"  // nogncheck
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h"  // nogncheck
 #endif
 
 namespace enterprise_connectors {
diff --git a/chrome/browser/enterprise/connectors/test/BUILD.gn b/chrome/browser/enterprise/connectors/test/BUILD.gn
index 21b62f77..b2bf5a2b 100644
--- a/chrome/browser/enterprise/connectors/test/BUILD.gn
+++ b/chrome/browser/enterprise/connectors/test/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 import("//build/config/chromeos/ui_mode.gni")
+import("//components/enterprise/buildflags/buildflags.gni")
 
 source_set("test_support") {
   testonly = true
@@ -49,6 +50,26 @@
     "//components/prefs",
   ]
 
+  if (enterprise_local_content_analysis) {
+    public += [
+      "fake_content_analysis_sdk_client.h",
+      "fake_content_analysis_sdk_manager.h",
+    ]
+    sources += [
+      "fake_content_analysis_sdk_client.cc",
+      "fake_content_analysis_sdk_manager.cc",
+    ]
+
+    # This data is needed so that the agent binary gets installed on test bots
+    # when it is not the same as the build bot.
+    data_deps = [ "//third_party/content_analysis_sdk:lca_agent" ]
+
+    public_deps += [
+      "//third_party/content_analysis_sdk:lca_agent",
+      "//third_party/content_analysis_sdk:liblcasdk",
+    ]
+  }
+
   if (is_win || is_linux || is_mac || is_chromeos_lacros) {
     public += [ "browser/management_context_mixin_browser.h" ]
     sources += [ "browser/management_context_mixin_browser.cc" ]
diff --git a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_client.cc b/chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_client.cc
similarity index 96%
rename from chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_client.cc
rename to chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_client.cc
index dbc8cd3..a0bf1d6 100644
--- a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_client.cc
+++ b/chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_client.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 "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_client.h"
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_client.h"
 
 namespace enterprise_connectors {
 
diff --git a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_client.h b/chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_client.h
similarity index 89%
rename from chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_client.h
rename to chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_client.h
index d1e8f5a..d44c13c 100644
--- a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_client.h
+++ b/chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_client.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_ANALYSIS_FAKE_CONTENT_ANALYSIS_SDK_CLIENT_H_
-#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_ANALYSIS_FAKE_CONTENT_ANALYSIS_SDK_CLIENT_H_
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_TEST_FAKE_CONTENT_ANALYSIS_SDK_CLIENT_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_TEST_FAKE_CONTENT_ANALYSIS_SDK_CLIENT_H_
 
 #include "base/synchronization/lock.h"
 #include "third_party/content_analysis_sdk/src/browser/include/content_analysis/sdk/analysis_client.h"
@@ -67,4 +67,4 @@
 
 }  // namespace enterprise_connectors
 
-#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_ANALYSIS_FAKE_CONTENT_ANALYSIS_SDK_CLIENT_H_
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_TEST_FAKE_CONTENT_ANALYSIS_SDK_CLIENT_H_
diff --git a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.cc b/chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.cc
similarity index 92%
rename from chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.cc
rename to chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.cc
index 682557b..1db0ce14 100644
--- a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.cc
+++ b/chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.cc
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h"
-#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_client.h"
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h"
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_client.h"
 
 #include <cstddef>
 
diff --git a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h b/chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h
similarity index 84%
rename from chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h
rename to chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h
index 48248c45..99ffaaa4 100644
--- a/chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h
+++ b/chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_ANALYSIS_FAKE_CONTENT_ANALYSIS_SDK_MANAGER_H_
-#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_ANALYSIS_FAKE_CONTENT_ANALYSIS_SDK_MANAGER_H_
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_TEST_FAKE_CONTENT_ANALYSIS_SDK_MANAGER_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_TEST_FAKE_CONTENT_ANALYSIS_SDK_MANAGER_H_
 
 #include "chrome/browser/enterprise/connectors/analysis/content_analysis_sdk_manager.h"
-#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_client.h"
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_client.h"
 #include "third_party/content_analysis_sdk/src/browser/include/content_analysis/sdk/analysis_client.h"
 
 namespace enterprise_connectors {
@@ -64,4 +64,4 @@
 
 }  // namespace enterprise_connectors
 
-#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_ANALYSIS_FAKE_CONTENT_ANALYSIS_SDK_MANAGER_H_
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_TEST_FAKE_CONTENT_ANALYSIS_SDK_MANAGER_H_
diff --git a/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator.cc b/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator.cc
index c2afbcf..4948e6a 100644
--- a/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator.cc
+++ b/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator.cc
@@ -3,9 +3,36 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator.h"
+#include "components/enterprise/common/proto/legacy_tech_events.pb.h"
 
 namespace enterprise_reporting {
 
+LegacyTechReportGenerator::LegacyTechCookieIssueDetails::
+    LegacyTechCookieIssueDetails() = default;
+LegacyTechReportGenerator::LegacyTechCookieIssueDetails::
+    LegacyTechCookieIssueDetails(const std::string& transfer_or_script_url,
+                                 const std::string& name,
+                                 const std::string& domain,
+                                 const std::string& path,
+                                 AccessOperation access_operation)
+    : transfer_or_script_url(transfer_or_script_url),
+      name(name),
+      domain(domain),
+      path(path),
+      access_operation(access_operation) {}
+
+LegacyTechReportGenerator::LegacyTechCookieIssueDetails::
+    LegacyTechCookieIssueDetails(LegacyTechCookieIssueDetails&& other) =
+        default;
+LegacyTechReportGenerator::LegacyTechCookieIssueDetails&
+LegacyTechReportGenerator::LegacyTechCookieIssueDetails::operator=(
+    LegacyTechCookieIssueDetails&& other) = default;
+LegacyTechReportGenerator::LegacyTechCookieIssueDetails::
+    ~LegacyTechCookieIssueDetails() = default;
+
+bool LegacyTechReportGenerator::LegacyTechCookieIssueDetails::operator==(
+    const LegacyTechCookieIssueDetails& other) const = default;
+
 LegacyTechReportGenerator::LegacyTechData::LegacyTechData() = default;
 LegacyTechReportGenerator::LegacyTechData::LegacyTechData(
     const std::string& type,
@@ -14,19 +41,27 @@
     const std::string& matched_url,
     const std::string& filename,
     uint64_t line,
-    uint64_t column)
+    uint64_t column,
+    std::optional<LegacyTechCookieIssueDetails> cookie_issue_details)
     : type(type),
       timestamp(timestamp),
       url(url),
       matched_url(matched_url),
       filename(filename),
       line(line),
-      column(column) {}
+      column(column),
+      cookie_issue_details(std::move(cookie_issue_details)) {}
 
 LegacyTechReportGenerator::LegacyTechData::LegacyTechData(
-    const LegacyTechData& other) = default;
+    LegacyTechData&& other) = default;
+LegacyTechReportGenerator::LegacyTechData&
+LegacyTechReportGenerator::LegacyTechData::operator=(LegacyTechData&& other) =
+    default;
 LegacyTechReportGenerator::LegacyTechData::~LegacyTechData() = default;
 
+bool LegacyTechReportGenerator::LegacyTechData::operator==(
+    const LegacyTechData& other) const = default;
+
 LegacyTechReportGenerator::LegacyTechReportGenerator() = default;
 LegacyTechReportGenerator::~LegacyTechReportGenerator() = default;
 
@@ -44,6 +79,31 @@
   report->set_filename(legacy_tech_data.filename);
   report->set_column(legacy_tech_data.column);
   report->set_line(legacy_tech_data.line);
+
+  if (legacy_tech_data.cookie_issue_details) {
+    const LegacyTechCookieIssueDetails& cookie_issue_data =
+        *legacy_tech_data.cookie_issue_details;
+    CookieIssueDetails* cookie_issue_report =
+        report->mutable_cookie_issue_details();
+
+    cookie_issue_report->set_transfer_or_script_url(
+        cookie_issue_data.transfer_or_script_url);
+    cookie_issue_report->set_name(cookie_issue_data.name);
+    cookie_issue_report->set_domain(cookie_issue_data.domain);
+    cookie_issue_report->set_path(cookie_issue_data.path);
+
+    switch (cookie_issue_data.access_operation) {
+      case LegacyTechCookieIssueDetails::AccessOperation::kRead:
+        cookie_issue_report->set_access_operation(
+            CookieAccessOperation::COOKIE_ACCESS_OPERATION_READ);
+        break;
+      case LegacyTechCookieIssueDetails::AccessOperation::kWrite:
+        cookie_issue_report->set_access_operation(
+            CookieAccessOperation::COOKIE_ACCESS_OPERATION_WRITE);
+        break;
+    }
+  }
+
   return report;
 }
 
diff --git a/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator.h b/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator.h
index 844d91b..eb3dc29 100644
--- a/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator.h
+++ b/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_ENTERPRISE_REPORTING_LEGACY_TECH_LEGACY_TECH_REPORT_GENERATOR_H_
 
 #include <memory>
+#include <optional>
 #include <string>
 #include <vector>
 
@@ -19,19 +20,49 @@
 
 class LegacyTechReportGenerator {
  public:
+  struct LegacyTechCookieIssueDetails {
+    enum AccessOperation { kRead, kWrite };
+    LegacyTechCookieIssueDetails();
+    LegacyTechCookieIssueDetails(const std::string& transfer_or_script_url,
+                                 const std::string& name,
+                                 const std::string& domain,
+                                 const std::string& path,
+                                 AccessOperation access_operation);
+    LegacyTechCookieIssueDetails(const LegacyTechCookieIssueDetails&) = delete;
+    LegacyTechCookieIssueDetails(LegacyTechCookieIssueDetails&& other);
+    LegacyTechCookieIssueDetails& operator=(
+        const LegacyTechCookieIssueDetails&) = delete;
+    LegacyTechCookieIssueDetails& operator=(
+        LegacyTechCookieIssueDetails&& other);
+    ~LegacyTechCookieIssueDetails();
+
+    bool operator==(const LegacyTechCookieIssueDetails& other) const;
+
+    std::string transfer_or_script_url;
+    std::string name;
+    std::string domain;
+    std::string path;
+    AccessOperation access_operation;
+  };
+
   struct LegacyTechData : public RealTimeReportGenerator::Data {
     LegacyTechData();
-    LegacyTechData(const std::string& type,
-                   const base::Time& timestamp,
-                   const GURL& url,
-                   const std::string& matched_url,
-                   const std::string& filename,
-                   uint64_t line,
-                   uint64_t column);
-    LegacyTechData(const LegacyTechData& other);
+    LegacyTechData(
+        const std::string& type,
+        const base::Time& timestamp,
+        const GURL& url,
+        const std::string& matched_url,
+        const std::string& filename,
+        uint64_t line,
+        uint64_t column,
+        std::optional<LegacyTechCookieIssueDetails> cookie_issue_details);
+    LegacyTechData(const LegacyTechData&) = delete;
+    LegacyTechData(LegacyTechData&& other);
+    LegacyTechData& operator=(const LegacyTechData&) = delete;
+    LegacyTechData& operator=(LegacyTechData&& other);
     ~LegacyTechData();
 
-    bool operator==(const LegacyTechData&) const = default;
+    bool operator==(const LegacyTechData& other) const;
 
     std::string type;
     base::Time timestamp;
@@ -40,6 +71,7 @@
     std::string filename;
     uint64_t line;
     uint64_t column;
+    std::optional<LegacyTechCookieIssueDetails> cookie_issue_details;
   };
 
   LegacyTechReportGenerator();
diff --git a/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator_unittest.cc b/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator_unittest.cc
index b2b05f0..1750855 100644
--- a/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator_unittest.cc
+++ b/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator_unittest.cc
@@ -4,7 +4,10 @@
 
 #include "chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator.h"
 
+#include <optional>
+
 #include "base/time/time.h"
+#include "components/enterprise/common/proto/legacy_tech_events.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -25,6 +28,18 @@
                                                       .day_of_week = 4,
                                                       .day_of_month = 4};
 
+constexpr char kType[] = "type";
+constexpr char kUrl[] = "https://www.example.com/path";
+constexpr char kMatchedUrl[] = "www.example.com";
+constexpr char kFileName[] = "filename.js";
+constexpr uint64_t kLine = 10;
+constexpr uint64_t kColumn = 42;
+
+constexpr char kCookieTransferOrScriptUrl[] = "script url";
+constexpr char kCookieName[] = "cookie name";
+constexpr char kCookieDomain[] = "cookie domain";
+constexpr char kCookiePath[] = "cookie path";
+
 }  // namespace
 
 class LegacyTechGeneratorTest : public ::testing::Test {
@@ -35,28 +50,98 @@
 
 TEST_F(LegacyTechGeneratorTest, Test) {
   LegacyTechReportGenerator::LegacyTechData data = {
-      /*type=*/"type",
+      /*type=*/kType,
       /*timestamp=*/base::Time(),
-      /*url=*/GURL("https://www.example.com/path"),
-      /*matched_url=*/"www.example.com",
-      /*filename=*/"filename.js",
-      /*line=*/10,
-      /*column=*/42};
+      /*url=*/GURL(kUrl),
+      /*matched_url=*/kMatchedUrl,
+      /*filename=*/kFileName,
+      /*line=*/kLine,
+      /*column=*/kColumn,
+      /*cookie_issue_details=*/std::nullopt};
   ASSERT_TRUE(base::Time::FromUTCExploded(kTestDate, &data.timestamp));
 
   LegacyTechReportGenerator generator;
-  auto report = generator.Generate(data);
+  std::unique_ptr<LegacyTechEvent> report = generator.Generate(data);
 
-  EXPECT_EQ(data.type, report->feature_id());
-  EXPECT_EQ(data.url.spec(), report->url());
-  EXPECT_EQ(data.matched_url, report->allowlisted_url_match());
-  EXPECT_EQ(data.filename, report->filename());
-  EXPECT_EQ(data.column, report->column());
-  EXPECT_EQ(data.line, report->line());
+  EXPECT_EQ(kType, report->feature_id());
+  EXPECT_EQ(kUrl, report->url());
+  EXPECT_EQ(kMatchedUrl, report->allowlisted_url_match());
+  EXPECT_EQ(kFileName, report->filename());
+  EXPECT_EQ(kColumn, report->column());
+  EXPECT_EQ(kLine, report->line());
+
+  EXPECT_FALSE(report->has_cookie_issue_details());
+
   base::Time midnight;
   ASSERT_TRUE(base::Time::FromUTCExploded(kTestDateInMidnight, &midnight));
   EXPECT_EQ(midnight.InMillisecondsSinceUnixEpoch(),
             report->event_timestamp_millis());
 }
 
+TEST_F(LegacyTechGeneratorTest, TestWithCookieIssueDetailsRead) {
+  LegacyTechReportGenerator::LegacyTechCookieIssueDetails cookie_issue_details =
+      {
+          kCookieTransferOrScriptUrl,
+          kCookieName,
+          kCookieDomain,
+          kCookiePath,
+          LegacyTechReportGenerator::LegacyTechCookieIssueDetails::
+              AccessOperation::kRead,
+      };
+
+  LegacyTechReportGenerator::LegacyTechData data = {
+      /*type=*/kType,
+      /*timestamp=*/base::Time(),
+      /*url=*/GURL(kUrl),
+      /*matched_url=*/kMatchedUrl,
+      /*filename=*/kFileName,
+      /*line=*/kLine,
+      /*column=*/kColumn,
+      /*cookie_issue_details=*/
+      std::move(cookie_issue_details)};
+  ASSERT_TRUE(base::Time::FromUTCExploded(kTestDate, &data.timestamp));
+
+  LegacyTechReportGenerator generator;
+  std::unique_ptr<LegacyTechEvent> report = generator.Generate(data);
+
+  EXPECT_TRUE(report->has_cookie_issue_details());
+  EXPECT_EQ(kCookieTransferOrScriptUrl,
+            report->cookie_issue_details().transfer_or_script_url());
+  EXPECT_EQ(kCookieName, report->cookie_issue_details().name());
+  EXPECT_EQ(kCookieDomain, report->cookie_issue_details().domain());
+  EXPECT_EQ(kCookiePath, report->cookie_issue_details().path());
+  EXPECT_EQ(CookieAccessOperation::COOKIE_ACCESS_OPERATION_READ,
+            report->cookie_issue_details().access_operation());
+}
+
+TEST_F(LegacyTechGeneratorTest, TestWithCookieIssueDetailsWrite) {
+  LegacyTechReportGenerator::LegacyTechCookieIssueDetails cookie_issue_details =
+      {
+          kCookieTransferOrScriptUrl,
+          kCookieName,
+          kCookieDomain,
+          kCookiePath,
+          LegacyTechReportGenerator::LegacyTechCookieIssueDetails::
+              AccessOperation::kWrite,
+      };
+
+  LegacyTechReportGenerator::LegacyTechData data = {
+      /*type=*/kType,
+      /*timestamp=*/base::Time(),
+      /*url=*/GURL(kUrl),
+      /*matched_url=*/kMatchedUrl,
+      /*filename=*/kFileName,
+      /*line=*/kLine,
+      /*column=*/kColumn,
+      /*cookie_issue_details=*/
+      std::move(cookie_issue_details)};
+  ASSERT_TRUE(base::Time::FromUTCExploded(kTestDate, &data.timestamp));
+
+  LegacyTechReportGenerator generator;
+  std::unique_ptr<LegacyTechEvent> report = generator.Generate(data);
+
+  EXPECT_EQ(CookieAccessOperation::COOKIE_ACCESS_OPERATION_WRITE,
+            report->cookie_issue_details().access_operation());
+}
+
 }  // namespace enterprise_reporting
diff --git a/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service.cc b/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service.cc
index 2a320f8..aeb12a0 100644
--- a/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service.cc
+++ b/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service.cc
@@ -4,6 +4,8 @@
 
 #include "chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service.h"
 
+#include <optional>
+
 #include "base/functional/bind.h"
 #include "base/no_destructor.h"
 #include "base/time/time.h"
@@ -41,9 +43,10 @@
       *matched_url,
       filename,
       line,
-      column};
+      column,
+      /*cookie_issue_details=*/std::nullopt};
 
-  trigger_.Run(data);
+  trigger_.Run(std::move(data));
 }
 
 // static
@@ -76,19 +79,19 @@
     LegacyTechReportTrigger&& trigger) {
   trigger_ = std::move(trigger);
   for (auto& data : pending_data_) {
-    trigger_.Run(data);
+    trigger_.Run(std::move(data));
   }
   pending_data_.clear();
 }
 
 void LegacyTechServiceFactory::ReportEventImpl(
-    const LegacyTechReportGenerator::LegacyTechData& data) {
+    LegacyTechReportGenerator::LegacyTechData data) {
   if (!trigger_) {
     // CBCM initialization is async, in case a report is triggered before.
-    pending_data_.push_back(data);
+    pending_data_.push_back(std::move(data));
     return;
   }
-  trigger_.Run(data);
+  trigger_.Run(std::move(data));
 }
 
 LegacyTechServiceFactory::LegacyTechServiceFactory()
diff --git a/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service.h b/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service.h
index 019d48f5..f82bbd6d 100644
--- a/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service.h
+++ b/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service.h
@@ -14,7 +14,7 @@
 namespace enterprise_reporting {
 
 using LegacyTechReportTrigger = base::RepeatingCallback<void(
-    const LegacyTechReportGenerator::LegacyTechData& data)>;
+    LegacyTechReportGenerator::LegacyTechData data)>;
 
 // A `KeyedService` provides an API that allows content layer to upload report.
 // It will trigger a report if the event URL matches the policy setting.
@@ -51,7 +51,7 @@
       content::BrowserContext* context) const override;
 
  private:
-  void ReportEventImpl(const LegacyTechReportGenerator::LegacyTechData& data);
+  void ReportEventImpl(LegacyTechReportGenerator::LegacyTechData data);
 
   friend base::NoDestructor<LegacyTechServiceFactory>;
 
diff --git a/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service_unittest.cc b/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service_unittest.cc
index ce26c5e..d42bad14 100644
--- a/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service_unittest.cc
+++ b/chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service_unittest.cc
@@ -3,6 +3,9 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_service.h"
+
+#include <functional>
+#include <optional>
 #include "base/functional/callback_forward.h"
 #include "chrome/browser/enterprise/reporting/legacy_tech/legacy_tech_report_generator.h"
 
@@ -18,6 +21,7 @@
 #include "url/gurl.h"
 
 using ::testing::_;
+using ::testing::Eq;
 
 namespace enterprise_reporting {
 
@@ -67,11 +71,16 @@
 
 TEST_F(LegacyTechServiceTest, MatchedAndUpload) {
   LegacyTechReportGenerator::LegacyTechData expected_data = {
-      "type",        base::Time::Now(), GURL("https://example.com"),
-      "example.com", "filename",        /*line=*/10,
-      /*column=*/42};
+      /*type=*/"type",
+      /*timestamp=*/base::Time::Now(),
+      /*url=*/GURL("https://example.com"),
+      /*matched_url=*/"example.com",
+      /*filename=*/"filename",
+      /*line=*/10,
+      /*column=*/42,
+      /*cookie_issue_details=*/std::nullopt};
 
-  EXPECT_CALL(mock_trigger_, Run(expected_data)).Times(1);
+  EXPECT_CALL(mock_trigger_, Run(Eq(std::ref(expected_data)))).Times(1);
   SetPolicy({"example.com"});
   LegacyTechServiceFactory::GetForProfile(&profile_)->ReportEvent(
       "type", GURL("https://example.com"), "filename",
@@ -81,7 +90,7 @@
 TEST_F(LegacyTechServiceTest, DelayedInitialization) {
   LegacyTechServiceFactory::GetInstance()->SetReportTrigger(
       base::RepeatingCallback<void(
-          const LegacyTechReportGenerator::LegacyTechData&)>());
+          LegacyTechReportGenerator::LegacyTechData)>());
   EXPECT_CALL(mock_trigger_, Run(_)).Times(0);
   SetPolicy({"example.com"});
   LegacyTechServiceFactory::GetForProfile(&profile_)->ReportEvent(
diff --git a/chrome/browser/enterprise/reporting/real_time_report_controller_android.cc b/chrome/browser/enterprise/reporting/real_time_report_controller_android.cc
index a216cc3..abb86db 100644
--- a/chrome/browser/enterprise/reporting/real_time_report_controller_android.cc
+++ b/chrome/browser/enterprise/reporting/real_time_report_controller_android.cc
@@ -26,9 +26,9 @@
 }
 
 void RealTimeReportControllerAndroid::TriggerLegacyTech(
-    const LegacyTechReportGenerator::LegacyTechData& data) {
+    LegacyTechReportGenerator::LegacyTechData data) {
   if (trigger_callback_) {
-    trigger_callback_.Run(RealTimeReportType::kLegacyTech, data);
+    trigger_callback_.Run(RealTimeReportType::kLegacyTech, std::move(data));
   }
 }
 
diff --git a/chrome/browser/enterprise/reporting/real_time_report_controller_android.h b/chrome/browser/enterprise/reporting/real_time_report_controller_android.h
index 05307eb..7e26e81 100644
--- a/chrome/browser/enterprise/reporting/real_time_report_controller_android.h
+++ b/chrome/browser/enterprise/reporting/real_time_report_controller_android.h
@@ -21,7 +21,7 @@
       const RealTimeReportControllerAndroid&) = delete;
   ~RealTimeReportControllerAndroid() override;
 
-  void TriggerLegacyTech(const LegacyTechReportGenerator::LegacyTechData& data);
+  void TriggerLegacyTech(LegacyTechReportGenerator::LegacyTechData data);
 
  private:
   // RealTimeReportController::Delegate
diff --git a/chrome/browser/enterprise/reporting/real_time_report_controller_desktop.cc b/chrome/browser/enterprise/reporting/real_time_report_controller_desktop.cc
index a7698a1..2a502745 100644
--- a/chrome/browser/enterprise/reporting/real_time_report_controller_desktop.cc
+++ b/chrome/browser/enterprise/reporting/real_time_report_controller_desktop.cc
@@ -60,9 +60,9 @@
 }
 
 void RealTimeReportControllerDesktop::TriggerLegacyTech(
-    const LegacyTechReportGenerator::LegacyTechData& data) {
+    LegacyTechReportGenerator::LegacyTechData data) {
   if (trigger_callback_) {
-    trigger_callback_.Run(RealTimeReportType::kLegacyTech, data);
+    trigger_callback_.Run(RealTimeReportType::kLegacyTech, std::move(data));
   }
 }
 
diff --git a/chrome/browser/enterprise/reporting/real_time_report_controller_desktop.h b/chrome/browser/enterprise/reporting/real_time_report_controller_desktop.h
index e2596ff0..0de3635 100644
--- a/chrome/browser/enterprise/reporting/real_time_report_controller_desktop.h
+++ b/chrome/browser/enterprise/reporting/real_time_report_controller_desktop.h
@@ -27,7 +27,7 @@
   void StopWatchingExtensionRequest() override;
 
   void TriggerExtensionRequest(Profile* profile);
-  void TriggerLegacyTech(const LegacyTechReportGenerator::LegacyTechData& data);
+  void TriggerLegacyTech(LegacyTechReportGenerator::LegacyTechData data);
 
  private:
   std::unique_ptr<ExtensionRequestObserverFactory>
diff --git a/chrome/browser/enterprise/reporting/real_time_report_controller_unittest.cc b/chrome/browser/enterprise/reporting/real_time_report_controller_unittest.cc
index 9cc31b7..e58f7da 100644
--- a/chrome/browser/enterprise/reporting/real_time_report_controller_unittest.cc
+++ b/chrome/browser/enterprise/reporting/real_time_report_controller_unittest.cc
@@ -160,7 +160,7 @@
 
   static_cast<RealTimeReportControllerDelegate*>(
       report_controller.GetDelegateForTesting())
-      ->TriggerLegacyTech(data);
+      ->TriggerLegacyTech(std::move(data));
 }
 
 }  // namespace enterprise_reporting
diff --git a/chrome/browser/extensions/api/automation/automation_apitest.cc b/chrome/browser/extensions/api/automation/automation_apitest.cc
index e7ca0da..71d4c4f 100644
--- a/chrome/browser/extensions/api/automation/automation_apitest.cc
+++ b/chrome/browser/extensions/api/automation/automation_apitest.cc
@@ -57,8 +57,16 @@
 
 namespace extensions {
 
+using ContextType = ExtensionBrowserTest::ContextType;
+
 class AutomationApiTest : public ExtensionApiTest {
  public:
+  explicit AutomationApiTest(ContextType context_type = ContextType::kNone)
+      : ExtensionApiTest(context_type) {}
+  ~AutomationApiTest() override = default;
+  AutomationApiTest(const AutomationApiTest&) = delete;
+  AutomationApiTest& operator=(const AutomationApiTest&) = delete;
+
   void SetUpOnMainThread() override {
     ExtensionApiTest::SetUpOnMainThread();
     host_resolver()->AddRule("*", "127.0.0.1");
@@ -94,24 +102,46 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 };
 
+class AutomationApiTestWithContextType
+    : public AutomationApiTest,
+      public testing::WithParamInterface<ContextType> {
+ public:
+  AutomationApiTestWithContextType() : AutomationApiTest(GetParam()) {}
+  ~AutomationApiTestWithContextType() override = default;
+  AutomationApiTestWithContextType(const AutomationApiTestWithContextType&) =
+      delete;
+  AutomationApiTestWithContextType& operator=(
+      const AutomationApiTestWithContextType&) = delete;
+};
+
 // Canvas tests rely on the harness producing pixel output in order to read back
 // pixels from a canvas element. So we have to override the setup function.
 class AutomationApiCanvasTest : public AutomationApiTest {
  public:
   void SetUp() override {
     EnablePixelOutput();
-    ExtensionApiTest::SetUp();
+    AutomationApiTest::SetUp();
   }
 };
 
 #if defined(USE_AURA)
 
+// TODO(crbug.com/1093066): This should be moved outside of the USE_AURA
+// block when tests are converted that are outside of this block.
+INSTANTIATE_TEST_SUITE_P(PersistentBackground,
+                         AutomationApiTestWithContextType,
+                         ::testing::Values(ContextType::kPersistentBackground));
+INSTANTIATE_TEST_SUITE_P(ServiceWorker,
+                         AutomationApiTestWithContextType,
+                         ::testing::Values(ContextType::kServiceWorker));
+
 namespace {
 static const char kDomain[] = "a.com";
 static const char kGotTree[] = "got_tree";
 }  // anonymous namespace
 
-IN_PROC_BROWSER_TEST_F(AutomationApiTest, TestRendererAccessibilityEnabled) {
+IN_PROC_BROWSER_TEST_P(AutomationApiTestWithContextType,
+                       TestRendererAccessibilityEnabled) {
   StartEmbeddedTestServer();
   const GURL url = GetURLForPath(kDomain, "/index.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
@@ -160,7 +190,7 @@
       << message_;
 }
 
-IN_PROC_BROWSER_TEST_F(AutomationApiTest, ImageLabels) {
+IN_PROC_BROWSER_TEST_P(AutomationApiTestWithContextType, ImageLabels) {
   StartEmbeddedTestServer();
   const GURL url = GetURLForPath(kDomain, "/index.html");
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url));
diff --git a/chrome/browser/extensions/extension_context_menu_model.cc b/chrome/browser/extensions/extension_context_menu_model.cc
index a1f50a5..47761b8 100644
--- a/chrome/browser/extensions/extension_context_menu_model.cc
+++ b/chrome/browser/extensions/extension_context_menu_model.cc
@@ -552,8 +552,9 @@
   AppendExtensionItems();
 
   // Site permissions section.
-  bool policy_entry_in_subpage = false;
   bool is_required_by_policy = IsExtensionRequiredByPolicy(extension, profile_);
+  bool has_policy_entry = !is_component_ && is_required_by_policy;
+  bool policy_entry_in_subpage = false;
 
   // Show section only when the extension requests host permissions.
   auto* permissions_manager = PermissionsManager::Get(profile_);
@@ -610,13 +611,18 @@
           IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_RUN_ON_ALL_SITES_V2,
           kRadioGroup);
 
-      // When the page access submenu is visible, it holds the policy entry.
-      page_access_submenu_->AddSeparator(ui::NORMAL_SEPARATOR);
-      page_access_submenu_->AddItemWithStringIdAndIcon(
-          POLICY_INSTALLED, IDS_EXTENSIONS_INSTALLED_BY_ADMIN,
-          ui::ImageModel::FromVectorIcon(vector_icons::kBusinessIcon,
-                                         ui::kColorIcon, 16));
-      policy_entry_in_subpage = true;
+      // We show the page access menu for force-installed extensions that
+      // modify sites other than those the user opted into all extensions
+      // modifying. In these cases, we indicate that the extension is installed
+      // by the admin through a menu entry.
+      if (has_policy_entry) {
+        page_access_submenu_->AddSeparator(ui::NORMAL_SEPARATOR);
+        page_access_submenu_->AddItemWithStringIdAndIcon(
+            POLICY_INSTALLED, IDS_EXTENSIONS_INSTALLED_BY_ADMIN,
+            ui::ImageModel::FromVectorIcon(vector_icons::kBusinessIcon,
+                                           ui::kColorIcon, 16));
+        policy_entry_in_subpage = true;
+      }
 
       AddSubMenuWithStringId(PAGE_ACCESS_SUBMENU,
                              IDS_EXTENSIONS_CONTEXT_MENU_SITE_PERMISSIONS,
@@ -630,8 +636,9 @@
         IDS_EXTENSIONS_CONTEXT_MENU_PAGE_ACCESS_PERMISSIONS_PAGE);
   }
 
-  // Policy section.
-  if (!is_component_ && is_required_by_policy && !policy_entry_in_subpage) {
+  // If there isn't an entry for the extension being force-installed in the
+  // page access menu above, we add one to the root menu here.
+  if (has_policy_entry && !policy_entry_in_subpage) {
     AddSeparator(ui::NORMAL_SEPARATOR);
     // TODO (kylixrd): Investigate the usage of the hard-coded color.
     AddItemWithStringIdAndIcon(
diff --git a/chrome/browser/extensions/extension_context_menu_model_unittest.cc b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
index 6f02d91..624f5ba1 100644
--- a/chrome/browser/extensions/extension_context_menu_model_unittest.cc
+++ b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
@@ -2151,6 +2151,111 @@
   }
 }
 
+TEST_P(ExtensionContextMenuModelWithUserHostControlsTest,
+       PolicyInstalledEntryVisibilityBasedOnSiteSettings) {
+  bool is_feature_enabled = GetParam();
+  InitializeEmptyExtensionService();
+
+  const Extension* extension =
+      AddExtensionWithHostPermission("Extension", manifest_keys::kBrowserAction,
+                                     ManifestLocation::kInternal, "<all_urls>");
+  const Extension* enterprise_extension =
+      AddExtension("Enterprise extension", manifest_keys::kBrowserAction,
+                   ManifestLocation::kExternalPolicy);
+  const Extension* enterprise_extension_host_permissions =
+      AddExtensionWithHostPermission(
+          "Enterprise extension requesting host permissions",
+          manifest_keys::kBrowserAction, ManifestLocation::kExternalPolicy,
+          "<all_urls>");
+
+  // Add a tab to the browser.
+  const GURL url("http://www.example.com/");
+  AddTab(url);
+
+  {
+    // Non-enterprise extension has no policy entry.
+    ExtensionContextMenuModel menu(extension, GetBrowser(),
+                                   /*is_pinned=*/true, nullptr, true,
+                                   ContextMenuSource::kToolbarAction);
+    EXPECT_EQ(GetPageAccessCommandState(menu, kPolicyInstalled),
+              CommandState::kAbsent);
+    EXPECT_EQ(GetCommandState(menu, kPolicyInstalled), CommandState::kAbsent);
+  }
+
+  {
+    // By default, the site permission is set to "customize by extension".
+    // Verify "policy installed" entry is visible and disabled in the main menu
+    // when extension doesn't request host permissions.
+    ExtensionContextMenuModel menu(enterprise_extension, GetBrowser(),
+                                   /*is_pinned=*/true, nullptr, true,
+                                   ContextMenuSource::kToolbarAction);
+    EXPECT_EQ(GetPageAccessCommandState(menu, kPolicyInstalled),
+              CommandState::kAbsent);
+    EXPECT_EQ(GetCommandState(menu, kPolicyInstalled), CommandState::kDisabled);
+
+    // Verify "policy installed" entry is visible and disabled when extension
+    // requests host permissions. Entry is in the page access submenu when the
+    // feature is enabled, otherwise is on the main menu.
+    ExtensionContextMenuModel menu_host_permissions(
+        enterprise_extension_host_permissions, GetBrowser(),
+        /*is_pinned=*/true, nullptr, true, ContextMenuSource::kToolbarAction);
+    if (is_feature_enabled) {
+      EXPECT_EQ(
+          GetPageAccessCommandState(menu_host_permissions, kPolicyInstalled),
+          CommandState::kDisabled);
+      EXPECT_EQ(GetCommandState(menu_host_permissions, kPolicyInstalled),
+                CommandState::kAbsent);
+    } else {
+      EXPECT_EQ(GetPageAccessCommandState(menu, kPolicyInstalled),
+                CommandState::kAbsent);
+      EXPECT_EQ(GetCommandState(menu, kPolicyInstalled),
+                CommandState::kDisabled);
+    }
+  }
+
+  // User site settings are only taken into account for site access computations
+  // when the feature is enabled, even if they are added by the manager.
+  // Therefore, the context menu should not take into account user site settings
+  // when the feature is disabled.
+  auto* manager = PermissionsManager::Get(profile());
+
+  {
+    // Add site as a user restricted site.
+    PermissionsManagerWaiter manager_waiter(manager);
+    manager->AddUserRestrictedSite(url::Origin::Create(url));
+    manager_waiter.WaitForUserPermissionsSettingsChange();
+
+    // Verify "policy installed" entry is visible and disabled in the main menu
+    // when extension doesn't request host permissions.
+    ExtensionContextMenuModel menu(enterprise_extension, GetBrowser(),
+                                   /*is_pinned=*/true, nullptr, true,
+                                   ContextMenuSource::kToolbarAction);
+    EXPECT_EQ(GetPageAccessCommandState(menu, kPolicyInstalled),
+              CommandState::kAbsent);
+    EXPECT_EQ(GetCommandState(menu, kPolicyInstalled), CommandState::kDisabled);
+
+    // Verify "policy installed" entry is visible and disabled when extension
+    // requests host permissions. Entry is in the page access submenu when the
+    // feature is enabled, otherwise is on the main menu.
+    ExtensionContextMenuModel menu_host_permissions(
+        enterprise_extension_host_permissions, GetBrowser(),
+        /*is_pinned=*/true, nullptr, true, ContextMenuSource::kToolbarAction);
+
+    if (is_feature_enabled) {
+      EXPECT_EQ(
+          GetPageAccessCommandState(menu_host_permissions, kPolicyInstalled),
+          CommandState::kDisabled);
+      EXPECT_EQ(GetCommandState(menu_host_permissions, kPolicyInstalled),
+                CommandState::kAbsent);
+    } else {
+      EXPECT_EQ(
+          GetPageAccessCommandState(menu_host_permissions, kPolicyInstalled),
+          CommandState::kAbsent);
+      EXPECT_EQ(GetCommandState(menu_host_permissions, kPolicyInstalled),
+                CommandState::kDisabled);
+    }
+  }
+}
 // Test clicking on the "permissions page" item opens the correct link.
 TEST_P(ExtensionContextMenuModelWithUserHostControlsTest,
        TestClickingPageAccessPermissionsPage) {
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index d84b4eb4..7de1340 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -555,6 +555,11 @@
     "expiry_milestone": 122
   },
   {
+    "name": "autofill-enable-card-benefits",
+    "owners": [ "alexandertekle@chromium.org", "yishuil@google.com" ],
+    "expiry_milestone": 130
+  },
+  {
     "name": "autofill-enable-card-product-name",
     "owners": [ "vishwasuppoor@chromium.org", "siyua@chromium.org", "alexandertekle@chromium.org" ],
     "expiry_milestone": 125
@@ -3496,6 +3501,11 @@
     "expiry_milestone": 130
   },
   {
+    "name": "enable-suspicious-site-detection-rt-lookups",
+    "owners": [ "skrakowi@chromium.org", "chrome-counter-abuse-alerts@google.com" ],
+    "expiry_milestone": 125
+  },
+  {
     "name": "enable-system-entropy",
     "owners": [ "mjackson@microsoft.com", "dmurph@chromium.org" ],
     "expiry_milestone": 125
@@ -6753,6 +6763,11 @@
     "expiry_milestone": 130
   },
   {
+    "name": "read-anything-omnibox-icon",
+    "owners": [ "abigailbklein@google.com", "jocelyntran@google.com", "//ui/accessibility/OWNERS" ],
+    "expiry_milestone": 130
+  },
+  {
     "name": "read-anything-read-aloud",
     "owners": [ "kristislee@google.com", "lwinston@google.com", "//ui/accessibility/OWNERS" ],
     "expiry_milestone": 133
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index e9c0b67..6695298 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -482,6 +482,11 @@
     "images of the exact required dimensions. The client side resizing of "
     "images will not be required.";
 
+const char kAutofillEnableCardBenefitsName[] = "Enable showing card benefits";
+const char kAutofillEnableCardBenefitsDescription[] =
+    "When enabled, card benefits offered by issuers will be shown in "
+    "Payments Autofill UI.";
+
 const char kAutofillEnableCardProductNameName[] =
     "Enable showing card product name";
 const char kAutofillEnableCardProductNameDescription[] =
@@ -1261,6 +1266,11 @@
     "Enables red interstitial facelift UI changes, including icon, string, and "
     "style changes.";
 
+const char kEnableSuspiciousSiteDetectionRTLookupsName[] =
+    "Suspicious site detection RT lookups";
+const char kEnableSuspiciousSiteDetectionRTLookupsDescription[] =
+    "Enables suspicious site detection for real time URL lookups.";
+
 const char kEnableTailoredSecurityUpdatedMessagesName[] =
     "Enable tailored security updated messages";
 const char kEnableTailoredSecurityUpdatedMessagesDescription[] =
@@ -4755,6 +4765,11 @@
 const char kReadAnythingReadAloudDescription[] =
     "Enables the experimental Read Aloud feature in Reading Mode.";
 
+const char kReadAnythingOmniboxIconName[] = "Reading Mode with Omnibox Icon";
+const char kReadAnythingOmniboxIconDescription[] =
+    "Show the reading mode icon in the omnibox. Click the icon to open reading "
+    "mode.";
+
 const char kEnableWebHidOnExtensionServiceWorkerName[] =
     "Enable WebHID on extension service workers";
 const char kEnableWebHidOnExtensionServiceWorkerDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index aa3e5e7..e2b5e53 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -290,6 +290,9 @@
 extern const char kAutofillEnableCardArtServerSideStretchingName[];
 extern const char kAutofillEnableCardArtServerSideStretchingDescription[];
 
+extern const char kAutofillEnableCardBenefitsName[];
+extern const char kAutofillEnableCardBenefitsDescription[];
+
 extern const char kAutofillEnableCardProductNameName[];
 extern const char kAutofillEnableCardProductNameDescription[];
 
@@ -745,6 +748,9 @@
 extern const char kEnableRedInterstitialFaceliftName[];
 extern const char kEnableRedInterstitialFaceliftDescription[];
 
+extern const char kEnableSuspiciousSiteDetectionRTLookupsName[];
+extern const char kEnableSuspiciousSiteDetectionRTLookupsDescription[];
+
 extern const char kEnableTailoredSecurityUpdatedMessagesName[];
 extern const char kEnableTailoredSecurityUpdatedMessagesDescription[];
 
@@ -2752,6 +2758,9 @@
 extern const char kReadAnythingReadAloudName[];
 extern const char kReadAnythingReadAloudDescription[];
 
+extern const char kReadAnythingOmniboxIconName[];
+extern const char kReadAnythingOmniboxIconDescription[];
+
 extern const char kEnableWebHidOnExtensionServiceWorkerName[];
 extern const char kEnableWebHidOnExtensionServiceWorkerDescription[];
 
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_unittest.cc b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_unittest.cc
index 1dfa8394..39c2c49c 100644
--- a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_unittest.cc
+++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service_unittest.cc
@@ -455,7 +455,7 @@
   MockAddSinkResultCallback mock_callback;
   MediaSinkInternal cast_sink1 = CreateCastSink(1);
 
-  EXPECT_CALL(mock_callback, Run(AddSinkResultCode::OK, Eq("cast:<id1>")));
+  EXPECT_CALL(mock_callback, Run(AddSinkResultCode::OK, Eq("cast:id1")));
   access_code_cast_sink_service_->OnChannelOpenedResult(mock_callback.Get(),
                                                         cast_sink1, true);
 }
diff --git a/chrome/browser/media/router/discovery/discovery_network_monitor.cc b/chrome/browser/media/router/discovery/discovery_network_monitor.cc
index fe0caea..005b196 100644
--- a/chrome/browser/media/router/discovery/discovery_network_monitor.cc
+++ b/chrome/browser/media/router/discovery/discovery_network_monitor.cc
@@ -40,8 +40,8 @@
     combined_ids = combined_ids + "!" + network_info.network_id;
   }
 
-  std::string hash = base::SHA1HashString(combined_ids);
-  return base::ToLowerASCII(base::HexEncode(hash.data(), hash.length()));
+  auto hash = base::SHA1HashSpan(base::as_bytes(base::make_span(combined_ids)));
+  return base::ToLowerASCII(base::HexEncode(hash));
 }
 
 base::LazyInstance<DiscoveryNetworkMonitor>::Leaky g_discovery_monitor =
diff --git a/chrome/browser/media/router/mojo/media_sink_service_status.cc b/chrome/browser/media/router/mojo/media_sink_service_status.cc
index 5ff080d..72d91d10 100644
--- a/chrome/browser/media/router/mojo/media_sink_service_status.cc
+++ b/chrome/browser/media/router/mojo/media_sink_service_status.cc
@@ -5,20 +5,16 @@
 #include "chrome/browser/media/router/mojo/media_sink_service_status.h"
 
 #include "base/json/json_string_value_serializer.h"
-#include "base/numerics/safe_conversions.h"
 #include "base/strings/strcat.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/string_util.h"
+#include "components/media_router/browser/log_util.h"
 
 namespace media_router {
 
 namespace {
 
 constexpr size_t kMaxAvailableSinksSize = 100;
-constexpr char kCastPrefix[] = "cast:<";
-constexpr char kDialPrefix[] = "dial:<";
 
-// Helper function to convert |value| to JSON string.
+// Helper function to convert `value` to JSON string.
 std::string ToJSONString(const base::Value::Dict& value) {
   std::string json;
   JSONStringValueSerializer serializer(&json);
@@ -26,64 +22,38 @@
   return serializer.Serialize(value) ? json : "";
 }
 
-// Returns UUID if |sink_id| is in the format of "cast:<UUID>" or "dial:<UUID>";
-// otherwise returns |sink_id| as UUID.
-base::StringPiece ExtractUUID(const base::StringPiece& sink_id) {
-  if (!base::EndsWith(sink_id, ">"))
-    return sink_id;
-
-  size_t prefix_length = 0;
-  if (base::StartsWith(sink_id, kCastPrefix))
-    prefix_length = sizeof(kCastPrefix) - 1;
-  if (base::StartsWith(sink_id, kDialPrefix))
-    prefix_length = sizeof(kDialPrefix) - 1;
-
-  if (prefix_length == 0)
-    return sink_id;
-
-  base::StringPiece uuid = sink_id;
-  uuid.remove_prefix(prefix_length);
-  uuid.remove_suffix(1);
-  return uuid;
-}
-
-// Returns the last four characters of UUID. UUID is extracted from |sink_id|.
-std::string TruncateSinkId(const std::string& sink_id) {
-  std::string uuid(ExtractUUID(sink_id));
-  return uuid.length() <= 4 ? uuid : uuid.substr(uuid.length() - 4);
-}
-
-// Helper function to convert |sink_internal| to JSON format represented by
+// Helper function to convert `sink_internal` to JSON format represented by
 // base::Value::Dict.
 base::Value::Dict ToValue(const MediaSinkInternal& sink_internal) {
   base::Value::Dict dict;
   const MediaSink& sink = sink_internal.sink();
-  dict.Set("id", base::Value(TruncateSinkId(sink.id())));
-  dict.Set("name", base::Value(sink.name()));
-  dict.Set("icon_type", base::Value(static_cast<int>(sink.icon_type())));
+  dict.Set("id", log_util::TruncateId(sink.id()));
+  dict.Set("name", sink.name());
+  dict.Set("icon_type", static_cast<int>(sink.icon_type()));
 
   if (sink_internal.is_dial_sink()) {
     DialSinkExtraData extra_data = sink_internal.dial_data();
-    dict.Set("ip_address", base::Value(extra_data.ip_address.ToString()));
-    dict.Set("model_name", base::Value(extra_data.model_name));
-    dict.Set("app_url", base::Value(extra_data.app_url.spec()));
+    dict.Set("ip_address", extra_data.ip_address.ToString());
+    dict.Set("model_name", extra_data.model_name);
+    dict.Set("app_url", extra_data.app_url.spec());
   }
 
   if (sink_internal.is_cast_sink()) {
     CastSinkExtraData extra_data = sink_internal.cast_data();
-    dict.Set("ip_endpoint", base::Value(extra_data.ip_endpoint.ToString()));
-    dict.Set("model_name", base::Value(extra_data.model_name));
-    dict.Set("capabilities", base::Value(base::checked_cast<int>(
-                                 extra_data.capabilities.ToEnumBitmask())));
-    dict.Set("channel_id", base::Value(extra_data.cast_channel_id));
-    dict.Set("discovered_by_dial", base::Value(extra_data.discovery_type ==
-                                               CastDiscoveryType::kDial));
+    dict.Set("ip_endpoint", extra_data.ip_endpoint.ToString());
+    dict.Set("model_name", extra_data.model_name);
+    dict.Set("capabilities",
+             base::checked_cast<int>(extra_data.capabilities.ToEnumBitmask()));
+    dict.Set("channel_id", extra_data.cast_channel_id);
+    dict.Set("discovered_by_dial",
+             extra_data.discovery_type == CastDiscoveryType::kDial);
   }
   return dict;
 }
 
-// Helper function to convert |sinks| to JSON format represented by
-// base::Value::Dict.
+// Helper function to convert `sinks` to JSON format represented by
+// base::Value::Dict. The key is the source id and the value is a list of
+// sinks represented by base::Value::Dict.
 base::Value::Dict ConvertDiscoveredSinksToValues(
     const base::flat_map<std::string, std::vector<MediaSinkInternal>>& sinks) {
   base::Value::Dict dict;
@@ -96,8 +66,9 @@
   return dict;
 }
 
-// Helper function to convert |available_sinks| to a dictionary of availability
-// strings in JSON format represented by base::Value::Dict.
+// Helper function to convert `available_sinks` to a dictionary of availability
+// strings in JSON format represented by base::Value::Dict. The key is the
+// source id and the value is a list of sink ids.
 base::Value::Dict ConvertAvailableSinksToValues(
     const base::LRUCache<std::string, std::vector<MediaSinkInternal>>&
         available_sinks) {
@@ -106,7 +77,7 @@
     base::Value::List list;
     for (const auto& inner_sink : sinks_it.second) {
       std::string sink_id = inner_sink.sink().id();
-      list.Append(base::Value(TruncateSinkId(sink_id)));
+      list.Append(log_util::TruncateId(sink_id));
     }
     dict.Set(sinks_it.first, std::move(list));
   }
diff --git a/chrome/browser/media/router/mojo/media_sink_service_status_unittest.cc b/chrome/browser/media/router/mojo/media_sink_service_status_unittest.cc
index c03c14c2..2fef051 100644
--- a/chrome/browser/media/router/mojo/media_sink_service_status_unittest.cc
+++ b/chrome/browser/media/router/mojo/media_sink_service_status_unittest.cc
@@ -57,13 +57,13 @@
   const char expected_str[] = R"(
       {
         "available_sinks": {
-          "DIAL:dial:youtube" : ["3610", "id2"]
+          "DIAL:dial:youtube" : ["dial:de51", "dial:id2"]
         },
         "discovered_sinks": { }
       })";
 
   MediaSinkInternal dial_sink1 = CreateDialSink(1);
-  dial_sink1.sink().set_sink_id("dial:<de51d94921f15f8af6dbf65592bb3610>");
+  dial_sink1.sink().set_sink_id("dial:de51d94921f15f8af6dbf65592bb3610");
   MediaSinkInternal dial_sink2 = CreateDialSink(2);
   std::vector<MediaSinkInternal> available_sinks = {dial_sink1, dial_sink2};
 
@@ -84,7 +84,7 @@
             {
               "app_url":"http://192.168.0.101/apps",
               "icon_type":7,
-              "id":"id1",
+              "id":"dial:id1",
               "ip_address":"192.168.0.101",
               "model_name":"model name 1",
               "name":"friendly name 1"
@@ -92,7 +92,7 @@
             {
               "app_url":"http://192.168.0.102/apps",
               "icon_type":7,
-              "id":"id2",
+              "id":"dial:id2",
               "ip_address":"192.168.0.102",
               "model_name":"model name 2",
               "name":"friendly name 2"
@@ -116,15 +116,15 @@
   const char expected_str[] = R"(
       {
         "available_sinks": {
-          "CAST:cast:netflix" : ["id2"],
-          "DIAL:dial:youtube" : ["id1"]
+          "CAST:cast:netflix" : ["cast:id2"],
+          "DIAL:dial:youtube" : ["dial:id1"]
         },
         "discovered_sinks": {
           "dial": [
             {
               "app_url":"http://192.168.0.101/apps",
               "icon_type":7,
-              "id":"id1",
+              "id":"dial:id1",
               "ip_address":"192.168.0.101",
               "model_name":"model name 1",
               "name":"friendly name 1"
@@ -132,19 +132,21 @@
           ],
           "cast": [
             {
-              "app_url":"http://192.168.0.102/apps",
-              "icon_type":7,
-              "id":"id2",
-              "ip_address":"192.168.0.102",
-              "model_name":"model name 2",
-              "name":"friendly name 2"
+              "capabilities": 5,
+              "channel_id": 2,
+              "discovered_by_dial": false,
+              "icon_type": 0,
+              "id": "cast:id2",
+              "ip_endpoint": "192.168.0.102:8011",
+              "model_name": "model name 2",
+              "name": "friendly name 2"
             }
           ]
         }
       })";
 
   MediaSinkInternal dial_sink1 = CreateDialSink(1);
-  MediaSinkInternal dial_sink2 = CreateDialSink(2);
+  MediaSinkInternal dial_sink2 = CreateCastSink(2);
   std::vector<MediaSinkInternal> sinks1 = {dial_sink1};
   std::vector<MediaSinkInternal> sinks2 = {dial_sink2};
 
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_test_base.cc b/chrome/browser/media/router/providers/cast/cast_activity_test_base.cc
index aa4566a..4e382d5 100644
--- a/chrome/browser/media/router/providers/cast/cast_activity_test_base.cc
+++ b/chrome/browser/media/router/providers/cast/cast_activity_test_base.cc
@@ -55,7 +55,7 @@
 
 const char* const CastActivityTestBase::kAppId = "theAppId";
 const char* const CastActivityTestBase::kRouteId = "theRouteId";
-const char* const CastActivityTestBase::kSinkId = "cast:<id42>";
+const char* const CastActivityTestBase::kSinkId = "cast:id42";
 const char* const CastActivityTestBase::kHashToken = "dummyHashToken";
 
 CastActivityTestBase::CastActivityTestBase() = default;
diff --git a/chrome/browser/media/router/providers/cast/cast_internal_message_util_unittest.cc b/chrome/browser/media/router/providers/cast/cast_internal_message_util_unittest.cc
index 3eeb0cf..f246f8c 100644
--- a/chrome/browser/media/router/providers/cast/cast_internal_message_util_unittest.cc
+++ b/chrome/browser/media/router/providers/cast/cast_internal_message_util_unittest.cc
@@ -348,7 +348,7 @@
            "displayStatus": null,
            "friendlyName": "friendly name 1",
            "isActiveInput": null,
-           "label": "yYH_HCL9CKJFmvKJ9m3Une2cS8s",
+           "label": "Pr2CqqG4_NOPcVV6oKbocxyAik0",
            "receiverType": "cast",
            "volume": null
         }
@@ -373,7 +373,7 @@
            "displayStatus": null,
            "friendlyName": "friendly name 1",
            "isActiveInput": null,
-           "label": "yYH_HCL9CKJFmvKJ9m3Une2cS8s",
+           "label": "Pr2CqqG4_NOPcVV6oKbocxyAik0",
            "receiverType": "cast",
            "volume": null
         }
@@ -407,7 +407,7 @@
          "displayStatus": null,
          "friendlyName": "friendly name 1",
          "isActiveInput": null,
-         "label": "yYH_HCL9CKJFmvKJ9m3Une2cS8s",
+         "label": "Pr2CqqG4_NOPcVV6oKbocxyAik0",
          "receiverType": "cast",
          "volume": null
       },
@@ -445,7 +445,7 @@
          "displayStatus": null,
          "friendlyName": "friendly name 1",
          "isActiveInput": null,
-         "label": "yYH_HCL9CKJFmvKJ9m3Une2cS8s",
+         "label": "Pr2CqqG4_NOPcVV6oKbocxyAik0",
          "receiverType": "cast",
          "volume": null
       },
@@ -485,7 +485,7 @@
          "displayStatus": null,
          "friendlyName": "friendly name 1",
          "isActiveInput": null,
-         "label": "yYH_HCL9CKJFmvKJ9m3Une2cS8s",
+         "label": "Pr2CqqG4_NOPcVV6oKbocxyAik0",
          "receiverType": "cast",
          "volume": null
       },
diff --git a/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc
index 8b42afa..5e8ec5a5 100644
--- a/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc
+++ b/chrome/browser/media/router/providers/cast/cast_media_route_provider_unittest.cc
@@ -307,7 +307,7 @@
     ASSERT_EQ(cast_state.session_state.size(), 1UL);
     const mojom::CastSessionState& session_state =
         *(cast_state.session_state[0]);
-    EXPECT_EQ(session_state.sink_id, "cast:<id1>");
+    EXPECT_EQ(session_state.sink_id, "cast:id1");
     EXPECT_EQ(session_state.app_id, "ABCDEFGH");
     EXPECT_EQ(session_state.session_id, "theSessionId");
     EXPECT_EQ(session_state.route_description, "App status");
diff --git a/chrome/browser/media/router/test/provider_test_helpers.cc b/chrome/browser/media/router/test/provider_test_helpers.cc
index a6658a7..9beb8c3 100644
--- a/chrome/browser/media/router/test/provider_test_helpers.cc
+++ b/chrome/browser/media/router/test/provider_test_helpers.cc
@@ -142,7 +142,7 @@
 
 MediaSinkInternal CreateDialSink(int num) {
   std::string friendly_name = base::StringPrintf("friendly name %d", num);
-  std::string unique_id = base::StringPrintf("dial:<id%d>", num);
+  std::string unique_id = base::StringPrintf("dial:id%d", num);
   net::IPEndPoint ip_endpoint = CreateIPEndPoint(num);
 
   media_router::MediaSink sink(unique_id, friendly_name,
@@ -158,7 +158,7 @@
 
 MediaSinkInternal CreateCastSink(int num) {
   std::string friendly_name = base::StringPrintf("friendly name %d", num);
-  std::string unique_id = base::StringPrintf("cast:<id%d>", num);
+  std::string unique_id = base::StringPrintf("cast:id%d", num);
   net::IPEndPoint ip_endpoint = CreateIPEndPoint(num);
 
   MediaSink sink{CreateCastSink(unique_id, friendly_name)};
diff --git a/chrome/browser/media/router/test/provider_test_helpers.h b/chrome/browser/media/router/test/provider_test_helpers.h
index eb3b3b0..ac768542 100644
--- a/chrome/browser/media/router/test/provider_test_helpers.h
+++ b/chrome/browser/media/router/test/provider_test_helpers.h
@@ -156,14 +156,14 @@
 };
 
 // Helper function to create an IP endpoint object.
-// If |num| is 1, returns 192.168.0.101:8009;
-// If |num| is 2, returns 192.168.0.102:8009.
+// If `num` is 1, returns 192.168.0.101:8009;
+// If `num` is 2, returns 192.168.0.102:8009.
 net::IPEndPoint CreateIPEndPoint(int num);
 
 // Helper function to create a DIAL media sink object.
-// If |num| is 1, returns a media sink object with following data:
+// If `num` is 1, returns a media sink object with following data:
 // {
-//   id: "id 1",
+//   id: "dial:id1",
 //   name: "friendly name 1",
 //   extra_data {
 //     model_name: "model name 1"
diff --git a/chrome/browser/media/webrtc/webrtc_log_uploader.cc b/chrome/browser/media/webrtc/webrtc_log_uploader.cc
index 793c583e..c885623d 100644
--- a/chrome/browser/media/webrtc/webrtc_log_uploader.cc
+++ b/chrome/browser/media/webrtc/webrtc_log_uploader.cc
@@ -98,6 +98,14 @@
     WebRtcLogUploader::UploadDoneData&& other) = default;
 WebRtcLogUploader::UploadDoneData::~UploadDoneData() = default;
 
+// static
+WebRtcLogUploader* WebRtcLogUploader::GetInstance() {
+  if (!g_browser_process) {
+    return nullptr;
+  }
+  return g_browser_process->webrtc_log_uploader();
+}
+
 WebRtcLogUploader::WebRtcLogUploader()
     : main_task_runner_(base::SequencedTaskRunner::GetCurrentDefault()),
       background_task_runner_(base::ThreadPool::CreateSequencedTaskRunner(
diff --git a/chrome/browser/media/webrtc/webrtc_log_uploader.h b/chrome/browser/media/webrtc/webrtc_log_uploader.h
index 4fd754f..30051e1 100644
--- a/chrome/browser/media/webrtc/webrtc_log_uploader.h
+++ b/chrome/browser/media/webrtc/webrtc_log_uploader.h
@@ -79,6 +79,7 @@
     int web_app_id;
   };
 
+  static WebRtcLogUploader* GetInstance();
   WebRtcLogUploader();
 
   WebRtcLogUploader(const WebRtcLogUploader&) = delete;
diff --git a/chrome/browser/media/webrtc/webrtc_logging_controller.cc b/chrome/browser/media/webrtc/webrtc_logging_controller.cc
index 2b4b463..e29a1f4f 100644
--- a/chrome/browser/media/webrtc/webrtc_logging_controller.cc
+++ b/chrome/browser/media/webrtc/webrtc_logging_controller.cc
@@ -41,13 +41,12 @@
 
 // static
 void WebRtcLoggingController::AttachToRenderProcessHost(
-    content::RenderProcessHost* host,
-    WebRtcLogUploader* log_uploader) {
+    content::RenderProcessHost* host) {
   host->SetUserData(
       kRenderProcessHostKey,
       std::make_unique<base::UserDataAdapter<WebRtcLoggingController>>(
-          new WebRtcLoggingController(host->GetID(), host->GetBrowserContext(),
-                                      log_uploader)));
+          new WebRtcLoggingController(host->GetID(),
+                                      host->GetBrowserContext())));
 }
 
 // static
@@ -80,7 +79,7 @@
   DCHECK(!callback.is_null());
 
   // Request a log_slot from the LogUploader and start logging.
-  if (text_log_handler_->StartLogging(log_uploader_, std::move(callback))) {
+  if (text_log_handler_->StartLogging(std::move(callback))) {
     // Start logging in the renderer. The callback has already been fired since
     // there is no acknowledgement when the renderer actually starts.
     content::RenderProcessHost* host =
@@ -122,7 +121,8 @@
 
   base::UmaHistogramSparse("WebRtcTextLogging.UploadStarted", web_app_id_);
 
-  log_uploader_->background_task_runner()->PostTaskAndReplyWithResult(
+  WebRtcLogUploader* log_uploader = WebRtcLogUploader::GetInstance();
+  log_uploader->background_task_runner()->PostTaskAndReplyWithResult(
       FROM_HERE, base::BindOnce(log_directory_getter_),
       base::BindOnce(&WebRtcLoggingController::TriggerUpload, this,
                      std::move(callback)));
@@ -136,29 +136,30 @@
   base::UmaHistogramSparse("WebRtcTextLogging.UploadStoredStarted",
                            web_app_id_);
 
-  // Make this a method call on log_uploader_
+  // Make this a method call on log_uploader
 
   WebRtcLogUploader::UploadDoneData upload_data;
   upload_data.callback = std::move(callback);
   upload_data.local_log_id = log_id;
   upload_data.web_app_id = web_app_id_;
 
+  WebRtcLogUploader* log_uploader = WebRtcLogUploader::GetInstance();
   if (!IsWebRtcTextLogAllowed(GetBrowserContext())) {
-    log_uploader_->NotifyUploadDisabled(std::move(upload_data));
+    log_uploader->NotifyUploadDisabled(std::move(upload_data));
     return;
   }
 
-  log_uploader_->background_task_runner()->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          [](WebRtcLogUploader* log_uploader,
-             WebRtcLogUploader::UploadDoneData upload_data,
-             base::RepeatingCallback<base::FilePath(void)>
-                 log_directory_getter) {
-            upload_data.paths.directory = log_directory_getter.Run();
-            log_uploader->UploadStoredLog(std::move(upload_data));
-          },
-          log_uploader_, std::move(upload_data), log_directory_getter_));
+  log_uploader->background_task_runner()->PostTask(
+      FROM_HERE, base::BindOnce(
+                     [](WebRtcLogUploader::UploadDoneData upload_data,
+                        base::RepeatingCallback<base::FilePath(void)>
+                            log_directory_getter) {
+                       upload_data.paths.directory = log_directory_getter.Run();
+                       WebRtcLogUploader* uploader =
+                           WebRtcLogUploader::GetInstance();
+                       uploader->UploadStoredLog(std::move(upload_data));
+                     },
+                     std::move(upload_data), log_directory_getter_));
 }
 
 void WebRtcLoggingController::DiscardLog(GenericDoneCallback callback) {
@@ -169,7 +170,8 @@
     // The callback is fired with an error message by ExpectLoggingStateStopped.
     return;
   }
-  log_uploader_->LoggingStoppedDontUpload();
+  WebRtcLogUploader* log_uploader = WebRtcLogUploader::GetInstance();
+  log_uploader->LoggingStoppedDontUpload();
   text_log_handler_->DiscardLog();
   rtp_dump_handler_.reset();
   stop_rtp_dump_callback_.Reset();
@@ -212,7 +214,8 @@
   std::unique_ptr<WebRtcLogPaths> log_paths(new WebRtcLogPaths());
   ReleaseRtpDumps(log_paths.get());
 
-  log_uploader_->background_task_runner()->PostTaskAndReplyWithResult(
+  WebRtcLogUploader* log_uploader = WebRtcLogUploader::GetInstance();
+  log_uploader->background_task_runner()->PostTaskAndReplyWithResult(
       FROM_HERE, base::BindOnce(log_directory_getter_),
       base::BindOnce(&WebRtcLoggingController::StoreLogInDirectory, this,
                      log_id, std::move(log_paths), std::move(callback)));
@@ -239,7 +242,8 @@
       base::BindRepeating(&WebRtcLoggingController::OnRtpPacket, this));
 
   if (!rtp_dump_handler_) {
-    log_uploader_->background_task_runner()->PostTaskAndReplyWithResult(
+    WebRtcLogUploader* log_uploader = WebRtcLogUploader::GetInstance();
+    log_uploader->background_task_runner()->PostTaskAndReplyWithResult(
         FROM_HERE, base::BindOnce(log_directory_getter_),
         base::BindOnce(&WebRtcLoggingController::CreateRtpDumpHandlerAndStart,
                        this, type, std::move(callback)));
@@ -290,7 +294,8 @@
     LogsDirectoryErrorCallback error_callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!callback.is_null());
-  log_uploader_->background_task_runner()->PostTaskAndReplyWithResult(
+  WebRtcLogUploader* log_uploader = WebRtcLogUploader::GetInstance();
+  log_uploader->background_task_runner()->PostTaskAndReplyWithResult(
       FROM_HERE, base::BindOnce(log_directory_getter_),
       base::BindOnce(&WebRtcLoggingController::GrantLogsDirectoryAccess, this,
                      std::move(callback), std::move(error_callback)));
@@ -373,8 +378,7 @@
 
 WebRtcLoggingController::WebRtcLoggingController(
     int render_process_id,
-    content::BrowserContext* browser_context,
-    WebRtcLogUploader* log_uploader)
+    content::BrowserContext* browser_context)
     : receiver_(this),
       render_process_id_(render_process_id),
       log_directory_getter_(base::BindRepeating(
@@ -382,10 +386,7 @@
           browser_context->GetPath())),
       upload_log_on_render_close_(false),
       text_log_handler_(
-          std::make_unique<WebRtcTextLogHandler>(render_process_id)),
-      log_uploader_(log_uploader) {
-  DCHECK(log_uploader_);
-}
+          std::make_unique<WebRtcTextLogHandler>(render_process_id)) {}
 
 WebRtcLoggingController::~WebRtcLoggingController() {
   // If we hit this, then we might be leaking a log reference count (see
@@ -399,6 +400,7 @@
   if (text_log_handler_->GetChannelIsClosing())
     return;
 
+  WebRtcLogUploader* log_uploader = WebRtcLogUploader::GetInstance();
   switch (text_log_handler_->GetState()) {
     case WebRtcTextLogHandler::STARTING:
     case WebRtcTextLogHandler::STARTED:
@@ -406,12 +408,12 @@
     case WebRtcTextLogHandler::STOPPED:
       text_log_handler_->ChannelClosing();
       if (upload_log_on_render_close_) {
-        log_uploader_->background_task_runner()->PostTaskAndReplyWithResult(
+        log_uploader->background_task_runner()->PostTaskAndReplyWithResult(
             FROM_HERE, base::BindOnce(log_directory_getter_),
             base::BindOnce(&WebRtcLoggingController::TriggerUpload, this,
                            UploadDoneCallback()));
       } else {
-        log_uploader_->LoggingStoppedDontUpload();
+        log_uploader->LoggingStoppedDontUpload();
         text_log_handler_->DiscardLog();
       }
       break;
@@ -473,12 +475,21 @@
   CHECK(log_buffer.get()) << "State=" << text_log_handler_->GetState()
                           << ", uorc=" << upload_log_on_render_close_;
 
-  log_uploader_->background_task_runner()->PostTask(
-      FROM_HERE,
-      base::BindOnce(&WebRtcLogUploader::LoggingStoppedDoStore,
-                     base::Unretained(log_uploader_), *log_paths, log_id,
-                     std::move(log_buffer), std::move(meta_data),
-                     std::move(done_callback)));
+  WebRtcLogUploader* log_uploader = WebRtcLogUploader::GetInstance();
+  log_uploader->background_task_runner()->PostTask(
+      FROM_HERE, base::BindOnce(
+                     [](WebRtcLogPaths paths, const std::string& log_id,
+                        std::unique_ptr<WebRtcLogBuffer> log_buffer,
+                        std::unique_ptr<WebRtcLogMetaDataMap> meta_data,
+                        GenericDoneCallback done_callback) {
+                       WebRtcLogUploader* uploader =
+                           WebRtcLogUploader::GetInstance();
+                       uploader->LoggingStoppedDoStore(
+                           paths, log_id, std::move(log_buffer),
+                           std::move(meta_data), std::move(done_callback));
+                     },
+                     *log_paths, log_id, std::move(log_buffer),
+                     std::move(meta_data), std::move(done_callback)));
 }
 
 void WebRtcLoggingController::DoUploadLogAndRtpDumps(
@@ -531,12 +542,21 @@
   content::BrowserContext* browser_context = GetBrowserContext();
   bool is_text_log_upload_allowed = IsWebRtcTextLogAllowed(browser_context);
 
-  log_uploader_->background_task_runner()->PostTask(
+  WebRtcLogUploader* log_uploader = WebRtcLogUploader::GetInstance();
+  log_uploader->background_task_runner()->PostTask(
       FROM_HERE,
-      base::BindOnce(&WebRtcLogUploader::OnLoggingStopped,
-                     base::Unretained(log_uploader_), std::move(log_buffer),
-                     std::move(meta_data), std::move(upload_done_data),
-                     is_text_log_upload_allowed));
+      base::BindOnce(
+          [](std::unique_ptr<WebRtcLogBuffer> log_buffer,
+             std::unique_ptr<WebRtcLogMetaDataMap> meta_data,
+             WebRtcLogUploader::UploadDoneData upload_done_data,
+             bool is_text_log_upload_allowed) {
+            WebRtcLogUploader* uploader = WebRtcLogUploader::GetInstance();
+            uploader->OnLoggingStopped(
+                std::move(log_buffer), std::move(meta_data),
+                std::move(upload_done_data), is_text_log_upload_allowed);
+          },
+          std::move(log_buffer), std::move(meta_data),
+          std::move(upload_done_data), is_text_log_upload_allowed));
 }
 
 void WebRtcLoggingController::CreateRtpDumpHandlerAndStart(
diff --git a/chrome/browser/media/webrtc/webrtc_logging_controller.h b/chrome/browser/media/webrtc/webrtc_logging_controller.h
index d984957..11d86604 100644
--- a/chrome/browser/media/webrtc/webrtc_logging_controller.h
+++ b/chrome/browser/media/webrtc/webrtc_logging_controller.h
@@ -60,8 +60,7 @@
       void(bool, const std::string&, const std::string&)>
       StartEventLoggingCallback;
 
-  static void AttachToRenderProcessHost(content::RenderProcessHost* host,
-                                        WebRtcLogUploader* log_uploader);
+  static void AttachToRenderProcessHost(content::RenderProcessHost* host);
   static WebRtcLoggingController* FromRenderProcessHost(
       content::RenderProcessHost* host);
 
@@ -155,8 +154,7 @@
   friend class base::RefCounted<WebRtcLoggingController>;
 
   WebRtcLoggingController(int render_process_id,
-                          content::BrowserContext* browser_context,
-                          WebRtcLogUploader* log_uploader);
+                          content::BrowserContext* browser_context);
   ~WebRtcLoggingController() override;
 
   void OnAgentDisconnected();
@@ -237,10 +235,6 @@
   // The callback to call when StopRtpDump is called.
   content::RenderProcessHost::WebRtcStopRtpDumpCallback stop_rtp_dump_callback_;
 
-  // A pointer to the log uploader that's shared for all browser contexts.
-  // Ownership lies with the browser process.
-  const raw_ptr<WebRtcLogUploader, LeakedDanglingUntriaged> log_uploader_;
-
   // Web app id used for statistics. Created as the hash of the value of a
   // "client" meta data key, if exists. 0 means undefined, and is the hash of
   // the empty string.
diff --git a/chrome/browser/media/webrtc/webrtc_logging_controller_unittest.cc b/chrome/browser/media/webrtc/webrtc_logging_controller_unittest.cc
index dbfabf6..4124a76 100644
--- a/chrome/browser/media/webrtc/webrtc_logging_controller_unittest.cc
+++ b/chrome/browser/media/webrtc/webrtc_logging_controller_unittest.cc
@@ -66,17 +66,18 @@
   }
 
   void UnloadMainTestProfile() {
-    webrtc_log_uploader_->Shutdown();
-    webrtc_log_uploader_.reset();
+    TestingBrowserProcess::GetGlobal()->webrtc_log_uploader()->Shutdown();
+    TestingBrowserProcess::GetGlobal()->SetWebRtcLogUploader(nullptr);
     rph_.reset();
     browser_context_.reset();
   }
 
   void CreateRenderHost() {
     rph_ = std::make_unique<MockRenderProcessHost>(browser_context_.get());
-    webrtc_log_uploader_ = std::make_unique<WebRtcLogUploader>();
-    WebRtcLoggingController::AttachToRenderProcessHost(
-        rph_.get(), webrtc_log_uploader_.get());
+    auto webrtc_log_uploader = std::make_unique<WebRtcLogUploader>();
+    TestingBrowserProcess::GetGlobal()->SetWebRtcLogUploader(
+        std::move(webrtc_log_uploader));
+    WebRtcLoggingController::AttachToRenderProcessHost(rph_.get());
     webrtc_logging_controller_ =
         WebRtcLoggingController::FromRenderProcessHost(rph_.get());
   }
@@ -145,7 +146,6 @@
 
   // Class under test.
   raw_ptr<WebRtcLoggingController> webrtc_logging_controller_ = nullptr;
-  std::unique_ptr<WebRtcLogUploader> webrtc_log_uploader_ = nullptr;
 
   // Testing utilities.
   content::BrowserTaskEnvironment task_environment_;
diff --git a/chrome/browser/media/webrtc/webrtc_text_log_handler.cc b/chrome/browser/media/webrtc/webrtc_text_log_handler.cc
index 17b507ac..68a058d 100644
--- a/chrome/browser/media/webrtc/webrtc_text_log_handler.cc
+++ b/chrome/browser/media/webrtc/webrtc_text_log_handler.cc
@@ -187,8 +187,7 @@
   FireGenericDoneCallback(std::move(callback), true, "");
 }
 
-bool WebRtcTextLogHandler::StartLogging(WebRtcLogUploader* log_uploader,
-                                        GenericDoneCallback callback) {
+bool WebRtcTextLogHandler::StartLogging(GenericDoneCallback callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(!callback.is_null());
 
@@ -204,6 +203,7 @@
     return false;
   }
 
+  WebRtcLogUploader* log_uploader = WebRtcLogUploader::GetInstance();
   if (!log_uploader->ApplyForStartLogging()) {
     FireGenericDoneCallback(std::move(callback), false,
                             "Cannot start, maybe the maximum number of "
diff --git a/chrome/browser/media/webrtc/webrtc_text_log_handler.h b/chrome/browser/media/webrtc/webrtc_text_log_handler.h
index 635f152..c78b2e6a 100644
--- a/chrome/browser/media/webrtc/webrtc_text_log_handler.h
+++ b/chrome/browser/media/webrtc/webrtc_text_log_handler.h
@@ -71,8 +71,7 @@
 
   // Opens a log and starts logging if allowed by the LogUploader.
   // Returns false if logging could not be started.
-  bool StartLogging(WebRtcLogUploader* log_uploader,
-                    GenericDoneCallback callback);
+  bool StartLogging(GenericDoneCallback callback);
 
   // Stops logging. Log will remain open until UploadLog or DiscardLog is
   // called.
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
index 09b3724..0d6dc69d4 100644
--- a/chrome/browser/printing/print_view_manager_base.cc
+++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -388,7 +388,6 @@
       UnregisterSystemPrintClient();
     }
 #endif
-    queue_->QueuePrinterQuery(std::move(printer_query));
 #if BUILDFLAG(IS_WIN)
     content::GetUIThreadTaskRunner({})->PostTask(
         FROM_HERE, base::BindOnce(&PrintViewManagerBase::SystemDialogCancelled,
diff --git a/chrome/browser/printing/system_access_process_print_browsertest.cc b/chrome/browser/printing/system_access_process_print_browsertest.cc
index b922236..3fef7a9 100644
--- a/chrome/browser/printing/system_access_process_print_browsertest.cc
+++ b/chrome/browser/printing/system_access_process_print_browsertest.cc
@@ -59,7 +59,7 @@
 #include "components/enterprise/buildflags/buildflags.h"
 
 #if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
-#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h"  // nogncheck
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h"  // nogncheck
 #endif  // BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
 #endif  // BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS)
 
@@ -2132,11 +2132,6 @@
 // RunLoop behavior can be made to work with test expectations.
 IN_PROC_BROWSER_TEST_P(SystemAccessProcessPrintBrowserTest,
                        SystemPrintAfterSystemPrintFromPrintPreview) {
-  // TODO(crbug.com/1497945):  Let test run once crash is resolved.
-  if (UseService()) {
-    GTEST_SKIP();
-  }
-
   AddPrinter("printer1");
   SetPrinterNameForSubsequentContexts("printer1");
   PrimeForCancelInAskUserForSettings();
diff --git a/chrome/browser/resources/certificate_viewer/BUILD.gn b/chrome/browser/resources/certificate_viewer/BUILD.gn
index 86407978..c1ad88b2 100644
--- a/chrome/browser/resources/certificate_viewer/BUILD.gn
+++ b/chrome/browser/resources/certificate_viewer/BUILD.gn
@@ -17,6 +17,7 @@
 
   non_web_component_files = [ "certificate_viewer.ts" ]
 
+  ts_composite = true
   ts_definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ]
   ts_deps = [
     "//ui/webui/resources/cr_elements:build_ts",
diff --git a/chrome/browser/resources/certificate_viewer/certificate_viewer.ts b/chrome/browser/resources/certificate_viewer/certificate_viewer.ts
index cf827a6..6192d36 100644
--- a/chrome/browser/resources/certificate_viewer/certificate_viewer.ts
+++ b/chrome/browser/resources/certificate_viewer/certificate_viewer.ts
@@ -24,7 +24,7 @@
   isError: boolean;
 }
 
-interface TreeItemDetail {
+export interface TreeItemDetail {
   payload: {
     val?: string,
     index?: number,
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/magnifier/magnifier.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/magnifier/magnifier.js
index 39087070..2980f3f7 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/magnifier/magnifier.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/magnifier/magnifier.js
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import {AutomationPredicate} from '../../common/automation_predicate.js';
 import {ChromeEventHandler} from '../../common/chrome_event_handler.js';
 import {EventHandler} from '../../common/event_handler.js';
 import {FlagName, Flags} from '../../common/flags.js';
@@ -224,8 +225,9 @@
 
     // Skip trying to move magnifier to encompass whole webpage or pdf. It's too
     // big, and magnifier usually ends up in middle at left edge of page.
-    if (node.isRootNode || node.role === RoleType.WEB_VIEW ||
-        node.role === RoleType.EMBEDDED_OBJECT) {
+    const isTooBig = AutomationPredicate.roles(
+        [RoleType.WEB_VIEW, RoleType.EMBEDDED_OBJECT]);
+    if (node.isRootNode || isTooBig(node)) {
       return;
     }
 
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox_range.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox_range.js
index 0d8be53..6cf01de 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox_range.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox_range.js
@@ -357,16 +357,14 @@
     if (prevRange && prevRange.start.node && start) {
       const entered =
           AutomationUtil.getUniqueAncestors(prevRange.start.node, start);
+      const isPluginOrIframe =
+          AutomationPredicate.roles([RoleType.PLUGIN_OBJECT, RoleType.IFRAME]);
 
-      entered
-          .filter(
-              ancestor => ancestor.role === RoleType.PLUGIN_OBJECT ||
-                  ancestor.role === RoleType.IFRAME)
-          .forEach(container => {
-            if (!container.state[StateType.FOCUSED]) {
-              container.focus();
-            }
-          });
+      entered.filter(isPluginOrIframe).forEach(container => {
+        if (!container.state[StateType.FOCUSED]) {
+          container.focus();
+        }
+      });
     }
 
     if (start.state[StateType.FOCUSED] || end.state[StateType.FOCUSED]) {
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/event/desktop_automation_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/event/desktop_automation_handler.js
index 7f656d8..bc29060 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/event/desktop_automation_handler.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/event/desktop_automation_handler.js
@@ -313,14 +313,14 @@
     }
 
     // Invalidate any previous editable text handler state.
-    if (!this.createTextEditHandlerIfNeeded_(evt.target, true)) {
+    if (!this.createTextEditHandlerIfNeeded_(node, true)) {
       this.textEditHandler_ = null;
     }
 
     // Discard focus events on embeddedObject and webView.
-    if (node.role === RoleType.EMBEDDED_OBJECT ||
-        node.role === RoleType.PLUGIN_OBJECT ||
-        node.role === RoleType.WEB_VIEW) {
+    const shouldDiscard = AutomationPredicate.roles(
+        [RoleType.EMBEDDED_OBJECT, RoleType.PLUGIN_OBJECT, RoleType.WEB_VIEW]);
+    if (shouldDiscard(node)) {
       return;
     }
 
@@ -679,8 +679,8 @@
 
       // TableView fires selection events on rows/cells
       // and we want to ignore those because it also fires focus events.
-      if (isDesktop && target.role === RoleType.CELL ||
-          target.role === RoleType.ROW) {
+      const skip = AutomationPredicate.roles([RoleType.CELL, RoleType.ROW]);
+      if (isDesktop && skip(target)) {
         return;
       }
 
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/event/range_automation_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/event/range_automation_handler.js
index a7eda00..88959b4 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/event/range_automation_handler.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/event/range_automation_handler.js
@@ -72,8 +72,7 @@
     while (retarget && retarget !== retarget.root) {
       // Table headers require retargeting for events because they often have
       // event types we care about e.g. sort direction.
-      if (retarget.role === RoleType.COLUMN_HEADER ||
-          retarget.role === RoleType.ROW_HEADER) {
+      if (AutomationPredicate.tableHeader(retarget)) {
         this.node_ = retarget;
         break;
       }
@@ -198,9 +197,7 @@
     }
 
     // Only report attribute changes on some *Option roles if it is selected.
-    if ((evt.target.role === RoleType.MENU_LIST_OPTION ||
-         evt.target.role === RoleType.LIST_BOX_OPTION) &&
-        !evt.target.selected) {
+    if (AutomationPredicate.listOption(evt.target) && !evt.target.selected) {
       return;
     }
 
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/command_handler.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/command_handler.js
index 2575950..da1cd84 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/command_handler.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/input/command_handler.js
@@ -1058,8 +1058,7 @@
       return;
     }
 
-    while (actionNode.role === RoleType.INLINE_TEXT_BOX ||
-           actionNode.role === RoleType.STATIC_TEXT) {
+    while (actionNode && AutomationPredicate.text(actionNode)) {
       actionNode = actionNode.parent;
     }
     if (actionNode.inPageLinkTarget) {
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/live_regions.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/live_regions.js
index b0b8a27..ca59879c 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/live_regions.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/live_regions.js
@@ -5,6 +5,7 @@
 /**
  * @fileoverview Implements support for live regions in ChromeVox.
  */
+import {AutomationPredicate} from '../../common/automation_predicate.js';
 import {AutomationUtil} from '../../common/automation_util.js';
 import {CursorRange} from '../../common/cursors/range.js';
 import {QueueMode, TtsCategory} from '../common/tts_types.js';
@@ -69,8 +70,9 @@
 
   /** @param {!AutomationNode} area */
   static announceDesktopLiveRegionChanged(area) {
-    if (area.root.role !== RoleType.DESKTOP &&
-        area.root.role !== RoleType.APPLICATION) {
+    const desktopOrApplication =
+        AutomationPredicate.roles([RoleType.DESKTOP, RoleType.APPLICATION]);
+    if (!area.root || !desktopOrApplication(area.root)) {
       return;
     }
 
diff --git a/chrome/browser/resources/chromeos/accessibility/common/automation_predicate.js b/chrome/browser/resources/chromeos/accessibility/common/automation_predicate.js
index d8641244..4d8d7c1 100644
--- a/chrome/browser/resources/chromeos/accessibility/common/automation_predicate.js
+++ b/chrome/browser/resources/chromeos/accessibility/common/automation_predicate.js
@@ -970,6 +970,14 @@
   anyAttribute: {longClickable: true},
 });
 
+/**
+ * Returns if the node is a list option, either in a menu or a listbox.
+ * @param {!AutomationNode} node
+ * @return {boolean}
+ */
+AutomationPredicate.listOption =
+    AutomationPredicate.roles([Role.LIST_BOX_OPTION, Role.MENU_LIST_OPTION]);
+
 // Table related predicates.
 /**
  * Returns if the node has a cell like role.
@@ -979,6 +987,13 @@
 AutomationPredicate.cellLike =
     AutomationPredicate.roles([Role.CELL, Role.ROW_HEADER, Role.COLUMN_HEADER]);
 
+/**
+ * Returns if the node is a table header.
+ * @param {!AutomationNode} node
+ * @return {boolean}
+ */
+AutomationPredicate.tableHeader =
+    AutomationPredicate.roles([Role.ROW_HEADER, Role.COLUMN_HEADER]);
 
 /**
  * Matches against nodes that we may be able to retrieve image data from.
diff --git a/chrome/browser/resources/chromeos/accessibility/switch_access/switch_access_predicate.js b/chrome/browser/resources/chromeos/accessibility/switch_access/switch_access_predicate.js
index fda9f57..651cfe23 100644
--- a/chrome/browser/resources/chromeos/accessibility/switch_access/switch_access_predicate.js
+++ b/chrome/browser/resources/chromeos/accessibility/switch_access/switch_access_predicate.js
@@ -46,8 +46,6 @@
     const defaultActionVerb = node.defaultActionVerb;
     const loc = node.location;
     const parent = node.parent;
-    const role = node.role;
-    const state = node.state;
 
     // Skip things that are offscreen or invisible.
     if (!SwitchAccessPredicate.isVisible(node)) {
@@ -62,14 +60,15 @@
     }
 
     // These web containers are not directly actionable.
-    if (role === RoleType.WEB_VIEW || role === RoleType.ROOT_WEB_AREA) {
+    if (AutomationPredicate.structuralContainer(node)) {
       cache.isActionable.set(node, false);
       return false;
     }
 
     // Check various indicators that the node is actionable.
-    if (role === RoleType.BUTTON || role === RoleType.SLIDER ||
-        role === RoleType.TAB) {
+    const actionableRole = AutomationPredicate.roles(
+        [RoleType.BUTTON, RoleType.SLIDER, RoleType.TAB]);
+    if (actionableRole(node)) {
       cache.isActionable.set(node, true);
       return true;
     }
@@ -91,7 +90,7 @@
       return true;
     }
 
-    if (role === RoleType.LIST_ITEM &&
+    if (node.role === RoleType.LIST_ITEM &&
         defaultActionVerb === DefaultActionVerb.CLICK) {
       cache.isActionable.set(node, true);
       return true;
@@ -101,7 +100,7 @@
     // should menu items.
     // Current heuristic is to show as actionble any focusable item where no
     // child is an interesting subtree.
-    if (state[StateType.FOCUSABLE] || role === RoleType.MENU_ITEM) {
+    if (node.state[StateType.FOCUSABLE] || node.role === RoleType.MENU_ITEM) {
       const result = !node.children.some(
           child => SwitchAccessPredicate.isInterestingSubtree(child, cache));
       cache.isActionable.set(node, result);
diff --git a/chrome/browser/resources/compose/app.html b/chrome/browser/resources/compose/app.html
index 4d823f7..72fe323 100644
--- a/chrome/browser/resources/compose/app.html
+++ b/chrome/browser/resources/compose/app.html
@@ -402,11 +402,9 @@
             $i18nRaw{fileBugText}
           </a>
         </div>
-        <div class="icon-buttons-row">
-          <cr-icon-button iron-icon="cr:thumbs-up"></cr-icon-button>
-          <cr-icon-button iron-icon="cr:thumbs-down" on-click="onFileBugClick_">
-          </cr-icon-button>
-        </div>
+        <cr-feedback-buttons
+            on-selected-option-changed="onFeedbackSelectedOptionChanged_">
+        </cr-feedback-buttons>
       </div>
       <cr-button id="insertButton" class="action-button" on-click="onAccept_">
         $i18n{insertButton}
diff --git a/chrome/browser/resources/compose/app.ts b/chrome/browser/resources/compose/app.ts
index 24b5247a..c0e6fc4 100644
--- a/chrome/browser/resources/compose/app.ts
+++ b/chrome/browser/resources/compose/app.ts
@@ -7,6 +7,7 @@
 import './textarea.js';
 import '//resources/cr_elements/cr_button/cr_button.js';
 import '//resources/cr_elements/cr_hidden_style.css.js';
+import '//resources/cr_elements/cr_feedback_buttons/cr_feedback_buttons.js';
 import '//resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import '//resources/cr_elements/cr_loading_gradient/cr_loading_gradient.js';
 import '//resources/cr_elements/icons.html.js';
@@ -14,6 +15,7 @@
 
 import {ColorChangeUpdater} from '//resources/cr_components/color_change_listener/colors_css_updater.js';
 import {CrButtonElement} from '//resources/cr_elements/cr_button/cr_button.js';
+import {CrFeedbackOption} from '//resources/cr_elements/cr_feedback_buttons/cr_feedback_buttons.js';
 import {CrScrollableMixin} from '//resources/cr_elements/cr_scrollable_mixin.js';
 import {I18nMixin} from '//resources/cr_elements/i18n_mixin.js';
 import {assert} from '//resources/js/assert.js';
@@ -412,6 +414,19 @@
       // TODO(b/301368162) Ask UX how to handle the edge case of multiple fails.
     }
   }
+
+  private onFeedbackSelectedOptionChanged_(
+      e: CustomEvent<{value: CrFeedbackOption}>) {
+    switch (e.detail.value) {
+      case CrFeedbackOption.UNSPECIFIED:
+      case CrFeedbackOption.THUMBS_UP:
+        // TODO(b/308355619): Save state and call handler.
+        return;
+      case CrFeedbackOption.THUMBS_DOWN:
+        this.apiProxy_.openBugReportingLink();
+        return;
+    }
+  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/side_panel/customize_chrome/app.html b/chrome/browser/resources/side_panel/customize_chrome/app.html
index 7ae751c..92bc61e 100644
--- a/chrome/browser/resources/side_panel/customize_chrome/app.html
+++ b/chrome/browser/resources/side_panel/customize_chrome/app.html
@@ -104,7 +104,8 @@
         <h2 slot="heading">$i18n{appearanceHeader}</h2>
       </sp-heading>
       <customize-chrome-appearance on-edit-theme-click="onEditThemeClick_"
-        id="appearanceElement">
+          on-wallpaper-search-click="onWallpaperSearchSelect_"
+          id="appearanceElement">
       </customize-chrome-appearance>
     </div>
     <hr class="sp-cards-separator">
diff --git a/chrome/browser/resources/side_panel/customize_chrome/appearance.html b/chrome/browser/resources/side_panel/customize_chrome/appearance.html
index 531a667c..10fedf1b 100644
--- a/chrome/browser/resources/side_panel/customize_chrome/appearance.html
+++ b/chrome/browser/resources/side_panel/customize_chrome/appearance.html
@@ -35,6 +35,10 @@
     --cr-icon-image: url(icons/upload.svg);
   }
 
+  #searchedImageButton {
+    --cr-icon-image: url(icons/image.svg);
+  }
+
   managed-dialog {
     --cr-dialog-width: min(calc(100% - 32px), 512px);
   }
@@ -103,6 +107,12 @@
     label="$i18n{yourUploadedImage}"
     label-description="$i18n{currentTheme}">
 </customize-chrome-hover-button>
+<customize-chrome-hover-button id="searchedImageButton" class="theme-button"
+    hidden$="[[!showSearchedImageButton_]]"
+    on-click="onSearchedImageButtonClick_"
+    label="$i18n{yourSearchedImage}"
+    label-description="$i18n{currentTheme}">
+</customize-chrome-hover-button>
 <cr-button id="editThemeButton" on-click="onEditThemeClicked_"
     class$="[[themeButtonClass_]]">
   <div id="imageIcon" class="cr-icon" slot="prefix-icon"></div>
diff --git a/chrome/browser/resources/side_panel/customize_chrome/appearance.ts b/chrome/browser/resources/side_panel/customize_chrome/appearance.ts
index 751df87..c9e7464 100644
--- a/chrome/browser/resources/side_panel/customize_chrome/appearance.ts
+++ b/chrome/browser/resources/side_panel/customize_chrome/appearance.ts
@@ -32,6 +32,7 @@
     followThemeToggle: HTMLElement,
     followThemeToggleControl: CrToggleElement,
     uploadedImageButton: HTMLButtonElement,
+    searchedImageButton: HTMLButtonElement,
   };
 }
 
@@ -104,6 +105,12 @@
         computed: 'computeShowUploadedImageButton_(theme_)',
       },
 
+      showSearchedImageButton_: {
+        type: Boolean,
+        value: false,
+        computed: 'computeShowSearchedImageButton_(theme_)',
+      },
+
       showManagedDialog_: Boolean,
     };
   }
@@ -200,7 +207,15 @@
     return !!(
         this.chromeRefresh2023Enabled_ && this.theme_ &&
         this.theme_.backgroundImage &&
-        this.theme_.backgroundImage.isUploadedImage);
+        this.theme_.backgroundImage.isUploadedImage &&
+        !this.theme_.backgroundImage.localBackgroundId);
+  }
+
+  private computeShowSearchedImageButton_(): boolean {
+    return !!(
+        this.chromeRefresh2023Enabled_ && this.theme_ &&
+        this.theme_.backgroundImage &&
+        this.theme_.backgroundImage.localBackgroundId);
   }
 
   private onEditThemeClicked_() {
@@ -220,6 +235,10 @@
     this.pageHandler_.chooseLocalCustomBackground();
   }
 
+  private onSearchedImageButtonClick_() {
+    this.dispatchEvent(new CustomEvent('wallpaper-search-click'));
+  }
+
   private onSetClassicChromeClicked_() {
     if (this.handleClickForManagedThemes_()) {
       return;
diff --git a/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search/wallpaper_search.html b/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search/wallpaper_search.html
index d169b96d..9b6a035 100644
--- a/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search/wallpaper_search.html
+++ b/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search/wallpaper_search.html
@@ -126,6 +126,12 @@
     height: 48px;
   }
 
+  #descriptorComboboxB customize-chrome-check-mark-wrapper {
+    --customize-chrome-check-mark-wrapper-end: -8px;
+    --customize-chrome-check-mark-wrapper-size: 16px;
+    --customize-chrome-check-mark-wrapper-top: -3px;
+  }
+
   #descriptorComboboxB img {
     border-radius: 8px;
     height: 40px;
@@ -249,11 +255,6 @@
       outline: var(--cr-focus-outline-hcm);
     }
   }
-
-  /** Temporary CSS to style demo. */
-  #descriptorComboboxB [selected] {
-    background: green;
-  }
 </style>
 <div class="sp-card">
   <sp-heading id="heading" on-back-button-click="onBackClick_"
@@ -297,7 +298,11 @@
           value="{{selectedDescriptorB_}}">
         <template is="dom-repeat" items="[[descriptors_.descriptorB]]">
           <div class="dropdown-item" role="option" value="[[item.label]]">
-            <img is="cr-auto-img" auto-src="[[item.imagePath]]"></img>
+            <customize-chrome-check-mark-wrapper
+                checked="[[isOptionSelectedInDescriptorB_(
+                    item, selectedDescriptorB_)]]">
+              <img is="cr-auto-img" auto-src="[[item.imagePath]]"></img>
+            </customize-chrome-check-mark-wrapper>
             <span>[[item.label]]</span>
           </div>
         </template>
diff --git a/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search/wallpaper_search.ts b/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search/wallpaper_search.ts
index 5ba23a8..4a73b0df 100644
--- a/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search/wallpaper_search.ts
+++ b/chrome/browser/resources/side_panel/customize_chrome/wallpaper_search/wallpaper_search.ts
@@ -27,7 +27,7 @@
 
 import {CustomizeChromePageCallbackRouter, CustomizeChromePageHandlerInterface, Theme} from '../customize_chrome.mojom-webui.js';
 import {CustomizeChromeApiProxy} from '../customize_chrome_api_proxy.js';
-import {DescriptorA, DescriptorDValue, Descriptors, WallpaperSearchHandlerInterface, WallpaperSearchResult, WallpaperSearchStatus} from '../wallpaper_search.mojom-webui.js';
+import {DescriptorA, DescriptorB, DescriptorDValue, Descriptors, WallpaperSearchHandlerInterface, WallpaperSearchResult, WallpaperSearchStatus} from '../wallpaper_search.mojom-webui.js';
 import {WindowProxy} from '../window_proxy.js';
 
 import {CustomizeChromeCombobox} from './combobox/customize_chrome_combobox.js';
@@ -279,6 +279,10 @@
     return defaultColor === this.selectedDefaultColor_;
   }
 
+  private isOptionSelectedInDescriptorB_(option: DescriptorB): boolean {
+    return option.label === this.selectedDescriptorB_;
+  }
+
   private async onBackClick_() {
     this.dispatchEvent(new Event('back-click'));
   }
diff --git a/chrome/browser/resources/tab_search/app.html b/chrome/browser/resources/tab_search/app.html
index 8effef2..bbb40bd 100644
--- a/chrome/browser/resources/tab_search/app.html
+++ b/chrome/browser/resources/tab_search/app.html
@@ -3,6 +3,7 @@
     --cr-primary-text-color: var(--color-tab-search-primary-foreground);
     --cr-secondary-text-color: var(--color-tab-search-secondary-foreground);
     --cr-separator-color: var(--color-tab-search-divider);
+    --cr-tabs-selected-color: var(--color-tab-search-selected);
     --mwb-background-color: var(--color-tab-search-background);
     --mwb-icon-button-fill-color: var(--color-tab-search-secondary-foreground);
     --mwb-list-item-hover-background-color: var(--cr-hover-background-color);
diff --git a/chrome/browser/resources/tab_search/tab_organization_results.html b/chrome/browser/resources/tab_search/tab_organization_results.html
index 6080801..7f036cb 100644
--- a/chrome/browser/resources/tab_search/tab_organization_results.html
+++ b/chrome/browser/resources/tab_search/tab_organization_results.html
@@ -41,7 +41,7 @@
   }
 
   .results {
-    background-color: var(--color-sys-surface5);
+    background-color: var(--color-tab-search-card-background);
     border-radius: 8px;
   }
 
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_util.cc b/chrome/browser/safe_browsing/download_protection/download_protection_util.cc
index 8868688..6a6fac0 100644
--- a/chrome/browser/safe_browsing/download_protection/download_protection_util.cc
+++ b/chrome/browser/safe_browsing/download_protection/download_protection_util.cc
@@ -147,9 +147,8 @@
     paths_to_check.insert(ou_tokens[i]);
   }
 
-  std::string hashed = base::SHA1HashString(std::string(
-      net::x509_util::CryptoBufferAsStringPiece(issuer.cert_buffer())));
-  std::string issuer_fp = base::HexEncode(hashed.data(), hashed.size());
+  std::string issuer_fp = base::HexEncode(base::SHA1HashSpan(
+      net::x509_util::CryptoBufferAsSpan(issuer.cert_buffer())));
   for (auto it = paths_to_check.begin(); it != paths_to_check.end(); ++it) {
     allowlist_strings->push_back("cert/" + issuer_fp + *it);
   }
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_util_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_util_unittest.cc
index 0ed81ede..a624ea91 100644
--- a/chrome/browser/safe_browsing/download_protection/download_protection_util_unittest.cc
+++ b/chrome/browser/safe_browsing/download_protection/download_protection_util_unittest.cc
@@ -34,10 +34,9 @@
   scoped_refptr<net::X509Certificate> issuer_cert(
       ReadTestCertificate(testdata_path, "issuer.pem"));
   ASSERT_TRUE(issuer_cert.get());
-  std::string hashed = base::SHA1HashString(std::string(
-      net::x509_util::CryptoBufferAsStringPiece(issuer_cert->cert_buffer())));
-  std::string cert_base =
-      "cert/" + base::HexEncode(hashed.data(), hashed.size());
+  std::string hashed = base::HexEncode(base::SHA1HashSpan(
+      net::x509_util::CryptoBufferAsSpan(issuer_cert->cert_buffer())));
+  std::string cert_base = "cert/" + hashed;
 
   scoped_refptr<net::X509Certificate> cert(
       ReadTestCertificate(testdata_path, "test_cn.pem"));
diff --git a/chrome/browser/safe_browsing/local_two_phase_testserver.cc b/chrome/browser/safe_browsing/local_two_phase_testserver.cc
index 8fd6652..eaf52863 100644
--- a/chrome/browser/safe_browsing/local_two_phase_testserver.cc
+++ b/chrome/browser/safe_browsing/local_two_phase_testserver.cc
@@ -32,8 +32,8 @@
 // Computes the SHA-1 of input string, and returns it as an ASCII-encoded string
 // of hex characters.
 std::string SHA1HexEncode(const std::string& in) {
-  std::string raw_sha1 = base::SHA1HashString(in);
-  return base::ToLowerASCII(base::HexEncode(raw_sha1.c_str(), raw_sha1.size()));
+  return base::ToLowerASCII(
+      base::HexEncode(base::SHA1HashSpan(base::as_bytes(base::make_span(in)))));
 }
 
 const char kStartHeader[] = "x-goog-resumable";
diff --git a/chrome/browser/search/background/wallpaper_search/wallpaper_search_background_manager.cc b/chrome/browser/search/background/wallpaper_search/wallpaper_search_background_manager.cc
index c7d87872..0a76f377 100644
--- a/chrome/browser/search/background/wallpaper_search/wallpaper_search_background_manager.cc
+++ b/chrome/browser/search/background/wallpaper_search/wallpaper_search_background_manager.cc
@@ -19,6 +19,7 @@
 #include "chrome/common/url_constants.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/codec/png_codec.h"
 #include "ui/gfx/image/image.h"
@@ -118,7 +119,8 @@
   }
 }
 
-void WallpaperSearchBackgroundManager::SaveCurrentBackgroundToHistory() {
+absl::optional<base::Token>
+WallpaperSearchBackgroundManager::SaveCurrentBackgroundToHistory() {
   absl::optional<CustomBackground> current_theme =
       ntp_custom_background_service_->GetCustomBackground();
   if (current_theme.has_value() &&
@@ -149,5 +151,7 @@
     }
     pref_service_->SetList(prefs::kNtpWallpaperSearchHistory,
                            std::move(new_history));
+    return current_theme->local_background_id;
   }
+  return absl::nullopt;
 }
diff --git a/chrome/browser/search/background/wallpaper_search/wallpaper_search_background_manager.h b/chrome/browser/search/background/wallpaper_search/wallpaper_search_background_manager.h
index bd904ee6..007ade7 100644
--- a/chrome/browser/search/background/wallpaper_search/wallpaper_search_background_manager.h
+++ b/chrome/browser/search/background/wallpaper_search/wallpaper_search_background_manager.h
@@ -9,6 +9,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/token.h"
 #include "chrome/browser/search/background/ntp_custom_background_service.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 
 class PrefRegistrySimple;
@@ -29,8 +30,9 @@
   virtual void SelectLocalBackgroundImage(const base::Token& id,
                                           const SkBitmap& bitmap);
 
-  // Saves a background to history.
-  virtual void SaveCurrentBackgroundToHistory();
+  // Saves the current background to history if it is a wallpaper search one.
+  // Returns the backround's ID if successful.
+  virtual absl::optional<base::Token> SaveCurrentBackgroundToHistory();
 
  private:
   raw_ptr<NtpCustomBackgroundService> ntp_custom_background_service_;
diff --git a/chrome/browser/supervised_user/supervised_user_regional_url_filter_browsertest.cc b/chrome/browser/supervised_user/supervised_user_regional_url_filter_browsertest.cc
index 503bd67..cc46865 100644
--- a/chrome/browser/supervised_user/supervised_user_regional_url_filter_browsertest.cc
+++ b/chrome/browser/supervised_user/supervised_user_regional_url_filter_browsertest.cc
@@ -18,7 +18,6 @@
 #include "base/types/strong_alias.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/supervised_user/kids_chrome_management/kids_chrome_management_client_factory.h"
-#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/mixin_based_in_process_browser_test.h"
@@ -28,7 +27,6 @@
 #include "components/supervised_user/core/browser/fetcher_config.h"
 #include "components/supervised_user/core/browser/kids_chrome_management_client.h"
 #include "components/supervised_user/core/browser/proto/kidschromemanagement_messages.pb.h"
-#include "components/supervised_user/core/browser/supervised_user_service.h"
 #include "components/supervised_user/core/common/features.h"
 #include "components/supervised_user/test_support/kids_management_api_server_mock.h"
 #include "components/variations/variations_switches.h"
@@ -63,31 +61,22 @@
 // Declare strong types for two flags.
 using UseProtoFetcher = base::StrongAlias<class UseProtoFetcherTag, bool>;
 using FilterWebsites = base::StrongAlias<class FilterWebsitesTag, bool>;
-using ParamsTuple =
+
+// With exception for platforms that don't have signed-out user concept, test
+// all possible products.
+using TestCase =
     std::tuple<SupervisionMixin::SignInMode, UseProtoFetcher, FilterWebsites>;
 
-// Wrapper class for ParamsTuple; introducing fluent aliases for test
-// parameters.
-class TestCase {
- public:
-  explicit TestCase(const ParamsTuple test_case_base)
-      : test_case_base_(test_case_base) {}
-
-  // Named accessors to TestCase's objects.
-  SupervisionMixin::SignInMode GetSignInMode() const {
-    return std::get<0>(test_case_base_);
-  }
-  bool ProtoFetcherEnabled() const {
-    return std::get<1>(test_case_base_).value();
-  }
-  bool FilterWebsitesEnabled() const {
-    return std::get<2>(test_case_base_).value();
-  }
-
- private:
-  std::tuple<SupervisionMixin::SignInMode, UseProtoFetcher, FilterWebsites>
-      test_case_base_;
-};
+// Named accessors to TestCase's objects.
+SupervisionMixin::SignInMode GetSignInMode(TestCase test_case) {
+  return std::get<0>(test_case);
+}
+bool ProtoFetcherEnabled(TestCase test_case) {
+  return std::get<1>(test_case).value();
+}
+bool FilterWebsitesEnabled(TestCase test_case) {
+  return std::get<2>(test_case).value();
+}
 
 // The region code for variations service (any should work).
 constexpr base::StringPiece kRegionCode = "jp";
@@ -95,7 +84,7 @@
 // Tests custom filtering logic based on regions, for supervised users.
 class SupervisedUserRegionalURLFilterTest
     : public MixinBasedInProcessBrowserTest,
-      public ::testing::WithParamInterface<ParamsTuple> {
+      public ::testing::WithParamInterface<TestCase> {
  public:
   SupervisedUserRegionalURLFilterTest() {
     // TODO(crbug.com/1394910): Use HTTPS URLs in tests to avoid having to
@@ -142,15 +131,13 @@
               ClassifyUrlRequestMonitor,
               (base::StringPiece, base::StringPiece));
 
-  static const TestCase GetTestCase() { return TestCase(GetParam()); }
-
   std::vector<base::test::FeatureRef> GetEnabledFeatures() const {
     std::vector<base::test::FeatureRef> features;
 
-    if (GetTestCase().ProtoFetcherEnabled()) {
+    if (ProtoFetcherEnabled(GetParam())) {
       features.push_back(kEnableProtoApiForClassifyUrl);
     }
-    if (GetTestCase().FilterWebsitesEnabled()) {
+    if (FilterWebsitesEnabled(GetParam())) {
       features.push_back(kFilterWebsitesForSupervisedUsersOnDesktopAndIOS);
     }
 
@@ -161,10 +148,10 @@
     std::vector<base::test::FeatureRef> features;
 
     features.push_back(features::kHttpsUpgrades);
-    if (!GetTestCase().ProtoFetcherEnabled()) {
+    if (!ProtoFetcherEnabled(GetParam())) {
       features.push_back(kEnableProtoApiForClassifyUrl);
     }
-    if (!GetTestCase().FilterWebsitesEnabled()) {
+    if (!FilterWebsitesEnabled(GetParam())) {
       features.push_back(kFilterWebsitesForSupervisedUsersOnDesktopAndIOS);
     }
 
@@ -204,16 +191,27 @@
         KidsChromeManagementClientFactory::GetForProfile(browser()->profile()));
   }
 
+  // Only supervised users have their url requests classified, only when the
+  // feature is enabled.
+  bool ShouldUrlsBeClassified() const {
+    if (GetSignInMode(GetParam()) !=
+        supervised_user::SupervisionMixin::SignInMode::kSupervised) {
+      return false;
+    }
+
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS)
+    return true;
+#else
+    return base::FeatureList::IsEnabled(
+        kFilterWebsitesForSupervisedUsersOnDesktopAndIOS);
+#endif
+  }
+
  protected:
   supervised_user::KidsManagementApiServerMock& kids_management_api_mock() {
     return supervision_mixin_.api_mock_setup_mixin().api_mock();
   }
 
-  bool IsUrlFilteringEnabled() const {
-    return SupervisedUserServiceFactory::GetForProfile(browser()->profile())
-        ->IsURLFilteringEnabled();
-  }
-
  private:
   base::test::ScopedFeatureList feature_list_;
   base::CallbackListSubscription create_services_subscription_;
@@ -223,7 +221,7 @@
       this,
       embedded_test_server(),
       {
-          .sign_in_mode = GetTestCase().GetSignInMode(),
+          .sign_in_mode = GetSignInMode(GetParam()),
           .embedded_test_server_options =
               {
                   .resolver_rules_map_host_list =
@@ -245,15 +243,16 @@
   expected.set_region_code(std::string(kRegionCode));
   expected.set_url(url_to_classify);
 
-  int number_of_expected_calls = IsUrlFilteringEnabled() ? 1 : 0;
-  if (supervised_user::IsProtoApiForClassifyUrlEnabled()) {
+  int number_of_expected_calls = ShouldUrlsBeClassified() ? 1 : 0;
+
+  if (ProtoFetcherEnabled(GetParam())) {
     if (number_of_expected_calls > 0) {
       kids_management_api_mock().AllowSubsequentClassifyUrl();
       EXPECT_CALL(kids_management_api_mock().classify_url_mock(), ClassifyUrl)
           .Times(number_of_expected_calls);
     }
     // Ignore all extra calls to other methods
-    EXPECT_CALL(*this, ClassifyUrlRequestMonitor(_, _))
+    EXPECT_CALL(*this, ClassifyUrlRequestMonitor(::testing::_, ::testing::_))
         .Times(::testing::AnyNumber());
     // Last expectation takes precedence.
     EXPECT_CALL(*this,
@@ -272,14 +271,15 @@
 // Instead of /0, /1... print human-readable description of the test: type of
 // the user signed in and the list of conditionally enabled features.
 std::string PrettyPrintTestCaseName(
-    const ::testing::TestParamInfo<ParamsTuple>& info) {
+    const ::testing::TestParamInfo<TestCase>& info) {
   std::stringstream ss;
-  ss << TestCase(info.param).GetSignInMode() << "Account";
-  ss << (TestCase(info.param).ProtoFetcherEnabled() ? "WithProtoFetcher"
-                                                    : "WithoutProtoFetcher");
-  ss << (TestCase(info.param).FilterWebsitesEnabled()
-             ? "WithFilterWebsites"
-             : "WithoutFilterWebsites");
+  ss << GetSignInMode(info.param) << "Account";
+  if (ProtoFetcherEnabled(info.param)) {
+    ss << "WithProtoFetcher";
+  }
+  if (FilterWebsitesEnabled(info.param)) {
+    ss << "WithFilterWebsites";
+  }
   return ss.str();
 }
 
diff --git a/chrome/browser/supervised_user/supervised_user_url_filter_browsertest.cc b/chrome/browser/supervised_user/supervised_user_url_filter_browsertest.cc
index b1a62a9..7a0fb92e 100644
--- a/chrome/browser/supervised_user/supervised_user_url_filter_browsertest.cc
+++ b/chrome/browser/supervised_user/supervised_user_url_filter_browsertest.cc
@@ -11,7 +11,6 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
-#include "base/types/strong_alias.h"
 #include "base/values.h"
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
@@ -63,7 +62,7 @@
 namespace {
 
 // Tests filtering for supervised users.
-class SupervisedUserURLFilterTestBase : public MixinBasedInProcessBrowserTest {
+class SupervisedUserURLFilterTest : public MixinBasedInProcessBrowserTest {
  public:
   // Indicates whether the interstitial should proceed or not.
   enum InterstitialAction {
@@ -71,7 +70,7 @@
     INTERSTITIAL_DONTPROCEED,
   };
 
-  SupervisedUserURLFilterTestBase() {
+  SupervisedUserURLFilterTest() {
     // TODO(crbug.com/1394910): Use HTTPS URLs in tests to avoid having to
     // disable this feature.
     feature_list_.InitWithFeatures(
@@ -79,7 +78,13 @@
          supervised_user::kSupervisedPrefsControlledBySupervisedStore},
         {features::kHttpsUpgrades});
   }
-  ~SupervisedUserURLFilterTestBase() override { feature_list_.Reset(); }
+  ~SupervisedUserURLFilterTest() override { feature_list_.Reset(); }
+
+  // TODO(crbug.com/1491942): This fails with the field trial testing config.
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    MixinBasedInProcessBrowserTest::SetUpCommandLine(command_line);
+    command_line->AppendSwitch("disable-field-trial-config");
+  }
 
   bool ShownPageIsInterstitial(Browser* browser) {
     WebContents* tab = browser->tab_strip_model()->GetActiveWebContents();
@@ -127,15 +132,10 @@
     run_loop.Run();  // Will go until ...Complete calls Quit.
   }
 
-  supervised_user::KidsManagementApiServerMock& kids_management_api_mock() {
-    return supervision_mixin_.api_mock_setup_mixin().api_mock();
-  }
-
   supervised_user::SupervisedUserService* GetSupervisedUserService() const {
     return SupervisedUserServiceFactory::GetForProfile(browser()->profile());
   }
 
- private:
   base::test::ScopedFeatureList feature_list_;
   supervised_user::SupervisionMixin supervision_mixin_{
       mixin_host_,
@@ -196,40 +196,14 @@
   raw_ptr<content::WebContents> contents_;
 };
 
-using UseProtoFetcher = base::StrongAlias<class UseProtoFetcherTag, bool>;
-class SupervisedUserURLFilterTest
-    : public SupervisedUserURLFilterTestBase,
-      public ::testing::WithParamInterface<UseProtoFetcher> {
- public:
-  SupervisedUserURLFilterTest() {
-    if (UseProtoFetcher()) {
-      proto_api_feature_list_.InitAndEnableFeature(
-          supervised_user::kEnableProtoApiForClassifyUrl);
-    } else {
-      proto_api_feature_list_.InitAndDisableFeature(
-          supervised_user::kEnableProtoApiForClassifyUrl);
-    }
-  }
-
- private:
-  bool UseProtoFetcher() const { return GetParam().value(); }
-  base::test::ScopedFeatureList proto_api_feature_list_;
-};
-
 // Navigates to a page in a new tab, then blocks it (which makes the
 // interstitial page behave differently from the preceding test, where the
 // navigation is blocked before it commits). The expected behavior is the same
 // though: the tab should be closed when going back.
-IN_PROC_BROWSER_TEST_P(SupervisedUserURLFilterTest, BlockNewTabAfterLoading) {
+IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest, BlockNewTabAfterLoading) {
   TabStripModel* tab_strip = browser()->tab_strip_model();
   WebContents* prev_tab = tab_strip->GetActiveWebContents();
 
-  if (supervised_user::IsProtoApiForClassifyUrlEnabled()) {
-    kids_management_api_mock().AllowSubsequentClassifyUrl();
-    EXPECT_CALL(kids_management_api_mock().classify_url_mock(), ClassifyUrl)
-        .Times(1);
-  }
-
   // Open URL in a new tab.
   GURL test_url("http://www.example.com/simple.html");
   ui_test_utils::NavigateToURLWithDisposition(
@@ -275,17 +249,11 @@
 
 // Tests that we don't end up canceling an interstitial (thereby closing the
 // whole tab) by attempting to show a second one above it.
-IN_PROC_BROWSER_TEST_P(SupervisedUserURLFilterTest, DontShowInterstitialTwice) {
+IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest, DontShowInterstitialTwice) {
   TabStripModel* tab_strip = browser()->tab_strip_model();
 
   // Open URL in a new tab.
   GURL test_url("http://www.example.com/simple.html");
-
-  if (supervised_user::IsProtoApiForClassifyUrlEnabled()) {
-    kids_management_api_mock().AllowSubsequentClassifyUrl();
-    EXPECT_CALL(kids_management_api_mock().classify_url_mock(), ClassifyUrl)
-        .Times(1);
-  }
   ui_test_utils::NavigateToURLWithDisposition(
       browser(), test_url, WindowOpenDisposition::NEW_FOREGROUND_TAB,
       ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP);
@@ -322,7 +290,7 @@
   EXPECT_EQ(tab, tab_strip->GetActiveWebContents());
 }
 
-IN_PROC_BROWSER_TEST_P(SupervisedUserURLFilterTest, GoBackOnDontProceed) {
+IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest, GoBackOnDontProceed) {
   WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   // Ensure navigation completes.
@@ -331,11 +299,6 @@
   ASSERT_EQ(0, web_contents->GetController().GetCurrentEntryIndex());
 
   GURL test_url("http://www.example.com/simple.html");
-  if (supervised_user::IsProtoApiForClassifyUrlEnabled()) {
-    kids_management_api_mock().AllowSubsequentClassifyUrl();
-    EXPECT_CALL(kids_management_api_mock().classify_url_mock(), ClassifyUrl)
-        .Times(1);
-  }
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
 
   ASSERT_FALSE(ShownPageIsInterstitial(browser()));
@@ -366,7 +329,7 @@
   EXPECT_EQ(0, web_contents->GetController().GetCurrentEntryIndex());
 }
 
-IN_PROC_BROWSER_TEST_P(SupervisedUserURLFilterTest,
+IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest,
                        ClosingBlockedTabDoesNotCrash) {
   WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
@@ -375,11 +338,7 @@
   ASSERT_EQ(0, web_contents->GetController().GetCurrentEntryIndex());
 
   GURL test_url("http://www.example.com/simple.html");
-  if (supervised_user::IsProtoApiForClassifyUrlEnabled()) {
-    kids_management_api_mock().AllowSubsequentClassifyUrl();
-    EXPECT_CALL(kids_management_api_mock().classify_url_mock(), ClassifyUrl)
-        .Times(1);
-  }
+
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
   ASSERT_FALSE(ShownPageIsInterstitial(browser()));
 
@@ -404,13 +363,8 @@
       0, TabCloseTypes::CLOSE_USER_GESTURE);
 }
 
-IN_PROC_BROWSER_TEST_P(SupervisedUserURLFilterTest, BlockThenUnblock) {
+IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterTest, BlockThenUnblock) {
   GURL test_url("http://www.example.com/simple.html");
-  if (supervised_user::IsProtoApiForClassifyUrlEnabled()) {
-    kids_management_api_mock().AllowSubsequentClassifyUrl();
-    EXPECT_CALL(kids_management_api_mock().classify_url_mock(), ClassifyUrl)
-        .Times(1);
-  }
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
 
   WebContents* web_contents =
@@ -456,19 +410,11 @@
   EXPECT_FALSE(ShownPageIsInterstitial(browser()));
 }
 
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    SupervisedUserURLFilterTest,
-    ::testing::Values(UseProtoFetcher(true), UseProtoFetcher(false)),
-    [](const ::testing::TestParamInfo<UseProtoFetcher>& info) {
-      return info.param.value() ? "ProtoFetcher" : "JsonFetcher";
-    });
-
 // Tests the filter mode in which all sites are blocked by default.
-class SupervisedUserBlockModeTest : public SupervisedUserURLFilterTestBase {
+class SupervisedUserBlockModeTest : public SupervisedUserURLFilterTest {
  public:
   void SetUpOnMainThread() override {
-    SupervisedUserURLFilterTestBase::SetUpOnMainThread();
+    SupervisedUserURLFilterTest::SetUpOnMainThread();
     Profile* profile = browser()->profile();
     supervised_user::SupervisedUserSettingsService*
         supervised_user_settings_service =
@@ -690,19 +636,12 @@
 };
 
 // Tests that prerendering doesn't check SupervisedUserURLFilter.
-IN_PROC_BROWSER_TEST_P(SupervisedUserURLFilterPrerenderingTest, OnURLChecked) {
+IN_PROC_BROWSER_TEST_F(SupervisedUserURLFilterPrerenderingTest, OnURLChecked) {
   MockSupervisedUserURLFilterObserver observer(
       GetSupervisedUserService()->GetURLFilter());
 
   GURL test_url("http://www.example.com/simple.html");
   EXPECT_CALL(observer, OnURLChecked).Times(1);
-  if (supervised_user::IsProtoApiForClassifyUrlEnabled()) {
-    kids_management_api_mock().AllowSubsequentClassifyUrl();
-    EXPECT_CALL(kids_management_api_mock().classify_url_mock(),
-                ClassifyUrl)
-        .Times(2);  // One for request and one for prerender.
-  }
-
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), test_url));
   testing::Mock::VerifyAndClearExpectations(&observer);
 
@@ -730,13 +669,4 @@
   EXPECT_CALL(observer, OnURLChecked).Times(1);
   prerender_helper().NavigatePrimaryPage(prerender_url);
 }
-
-INSTANTIATE_TEST_SUITE_P(
-    All,
-    SupervisedUserURLFilterPrerenderingTest,
-    ::testing::Values(UseProtoFetcher(true), UseProtoFetcher(false)),
-    [](const ::testing::TestParamInfo<UseProtoFetcher>& info) {
-      return info.param.value() ? "ProtoFetcher" : "JsonFetcher";
-    });
-
 }  // namespace
diff --git a/chrome/browser/ui/android/omnibox/java/res/layout/url_action_container.xml b/chrome/browser/ui/android/omnibox/java/res/layout/url_action_container.xml
index d462241..9539b710 100644
--- a/chrome/browser/ui/android/omnibox/java/res/layout/url_action_container.xml
+++ b/chrome/browser/ui/android/omnibox/java/res/layout/url_action_container.xml
@@ -29,9 +29,6 @@
             android:visibility="invisible"
             android:contentDescription="@string/accessibility_toolbar_btn_mic" />
 
-    <!-- This is a short term solution to have 2 Lens buttons in this xml to
-         support different position variants in experiment.
-         TODO(b/182195615): only keep one Lens button after the experiment. -->
         <org.chromium.ui.widget.ChromeImageButton
             android:id="@+id/lens_camera_button"
             style="@style/LocationBarActionButton"
@@ -54,4 +51,4 @@
             android:contentDescription="@string/download_page" />
 
     </LinearLayout>
-</merge>
\ No newline at end of file
+</merge>
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
index fe6e0071..09b8f05 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBar.java
@@ -30,6 +30,7 @@
 import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 import androidx.core.text.BidiFormatter;
 import androidx.core.text.TextDirectionHeuristicsCompat;
 import androidx.core.view.inputmethod.EditorInfoCompat;
@@ -104,8 +105,11 @@
     private boolean mAllowFocus = true;
 
     private boolean mPendingScroll;
-    private int mPreviousWidth;
 
+    // Captures the current intended text scroll type.
+    // This may not be effective if mPendingScroll is true.
+    @ScrollType private int mCurrentScrollType;
+    // Captures previously calculated text scroll type.
     @ScrollType private int mPreviousScrollType;
     private String mPreviousScrollText;
     private int mPreviousScrollViewWidth;
@@ -136,8 +140,6 @@
     Editable mScrollToTLDPrevUrl;
     int mScrollToTLDPrevEndIndex;
 
-    @ScrollType private int mScrollType;
-
     /** What scrolling action should be taken after the URL bar text changes. * */
     @IntDef({ScrollType.NO_SCROLL, ScrollType.SCROLL_TO_TLD, ScrollType.SCROLL_TO_BEGINNING})
     @Retention(RetentionPolicy.SOURCE)
@@ -293,7 +295,8 @@
     }
 
     @Override
-    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
+    @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
+    public void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
         mFocused = focused;
         super.onFocusChanged(focused, direction, previouslyFocusedRect);
 
@@ -439,7 +442,7 @@
             }
 
             // Ensure the display text is visible after updating the URL direction.
-            scrollDisplayText();
+            scrollDisplayText(mCurrentScrollType);
         }
     }
 
@@ -619,8 +622,7 @@
         } else {
             mOriginEndIndex = 0;
         }
-        mScrollType = scrollType;
-        scrollDisplayText();
+        scrollDisplayText(scrollType);
     }
 
     /**
@@ -647,19 +649,6 @@
         return getMeasuredWidth() - (getPaddingLeft() + getPaddingRight());
     }
 
-    /**
-     * Scrolls the omnibox text to a position determined by the current scroll type.
-     *
-     * @see #setScrollState(int, int)
-     */
-    private void scrollDisplayText() {
-        if (isLayoutRequested()) {
-            mPendingScroll = mScrollType != ScrollType.NO_SCROLL;
-            return;
-        }
-        scrollDisplayTextInternal(mScrollType);
-    }
-
     private boolean isVisibleTextTheSame(Editable text) {
         if (text == null) {
             return false;
@@ -679,8 +668,17 @@
      *     bring the TLD into view. SCROLL_TO_BEGINNING: Scrolls text that's too long to fit in the
      *     omnibox to the beginning so we can see the first character.
      */
-    private void scrollDisplayTextInternal(@ScrollType int scrollType) {
-        mPendingScroll = false;
+    @VisibleForTesting
+    public void scrollDisplayText(@ScrollType int scrollType) {
+        // It's possible that text layout is not available right now. This could happen when the
+        // call is made before the text could be measured. Fall back to safe defaults, even if not
+        // correct for RTL layouts - this should be very rare (~10 cases per day worldwide).
+        // The layout will likely be available after the view measures itself again.
+        // Postpone scroll until we view and text layout are known.
+        // Request scroll update in case scroll type or view dimensions have changed.
+        mCurrentScrollType = scrollType;
+        mPendingScroll = isLayoutRequested() || (getLayout() == null);
+        if (mPendingScroll) return;
 
         if (mFocused) return;
 
@@ -703,6 +701,7 @@
                 && currentIsRtl == mPreviousScrollWasRtl
                 && isVisibleTextTheSame(text)) {
             scrollTo(mPreviousScrollResultXPosition, getScrollY());
+
             return;
         }
 
@@ -730,8 +729,9 @@
     }
 
     /** Scrolls the omnibox text to show the very beginning of the text entered. */
-    private void scrollToBeginning() {
-        // Clearly the visible text hint as this path is not used for normal browser navigation.
+    @VisibleForTesting
+    /* package */ void scrollToBeginning() {
+        // Clear the visible text hint as this path is not used for normal browser navigation.
         // If that changes in the future, update this to actually calculate the visible text hints.
         mVisibleTextPrefixHint = null;
 
@@ -828,7 +828,8 @@
     }
 
     /** Scrolls the omnibox text to bring the TLD into view. */
-    private void scrollToTLD() {
+    @VisibleForTesting
+    /* package */ void scrollToTLD() {
         Editable url = getText();
         int measuredWidth = getVisibleMeasuredViewportWidth();
         int urlTextLength = url.length();
@@ -950,15 +951,19 @@
     }
 
     @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
+    public void layout(int left, int top, int right, int bottom) {
+        super.layout(left, top, right, bottom);
 
-        if (mPendingScroll) {
-            scrollDisplayTextInternal(mScrollType);
-        } else if (mPreviousWidth != (right - left)) {
-            scrollDisplayTextInternal(mScrollType);
+        // Note: this must happen after the *entire* layout cycle completes.
+        // Running this during onLayout guarantees that isLayoutRequested will remain true,
+        // and the text layout will remain unresolved, suppressing resolution of display text
+        // scroll position.
+        if (mPendingScroll || mPreviousScrollViewWidth != getVisibleMeasuredViewportWidth()) {
+            scrollDisplayText(mCurrentScrollType);
+            // sanity check: be sure we don't re-request layout as a result of something that
+            // happens in scrollDisplayText().
+            assert !isLayoutRequested();
         }
-        mPreviousWidth = right - left;
     }
 
     @Override
@@ -1135,4 +1140,9 @@
             canvas.drawText(ELLIPSIS, x, y, paint);
         }
     }
+
+    @VisibleForTesting
+    /* package */ boolean hasPendingDisplayTextScrollForTesting() {
+        return mPendingScroll;
+    }
 }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarUnitTest.java
index 2cdd51b..f3c6c53 100644
--- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarUnitTest.java
+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/UrlBarUnitTest.java
@@ -5,7 +5,16 @@
 package org.chromium.chrome.browser.omnibox;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.AdditionalMatchers.not;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
@@ -14,6 +23,7 @@
 import android.text.Layout;
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
+import android.view.ContextThemeWrapper;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.MeasureSpec;
@@ -42,6 +52,7 @@
 import org.chromium.base.test.util.HistogramWatcher;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.omnibox.UrlBar.UrlBarDelegate;
+import org.chromium.chrome.browser.omnibox.test.R;
 import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
 import org.chromium.chrome.test.util.browser.Features.JUnitProcessor;
@@ -50,8 +61,13 @@
 
 /** Unit tests for the URL bar UI component. */
 @RunWith(BaseRobolectricTestRunner.class)
-@Config(qualifiers = "w100dp-h50dp")
+@Config(
+        qualifiers = "w100dp-h50dp",
+        shadows = {UrlBarUnitTest.UrlBarShadowLayout.class, UrlBarUnitTest.UrlBarShadowPaint.class})
 public class UrlBarUnitTest {
+    private static final int URL_BAR_WIDTH = 100;
+    private static final int URL_BAR_HEIGHT = 10;
+
     private UrlBar mUrlBar;
     public @Rule TestRule mFeaturesProcessorRule = new JUnitProcessor();
     public @Rule MockitoRule mockitoRule = MockitoJUnit.rule();
@@ -72,7 +88,7 @@
     private final int mNumberOfVisibleCharacters = 20;
 
     @Implements(Layout.class)
-    public static class ShadowLayout {
+    public static class UrlBarShadowLayout {
         @Implementation
         public float getPrimaryHorizontal(int offset) {
             return (float) offset * 5;
@@ -87,7 +103,7 @@
     }
 
     @Implements(Paint.class)
-    public static class MyShadowPaint extends ShadowPaint {
+    public static class UrlBarShadowPaint extends ShadowPaint {
         @Implementation
         public int getOffsetForAdvance(
                 CharSequence text,
@@ -103,12 +119,39 @@
 
     @Before
     public void setUp() {
-        mUrlBar = spy(new UrlBarApi26(ContextUtils.getApplicationContext(), null));
+        var ctx =
+                new ContextThemeWrapper(
+                        ContextUtils.getApplicationContext(), R.style.Theme_AppCompat);
+        mUrlBar = spy(new UrlBarApi26(ctx, null));
         mUrlBar.setDelegate(mUrlBarDelegate);
+    }
 
-        LayoutParams params =
-                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
-        mUrlBar.setLayoutParams(params);
+    /** Force reset text layout. */
+    private void resetTextLayout() {
+        mUrlBar.nullLayouts();
+        assertNull(mUrlBar.getLayout());
+    }
+
+    /**
+     * Simulate measure() and layout() pass on the view. Ensures view size and text layout are
+     * resolved.
+     */
+    private void measureAndLayoutUrlBarForSize(int width, int height) {
+        // Measure and layout the Url bar.
+        mUrlBar.setLayoutParams(new LayoutParams(width, height));
+        mUrlBar.measure(
+                MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
+                MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
+        mUrlBar.layout(0, 0, width, height);
+
+        // Sanity check: new layout should be available.
+        assertNotNull(mUrlBar.getLayout());
+        assertFalse(mUrlBar.isLayoutRequested());
+    }
+
+    /** Resize the UrlBar to its default size for testing. */
+    private void measureAndLayoutUrlBar() {
+        measureAndLayoutUrlBarForSize(URL_BAR_WIDTH, URL_BAR_HEIGHT);
     }
 
     @Test
@@ -185,6 +228,7 @@
     @Test
     @EnableFeatures(ChromeFeatureList.ANDROID_VISIBLE_URL_TRUNCATION)
     public void testTruncation_LongUrl() {
+        measureAndLayoutUrlBar();
         String url = mShortDomain + mLongPath;
         mUrlBar.setTextWithTruncation(url, UrlBar.ScrollType.SCROLL_TO_TLD, mShortDomain.length());
         String text = mUrlBar.getText().toString();
@@ -203,6 +247,7 @@
     @Test
     @EnableFeatures(ChromeFeatureList.ANDROID_VISIBLE_URL_TRUNCATION)
     public void testTruncation_LongTld_ScrollToTld() {
+        measureAndLayoutUrlBar();
         String url = mLongDomain + mShortPath;
         mUrlBar.setTextWithTruncation(url, UrlBar.ScrollType.SCROLL_TO_TLD, mLongDomain.length());
         String text = mUrlBar.getText().toString();
@@ -212,6 +257,7 @@
     @Test
     @EnableFeatures(ChromeFeatureList.ANDROID_VISIBLE_URL_TRUNCATION)
     public void testTruncation_LongTld_ScrollToBeginning() {
+        measureAndLayoutUrlBar();
         String url = mShortDomain + mLongPath;
         mUrlBar.setTextWithTruncation(url, UrlBar.ScrollType.SCROLL_TO_BEGINNING, 0);
         String text = mUrlBar.getText().toString();
@@ -221,6 +267,7 @@
     @Test
     @EnableFeatures(ChromeFeatureList.ANDROID_VISIBLE_URL_TRUNCATION)
     public void testTruncation_NoTruncationForWrapContent() {
+        measureAndLayoutUrlBar();
         LayoutParams previousLayoutParams = mUrlBar.getLayoutParams();
         LayoutParams params =
                 new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
@@ -254,21 +301,10 @@
 
     @Test
     @EnableFeatures(ChromeFeatureList.ANDROID_NO_VISIBLE_HINT_FOR_TABLETS)
-    @Config(
-            qualifiers = "w600dp-h820dp",
-            shadows = {ShadowLayout.class, MyShadowPaint.class})
+    @Config(qualifiers = "sw600dp")
     public void testNoVisibleHintCalculationForTablets_noHistogramRecords() {
-        // Ensure that Views and Layouts aren't null.
-        mUrlBar.measure(
-                MeasureSpec.makeMeasureSpec(820, MeasureSpec.EXACTLY),
-                MeasureSpec.makeMeasureSpec(20, MeasureSpec.EXACTLY));
-        mUrlBar.layout(0, 0, mUrlBar.getMeasuredWidth(), mUrlBar.getMeasuredHeight());
-
-        // Avoid short circuiting in scrollDisplayText().
-        doReturn(false).when(mUrlBar).isLayoutRequested();
-
-        String url = mShortDomain + mLongPath;
-        mUrlBar.setText(url);
+        measureAndLayoutUrlBar();
+        mUrlBar.setText(mShortDomain + mLongPath);
 
         HistogramWatcher histogramWatcher =
                 HistogramWatcher.newBuilder()
@@ -280,19 +316,13 @@
     }
 
     @Test
-    @Config(shadows = {ShadowLayout.class, MyShadowPaint.class})
     public void testVisibleHintCalculationHistograms() {
-        // Ensure that Views and Layouts aren't null.
-        mUrlBar.measure(
-                MeasureSpec.makeMeasureSpec(100, MeasureSpec.EXACTLY),
-                MeasureSpec.makeMeasureSpec(10, MeasureSpec.EXACTLY));
-        mUrlBar.layout(0, 0, mUrlBar.getMeasuredWidth(), mUrlBar.getMeasuredHeight());
-
-        // Avoid short circuiting in scrollDisplayText().
-        doReturn(false).when(mUrlBar).isLayoutRequested();
-
-        String url = mShortDomain + mLongPath;
-        mUrlBar.setText(url);
+        // Note: this test always assumed unstyled size of the Omnibox.
+        // The recorded test values differ when actual theming is applied.
+        // For that reason, we re-set the UrlBar to unstyled variant.
+        mUrlBar = spy(new UrlBarApi26(ContextUtils.getApplicationContext(), null));
+        measureAndLayoutUrlBar();
+        mUrlBar.setText(mShortDomain + mLongPath);
 
         HistogramWatcher histogramWatcher =
                 HistogramWatcher.newBuilder()
@@ -306,18 +336,20 @@
 
     @Test
     @DisableFeatures(ChromeFeatureList.ANDROID_VISIBLE_URL_TRUNCATION)
-    public void testSetLengtHistogram_noTruncation() {
+    public void testSetLengthHistogram_noTruncation() {
+        measureAndLayoutUrlBar();
         String url = mShortDomain + mLongPath;
 
         HistogramWatcher histogramWatcher =
                 HistogramWatcher.newSingleRecordWatcher("Omnibox.SetText.TextLength", url.length());
-        mUrlBar.setText(url);
+        mUrlBar.setText(mShortDomain + mLongPath);
         histogramWatcher.assertExpected();
     }
 
     @Test
     @EnableFeatures(ChromeFeatureList.ANDROID_VISIBLE_URL_TRUNCATION)
     public void testSetLengtHistogram_withTruncation() {
+        measureAndLayoutUrlBar();
         String url = mShortDomain + mLongPath;
 
         HistogramWatcher histogramWatcher =
@@ -326,4 +358,174 @@
         mUrlBar.setTextWithTruncation(url, UrlBar.ScrollType.SCROLL_TO_TLD, mShortDomain.length());
         histogramWatcher.assertExpected();
     }
+
+    @Test
+    public void
+            scrollToBeginning_fallBackToDefaultWhenLayoutUnavailable_ltrLayout_noText_ltrHint() {
+        // Explicitly invalidate text layouts. This could happen for a number of reasons.
+        // This is also the implicit default value until text is measured, but don't rely on this.
+        doReturn(View.LAYOUT_DIRECTION_LTR).when(mUrlBar).getLayoutDirection();
+        mUrlBar.setHint("hint text");
+        resetTextLayout();
+
+        // As long as layouts are not available, no action should be taken.
+        // This is typically the case when the text view or content is manipulated in some way and
+        // has not yet completed the full measure/layout cycle.
+        mUrlBar.scrollDisplayText(UrlBar.ScrollType.SCROLL_TO_BEGINNING);
+        verify(mUrlBar, never()).scrollTo(anyInt(), anyInt());
+        assertTrue(mUrlBar.hasPendingDisplayTextScrollForTesting());
+        clearInvocations(mUrlBar);
+
+        // LTR layout always scrolls to 0, because that's the natural origin of LTR text.
+        measureAndLayoutUrlBar();
+        verify(mUrlBar).scrollTo(0, 0);
+        assertFalse(mUrlBar.hasPendingDisplayTextScrollForTesting());
+        clearInvocations(mUrlBar);
+
+        // Simulate request to update scroll type with no changes of scroll type, text, or view
+        // size. This should avoid recalculations and simply re-set the scroll position.
+        mUrlBar.scrollDisplayText(UrlBar.ScrollType.SCROLL_TO_BEGINNING);
+        verify(mUrlBar, never()).scrollToTLD();
+        verify(mUrlBar, never()).scrollToBeginning();
+        verify(mUrlBar).scrollTo(0, 0);
+    }
+
+    @Test
+    public void
+            scrollToBeginning_fallBackToDefaultWhenLayoutUnavailable_rtlLayout_noText_ltrHint() {
+        // Explicitly invalidate text layouts. This could happen for a number of reasons.
+        // This is also the implicit default value until text is measured, but don't rely on this.
+        doReturn(View.LAYOUT_DIRECTION_RTL).when(mUrlBar).getLayoutDirection();
+        mUrlBar.setHint("hint text");
+        resetTextLayout();
+
+        // As long as layouts are not available, no action should be taken.
+        // This is typically the case when the text view or content is manipulated in some way and
+        // has not yet completed the full measure/layout cycle.
+        mUrlBar.scrollDisplayText(UrlBar.ScrollType.SCROLL_TO_BEGINNING);
+        verify(mUrlBar, never()).scrollTo(anyInt(), anyInt());
+        assertTrue(mUrlBar.hasPendingDisplayTextScrollForTesting());
+        clearInvocations(mUrlBar);
+
+        // RTL layouts should scroll to 0 too, because that's the natural origin of LTR text.
+        measureAndLayoutUrlBar();
+        verify(mUrlBar).scrollTo(0, 0);
+        assertFalse(mUrlBar.hasPendingDisplayTextScrollForTesting());
+        clearInvocations(mUrlBar);
+
+        // Simulate request to update scroll type with no changes of scroll type, text, or view
+        // size. This should avoid recalculations and simply re-set the scroll position.
+        mUrlBar.scrollDisplayText(UrlBar.ScrollType.SCROLL_TO_BEGINNING);
+        verify(mUrlBar, never()).scrollToTLD();
+        verify(mUrlBar, never()).scrollToBeginning();
+        verify(mUrlBar).scrollTo(0, 0);
+    }
+
+    @Test
+    public void
+            scrollToBeginning_fallBackToDefaultWhenLayoutUnavailable_ltrLayout_noText_rtlHint() {
+        // Explicitly invalidate text layouts. This could happen for a number of reasons.
+        // This is also the implicit default value until text is measured, but don't rely on this.
+        doReturn(View.LAYOUT_DIRECTION_LTR).when(mUrlBar).getLayoutDirection();
+        mUrlBar.setHint("טקסט רמז");
+        resetTextLayout();
+
+        // As long as layouts are not available, no action should be taken.
+        // This is typically the case when the text view or content is manipulated in some way and
+        // has not yet completed the full measure/layout cycle.
+        mUrlBar.scrollDisplayText(UrlBar.ScrollType.SCROLL_TO_BEGINNING);
+        verify(mUrlBar, never()).scrollTo(anyInt(), anyInt());
+        assertTrue(mUrlBar.hasPendingDisplayTextScrollForTesting());
+        clearInvocations(mUrlBar);
+
+        // LTR layout always scrolls to 0, even if the hint text is RTL. View hierarchy dictates the
+        // layout direction.
+        measureAndLayoutUrlBar();
+        verify(mUrlBar).scrollTo(0, 0);
+        assertFalse(mUrlBar.hasPendingDisplayTextScrollForTesting());
+        clearInvocations(mUrlBar);
+
+        // Simulate request to update scroll type with no changes of scroll type, text, or view
+        // size. This should avoid recalculations and simply re-set the scroll position.
+        mUrlBar.scrollDisplayText(UrlBar.ScrollType.SCROLL_TO_BEGINNING);
+        verify(mUrlBar, never()).scrollToTLD();
+        verify(mUrlBar, never()).scrollToBeginning();
+        verify(mUrlBar).scrollTo(0, 0);
+    }
+
+    @Test
+    public void
+            scrollToBeginning_fallBackToDefaultWhenLayoutUnavailable_rtlLayout_noText_rtlHint() {
+        // Explicitly invalidate text layouts. This could happen for a number of reasons.
+        // This is also the implicit default value until text is measured, but don't rely on this.
+        doReturn(View.LAYOUT_DIRECTION_RTL).when(mUrlBar).getLayoutDirection();
+        mUrlBar.setHint("טקסט רמז");
+        resetTextLayout();
+
+        // As long as layouts are not available, no action should be taken.
+        // This is typically the case when the text view or content is manipulated in some way and
+        // has not yet completed the full measure/layout cycle.
+        mUrlBar.scrollDisplayText(UrlBar.ScrollType.SCROLL_TO_BEGINNING);
+        verify(mUrlBar, never()).scrollTo(anyInt(), anyInt());
+        assertTrue(mUrlBar.hasPendingDisplayTextScrollForTesting());
+        clearInvocations(mUrlBar);
+
+        // RTL layout should position RTL text at an appropriate offset relative to view end.
+        measureAndLayoutUrlBar();
+        verify(mUrlBar).scrollTo(not(eq(0)), eq(0));
+        assertFalse(mUrlBar.hasPendingDisplayTextScrollForTesting());
+        clearInvocations(mUrlBar);
+
+        // Simulate request to update scroll type with no changes of scroll type, text, or view
+        // size. This should avoid recalculations and simply re-set the scroll position.
+        mUrlBar.scrollDisplayText(UrlBar.ScrollType.SCROLL_TO_BEGINNING);
+        verify(mUrlBar, never()).scrollToTLD();
+        verify(mUrlBar, never()).scrollToBeginning();
+        verify(mUrlBar).scrollTo(not(eq(0)), eq(0));
+    }
+
+    @Test
+    public void layout_noScrollWithNoSizeChanges() {
+        // Initialize the URL bar. Verify test conditions.
+        mUrlBar.setText(mShortDomain);
+        mUrlBar.scrollDisplayText(UrlBar.ScrollType.SCROLL_TO_BEGINNING);
+        measureAndLayoutUrlBar();
+        assertFalse(mUrlBar.hasPendingDisplayTextScrollForTesting());
+        clearInvocations(mUrlBar);
+
+        // Simulate layout re-entry.
+        // We know the url bar has no pending scroll request, and we apply the same size.
+        measureAndLayoutUrlBar();
+        verify(mUrlBar, never()).scrollDisplayText(anyInt());
+    }
+
+    @Test
+    public void layout_noScrollWhenHeightChanges() {
+        // Initialize the URL bar. Verify test conditions.
+        mUrlBar.setText(mShortDomain);
+        mUrlBar.scrollDisplayText(UrlBar.ScrollType.SCROLL_TO_BEGINNING);
+        measureAndLayoutUrlBar();
+        assertFalse(mUrlBar.hasPendingDisplayTextScrollForTesting());
+        clearInvocations(mUrlBar);
+
+        // Simulate layout re-entry.
+        // We change the height of the view which should not affect scroll position.
+        measureAndLayoutUrlBarForSize(URL_BAR_WIDTH, URL_BAR_HEIGHT + 1);
+        verify(mUrlBar, never()).scrollDisplayText(anyInt());
+    }
+
+    @Test
+    public void layout_updateScrollWhenWidthChanges() {
+        // Initialize the URL bar. Verify test conditions.
+        mUrlBar.setText(mShortDomain);
+        mUrlBar.scrollDisplayText(UrlBar.ScrollType.SCROLL_TO_BEGINNING);
+        measureAndLayoutUrlBar();
+        assertFalse(mUrlBar.hasPendingDisplayTextScrollForTesting());
+        clearInvocations(mUrlBar);
+
+        // Simulate layout re-entry.
+        // We change the width, which may impact scroll position.
+        measureAndLayoutUrlBarForSize(URL_BAR_WIDTH + 1, URL_BAR_HEIGHT);
+        verify(mUrlBar).scrollDisplayText(anyInt());
+    }
 }
diff --git a/chrome/browser/ui/android/toolbar/BUILD.gn b/chrome/browser/ui/android/toolbar/BUILD.gn
index 3fac664..99afd553 100644
--- a/chrome/browser/ui/android/toolbar/BUILD.gn
+++ b/chrome/browser/ui/android/toolbar/BUILD.gn
@@ -94,6 +94,7 @@
     "java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarProperties.java",
     "java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarView.java",
     "java/src/org/chromium/chrome/browser/toolbar/top/StartSurfaceToolbarViewBinder.java",
+    "java/src/org/chromium/chrome/browser/toolbar/top/TabStripTransitionCoordinator.java",
     "java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherActionMenuCoordinator.java",
     "java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTTCoordinator.java",
     "java/src/org/chromium/chrome/browser/toolbar/top/TabSwitcherModeTopToolbar.java",
@@ -332,6 +333,7 @@
     "java/src/org/chromium/chrome/browser/toolbar/optional_button/OptionalButtonViewTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/top/OptionalBrowsingModeButtonControllerTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/top/PhoneCaptureStateTokenTest.java",
+    "java/src/org/chromium/chrome/browser/toolbar/top/TabStripTransitionCoordinatorUnitTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/top/TabletCaptureStateTokenTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/top/ToggleTabStackButtonCoordinatorTest.java",
     "java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java",
@@ -385,6 +387,7 @@
     "//third_party/androidx:androidx_fragment_fragment_testing_java",
     "//third_party/androidx:androidx_preference_preference_java",
     "//third_party/androidx:androidx_test_core_java",
+    "//third_party/androidx:androidx_test_ext_junit_java",
     "//third_party/androidx:androidx_test_runner_java",
     "//third_party/hamcrest:hamcrest_java",
     "//third_party/hamcrest:hamcrest_library_java",
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabStripTransitionCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabStripTransitionCoordinator.java
new file mode 100644
index 0000000..3d33c999
--- /dev/null
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabStripTransitionCoordinator.java
@@ -0,0 +1,254 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.toolbar.top;
+
+import android.content.ComponentCallbacks;
+import android.content.res.Configuration;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.View.OnLayoutChangeListener;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import org.chromium.base.ObserverList;
+import org.chromium.base.ResettersForTesting;
+import org.chromium.chrome.browser.browser_controls.BrowserControlsSizer;
+import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
+import org.chromium.chrome.browser.browser_controls.BrowserControlsVisibilityManager;
+import org.chromium.chrome.browser.toolbar.R;
+import org.chromium.ui.base.DeviceFormFactor;
+import org.chromium.ui.base.ViewUtils;
+
+/** Subclass used to manage tab strip visibility and height presents. */
+public class TabStripTransitionCoordinator implements ComponentCallbacks {
+
+    /** Observes height of tab strip that could change during run time. */
+    public interface TabStripHeightObserver {
+        /** Notified when the tab strip height is about to change. */
+        void onTabStripHeightChanged(int newHeight);
+    }
+
+    private static Integer sMinScreenWidthForTesting;
+
+    private final ObserverList<TabStripHeightObserver> mTabStripHeightObservers =
+            new ObserverList<>();
+    private final BrowserControlsVisibilityManager mBrowserControlsVisibilityManager;
+    private final View mControlContainer;
+    private final View mToolbarLayout;
+    private final int mTabStripHeightFromResource;
+
+    private int mTabStripHeight;
+    private boolean mTabStripVisible;
+    private @Nullable BrowserControlsStateProvider.Observer mBrowserControlsObserver;
+    private @Nullable OnLayoutChangeListener mOnLayoutChangedListener;
+
+    /**
+     * Create the coordinator managing transitions for when showing / hiding the tab strip.
+     *
+     * @param browserControlsVisibilityManager {@link BrowserControlsVisibilityManager} to observe
+     *     browser controls height and animation state.
+     * @param controlContainer The {@link ToolbarControlContainer} for the containing activity.
+     * @param toolbarLayout {@link ToolbarLayout} for the current toolbar.
+     */
+    TabStripTransitionCoordinator(
+            BrowserControlsVisibilityManager browserControlsVisibilityManager,
+            View controlContainer,
+            View toolbarLayout,
+            int tabStripHeightFromResource) {
+        mBrowserControlsVisibilityManager = browserControlsVisibilityManager;
+        mControlContainer = controlContainer;
+        mToolbarLayout = toolbarLayout;
+        mTabStripHeightFromResource = tabStripHeightFromResource;
+
+        mTabStripHeight = tabStripHeightFromResource;
+        mTabStripVisible = mTabStripHeight > 0;
+    }
+
+    /** Return the current tab strip height. */
+    public int getTabStripHeight() {
+        return mTabStripHeight;
+    }
+
+    /** Add observer for tab strip height change. */
+    public void addObserver(TabStripHeightObserver observer) {
+        mTabStripHeightObservers.addObserver(observer);
+    }
+
+    /** Remove observer for tab strip height change. */
+    public void removeObserver(TabStripHeightObserver observer) {
+        mTabStripHeightObservers.removeObserver(observer);
+    }
+
+    /** Remove observers and release reference to dependencies. */
+    public void destroy() {
+        if (mBrowserControlsObserver != null) {
+            mBrowserControlsVisibilityManager.removeObserver(mBrowserControlsObserver);
+            mBrowserControlsObserver = null;
+        }
+        mTabStripHeightObservers.clear();
+    }
+
+    @Override
+    public void onConfigurationChanged(@NonNull Configuration configuration) {
+        maybeUpdateTabStripVisibility();
+    }
+
+    @Override
+    public void onLowMemory() {}
+
+    @VisibleForTesting
+    void maybeUpdateTabStripVisibility() {
+        DisplayMetrics displayMetrics = mControlContainer.getResources().getDisplayMetrics();
+        int width = displayMetrics.widthPixels;
+        boolean showTabStrip =
+                width >= ViewUtils.dpToPx(displayMetrics, getScreenWidthThresholdDp());
+
+        if (showTabStrip == mTabStripVisible) return;
+        mTabStripVisible = showTabStrip;
+
+        // If control container is already stable, or the Android view is invisible, perform the
+        // layout directly; otherwise, wait for one layout pass so the toolbar is redrawn at the
+        // reduced width before capturing a new bitmap for the C++ animation.
+        if (!mControlContainer.isInLayout()
+                || mBrowserControlsVisibilityManager.getAndroidControlsVisibility()
+                        != View.VISIBLE) {
+            setTabStripVisibility(showTabStrip);
+            return;
+        }
+
+        // If an layout is already scheduled for a different visibility, cancel it.
+        if (mOnLayoutChangedListener != null) {
+            mControlContainer.removeOnLayoutChangeListener(mOnLayoutChangedListener);
+        }
+
+        // Wait for one layout pass so the toolbar is redrawn at the reduced width before capturing
+        // a new bitmap for the C++ animation.
+        mOnLayoutChangedListener =
+                (view, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
+                    mControlContainer.removeOnLayoutChangeListener(mOnLayoutChangedListener);
+                    mOnLayoutChangedListener = null;
+
+                    setTabStripVisibility(showTabStrip);
+                };
+        mControlContainer.addOnLayoutChangeListener(mOnLayoutChangedListener);
+    }
+
+    /**
+     * Set the new height for the tab strip. This on high level consists with 3 steps:
+     *
+     * <ul>
+     *   <li>1. Use {@link BrowserControlsSizer} to change the browser control height. This will
+     *       kick off the scene layer transition.
+     *   <li>2. Add / remove margins from the toolbar and toolbar hairline based on tab strip's new
+     *       height.
+     *   <li>3. Notify the tab strip scene layer for the new height. This will in turn notify
+     *       StripLayoutHelperManager to mark a yOffset that tabStrip will render off-screen. Note
+     *       that we cannot simply mark the tab strip scene layer hidden, since it's still required
+     *       to be visible during the transition.
+     * </ul>
+     *
+     * @param show Whether the tab strip should be shown.
+     */
+    private void setTabStripVisibility(boolean show) {
+        mTabStripHeight = show ? mTabStripHeightFromResource : 0;
+
+        // Notify tab strip height is changed, and get ready for the browser controls updates.
+        for (var observer : mTabStripHeightObservers) {
+            observer.onTabStripHeightChanged(mTabStripHeight);
+        }
+
+        if (mBrowserControlsObserver != null) return;
+        mBrowserControlsObserver =
+                new BrowserControlsStateProvider.Observer() {
+                    @Override
+                    public void onControlsOffsetChanged(
+                            int topOffset,
+                            int topControlsMinHeightOffset,
+                            int bottomOffset,
+                            int bottomControlsMinHeightOffset,
+                            boolean needsAnimate) {
+                        updateTabStripHeightImpl();
+                    }
+
+                    @Override
+                    public void onAndroidControlsVisibilityChanged(int visibility) {
+                        // Update the margin when browser control turns into invisible. This can
+                        // happen before onControlsOffsetChanged.
+                        updateTabStripHeightImpl();
+                    }
+
+                    @Override
+                    public void onTopControlsHeightChanged(
+                            int topControlsHeight, int topControlsMinHeight) {
+                        // If the browser control is performing an browser initiated animation,
+                        // we should update the view margins right away. This will make sure the
+                        // toolbar stays in the same place with changes in control container's Y
+                        // translation.
+                        //
+                        // For cc initiated transition, we'll defer the view updates until the first
+                        // #onControlsOffsetChanged is called. This avoid the toolbar margins gets
+                        // updated too fast before the cc layer respond, in which the Android views
+                        // in the browser control are still visible.
+                        if (mBrowserControlsVisibilityManager.offsetOverridden()) {
+                            updateTabStripHeightImpl();
+                        }
+                    }
+                };
+        mBrowserControlsVisibilityManager.addObserver(mBrowserControlsObserver);
+    }
+
+    // TODO(crbug.com/1498252): Find a better place to set these top margins.
+    private void updateTabStripHeightImpl() {
+        // Remove the mBrowserControlsObserver, to make sure this method is called only once.
+        if (mBrowserControlsObserver != null) {
+            mBrowserControlsVisibilityManager.removeObserver(mBrowserControlsObserver);
+            mBrowserControlsObserver = null;
+        }
+
+        // The top margin is the space left for the tab strip.
+        updateTopMargin(mToolbarLayout, mTabStripHeight);
+
+        // Change the toolbar hairline top margin.
+        int topControlHeight = mTabStripHeight + mToolbarLayout.getHeight();
+        View toolbarHairline = mControlContainer.findViewById(R.id.toolbar_hairline);
+        updateTopMargin(toolbarHairline, topControlHeight);
+
+        // optionally, update the find toolbar.
+        View findToolbar = mControlContainer.findViewById(R.id.find_toolbar);
+        if (findToolbar != null) {
+            updateTopMargin(findToolbar, mTabStripHeight);
+        } else {
+            View findToolbarStub = mControlContainer.findViewById(R.id.find_toolbar_stub);
+            updateTopMargin(findToolbarStub, mTabStripHeight);
+        }
+    }
+
+    private static void updateTopMargin(View view, int topMargin) {
+        ViewGroup.MarginLayoutParams hairlineParams =
+                (ViewGroup.MarginLayoutParams) view.getLayoutParams();
+        hairlineParams.topMargin = topMargin;
+        view.setLayoutParams(hairlineParams);
+    }
+
+    /** Get the min screen width required in DP for the tab strip to become visible. */
+    private static int getScreenWidthThresholdDp() {
+        return sMinScreenWidthForTesting != null
+                ? sMinScreenWidthForTesting
+                : DeviceFormFactor.MINIMUM_TABLET_WIDTH_DP;
+    }
+
+    /**
+     * Set the test override that the min screen size for the tab strip to become visible.
+     *
+     * @param screenWidthForTesting Screen size in required for tab strip to become visible.
+     */
+    public static void setMinScreenWidthForTesting(int screenWidthForTesting) {
+        sMinScreenWidthForTesting = screenWidthForTesting;
+        ResettersForTesting.register(() -> sMinScreenWidthForTesting = null);
+    }
+}
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabStripTransitionCoordinatorUnitTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabStripTransitionCoordinatorUnitTest.java
new file mode 100644
index 0000000..9df2958
--- /dev/null
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TabStripTransitionCoordinatorUnitTest.java
@@ -0,0 +1,299 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.toolbar.top;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.widget.FrameLayout;
+
+import androidx.annotation.Nullable;
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
+import org.chromium.chrome.browser.browser_controls.BrowserControlsVisibilityManager;
+import org.chromium.ui.base.TestActivity;
+
+/** Unit test for {@link TabStripTransitionCoordinator}. */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(qualifiers = "w600dp")
+public class TabStripTransitionCoordinatorUnitTest {
+    private static final int TEST_TAB_STRIP_HEIGHT = 40;
+    private static final int TEST_TOOLBAR_HEIGHT = 56;
+
+    @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
+    @Rule
+    public ActivityScenarioRule<TestActivity> mActivityScenario =
+            new ActivityScenarioRule<>(TestActivity.class);
+
+    @Mock private BrowserControlsVisibilityManager mBrowserControlsVisibilityManager;
+    @Captor private ArgumentCaptor<BrowserControlsStateProvider.Observer> mBrowserControlsObserver;
+
+    private TabStripTransitionCoordinator mCoordinator;
+    private TestActivity mActivity;
+    private TestControlContainer mSpyControlContainer;
+
+    @Before
+    public void setup() {
+        mActivityScenario.getScenario().onActivity(activity -> mActivity = activity);
+        mSpyControlContainer = TestControlContainer.createSpy(mActivity);
+        mActivity.setContentView(mSpyControlContainer);
+
+        mCoordinator =
+                new TabStripTransitionCoordinator(
+                        mBrowserControlsVisibilityManager,
+                        mSpyControlContainer,
+                        mSpyControlContainer.toolbarLayout,
+                        TEST_TAB_STRIP_HEIGHT);
+        doNothing()
+                .when(mBrowserControlsVisibilityManager)
+                .addObserver(mBrowserControlsObserver.capture());
+        doReturn(View.VISIBLE)
+                .when(mBrowserControlsVisibilityManager)
+                .getAndroidControlsVisibility();
+    }
+
+    @Test
+    public void updateTabStripHeight_WideWindow() {
+        mCoordinator.maybeUpdateTabStripVisibility();
+        Assert.assertEquals(
+                "Tab strip height is wrong.",
+                TEST_TAB_STRIP_HEIGHT,
+                mCoordinator.getTabStripHeight());
+
+        setDeviceWidthDp(480);
+        mCoordinator.maybeUpdateTabStripVisibility();
+        Assert.assertEquals("Tab strip height is wrong.", 0, mCoordinator.getTabStripHeight());
+    }
+
+    @Test
+    @Config(qualifiers = "w480dp")
+    public void updateTabStripHeight_NarrowWindow() {
+        mCoordinator.maybeUpdateTabStripVisibility();
+        Assert.assertEquals("Tab strip height is wrong.", 0, mCoordinator.getTabStripHeight());
+
+        setDeviceWidthDp(600);
+        mCoordinator.maybeUpdateTabStripVisibility();
+        Assert.assertEquals(
+                "Tab strip height is wrong.",
+                TEST_TAB_STRIP_HEIGHT,
+                mCoordinator.getTabStripHeight());
+    }
+
+    @Test
+    public void updateTabStripHeight_DuringLayout() {
+        mCoordinator.maybeUpdateTabStripVisibility();
+        Assert.assertEquals(
+                "Tab strip height is wrong.",
+                TEST_TAB_STRIP_HEIGHT,
+                mCoordinator.getTabStripHeight());
+
+        doReturn(true).when(mSpyControlContainer).isInLayout();
+        setDeviceWidthDp(480);
+        mCoordinator.maybeUpdateTabStripVisibility();
+        Assert.assertEquals(
+                "Tab strip height is not updated yet during layout.",
+                TEST_TAB_STRIP_HEIGHT,
+                mCoordinator.getTabStripHeight());
+        simulateLayoutChange();
+        Assert.assertEquals(
+                "Tab strip height should be updated after layout.",
+                0,
+                mCoordinator.getTabStripHeight());
+    }
+
+    @Test
+    public void updateTabStripHeight_BrowserControlsHidden() {
+        doReturn(true).when(mSpyControlContainer).isInLayout();
+        doReturn(View.GONE).when(mBrowserControlsVisibilityManager).getAndroidControlsVisibility();
+        mCoordinator.maybeUpdateTabStripVisibility();
+        Assert.assertEquals(
+                "Tab strip update should be instant.",
+                TEST_TAB_STRIP_HEIGHT,
+                mCoordinator.getTabStripHeight());
+
+        setDeviceWidthDp(480);
+        mCoordinator.maybeUpdateTabStripVisibility();
+        Assert.assertEquals(
+                "Tab strip update should be instant.", 0, mCoordinator.getTabStripHeight());
+    }
+
+    @Test
+    public void hideTabStrip() {
+        mCoordinator.maybeUpdateTabStripVisibility();
+
+        setDeviceWidthDp(480);
+        mCoordinator.maybeUpdateTabStripVisibility();
+
+        // Simulate top controls size change from browser. Input values doesn't matter in this call.
+        mBrowserControlsObserver.getValue().onControlsOffsetChanged(0, 0, 0, 0, false);
+        assertTabStripHeightForMargins(0);
+    }
+
+    @Test
+    public void hideTabStripWithOffsetOverride() {
+        mCoordinator.maybeUpdateTabStripVisibility();
+
+        setDeviceWidthDp(480);
+        mCoordinator.maybeUpdateTabStripVisibility();
+
+        // Simulate top controls size change from browser.
+        doReturn(true).when(mBrowserControlsVisibilityManager).offsetOverridden();
+        mBrowserControlsObserver.getValue().onTopControlsHeightChanged(TEST_TOOLBAR_HEIGHT, 0);
+        assertTabStripHeightForMargins(0);
+    }
+
+    @Test
+    @Config(qualifiers = "w480dp")
+    public void showTabStrip() {
+        mCoordinator.maybeUpdateTabStripVisibility();
+
+        setDeviceWidthDp(600);
+        mCoordinator.maybeUpdateTabStripVisibility();
+
+        // Simulate top controls size change from browser. Input values doesn't matter in this call.
+        mBrowserControlsObserver.getValue().onControlsOffsetChanged(0, 0, 0, 0, false);
+        assertTabStripHeightForMargins(TEST_TAB_STRIP_HEIGHT);
+    }
+
+    @Test
+    @Config(qualifiers = "w480dp")
+    public void showTabStripWithOffsetOverride() {
+        mCoordinator.maybeUpdateTabStripVisibility();
+
+        setDeviceWidthDp(600);
+        mCoordinator.maybeUpdateTabStripVisibility();
+
+        // Simulate top controls size change from browser.
+        doReturn(true).when(mBrowserControlsVisibilityManager).offsetOverridden();
+        mBrowserControlsObserver.getValue().onTopControlsHeightChanged(TEST_TOOLBAR_HEIGHT, 0);
+        assertTabStripHeightForMargins(TEST_TAB_STRIP_HEIGHT);
+    }
+
+    private void setDeviceWidthDp(int widthDp) {
+        Resources res = mActivity.getResources();
+        DisplayMetrics displayMetrics = res.getDisplayMetrics();
+        displayMetrics.widthPixels = (int) displayMetrics.density * widthDp;
+
+        Configuration configuration = res.getConfiguration();
+        configuration.screenWidthDp = widthDp;
+        mActivity.createConfigurationContext(configuration);
+    }
+
+    private void assertTabStripHeightForMargins(int tabStripHeight) {
+        Assert.assertEquals(
+                "Top margin is wrong for toolbarLayout.",
+                tabStripHeight,
+                mSpyControlContainer.toolbarLayout.getTopMargin());
+        Assert.assertEquals(
+                "Top margin is wrong for findToolbar.",
+                tabStripHeight,
+                mSpyControlContainer.findToolbar.getTopMargin());
+        Assert.assertEquals(
+                "Top margin is wrong for toolbarHairline.",
+                tabStripHeight + TEST_TOOLBAR_HEIGHT,
+                mSpyControlContainer.toolbarHairline.getTopMargin());
+    }
+
+    private void simulateLayoutChange() {
+        Assert.assertNotNull(mSpyControlContainer.onLayoutChangeListener);
+        mSpyControlContainer.onLayoutChangeListener.onLayoutChange(
+                mSpyControlContainer, 0, 0, 0, 0, 0, 0, 0, 0);
+    }
+
+    // Due to the complexity to use the real views for top toolbar in robolectric tests, use view
+    // mocks for the sake of unit tests.
+    static class TestControlContainer extends FrameLayout {
+        public TestView toolbarLayout;
+        public TestView toolbarHairline;
+        public TestView findToolbar;
+
+        @Nullable public View.OnLayoutChangeListener onLayoutChangeListener;
+
+        static TestControlContainer createSpy(Context context) {
+            TestControlContainer controlContainer =
+                    Mockito.spy(new TestControlContainer(context, null));
+
+            doReturn(controlContainer.toolbarLayout)
+                    .when(controlContainer)
+                    .findViewById(R.id.toolbar);
+            doReturn(controlContainer.toolbarHairline)
+                    .when(controlContainer)
+                    .findViewById(R.id.toolbar_hairline);
+            doReturn(controlContainer.findToolbar)
+                    .when(controlContainer)
+                    .findViewById(R.id.find_toolbar);
+
+            doAnswer(
+                            args -> {
+                                controlContainer.onLayoutChangeListener = args.getArgument(0);
+                                return null;
+                            })
+                    .when(controlContainer)
+                    .addOnLayoutChangeListener(any());
+
+            return controlContainer;
+        }
+
+        public TestControlContainer(Context context, @Nullable AttributeSet attrs) {
+            super(context, attrs);
+
+            toolbarLayout = Mockito.spy(new TestView(context, attrs));
+            findToolbar = Mockito.spy(new TestView(context, attrs));
+            when(toolbarLayout.getHeight()).thenReturn(TEST_TOOLBAR_HEIGHT);
+            when(findToolbar.getHeight()).thenReturn(TEST_TOOLBAR_HEIGHT);
+            toolbarHairline = new TestView(context, attrs);
+
+            MarginLayoutParams sourceParams =
+                    new MarginLayoutParams(
+                            ViewGroup.LayoutParams.MATCH_PARENT,
+                            ViewGroup.LayoutParams.MATCH_PARENT);
+            sourceParams.topMargin = TEST_TAB_STRIP_HEIGHT + TEST_TOOLBAR_HEIGHT;
+            addView(toolbarHairline, new MarginLayoutParams(sourceParams));
+
+            sourceParams.topMargin = TEST_TAB_STRIP_HEIGHT;
+            sourceParams.height = TEST_TOOLBAR_HEIGHT;
+            addView(toolbarLayout, new MarginLayoutParams(sourceParams));
+            addView(findToolbar, new MarginLayoutParams(sourceParams));
+        }
+    }
+
+    static class TestView extends View {
+        public TestView(Context context, @Nullable AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        public int getTopMargin() {
+            return ((MarginLayoutParams) getLayoutParams()).topMargin;
+        }
+    }
+}
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
index 1900ef7..f8a7986 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
@@ -66,8 +66,6 @@
  * Layout for the browser controls (omnibox, menu, tab strip, etc..).
  */
 public class ToolbarControlContainer extends OptimizedFrameLayout implements ControlContainer {
-    private final float mTabStripHeight;
-
     private boolean mIncognito;
 
     private Toolbar mToolbar;
@@ -86,7 +84,6 @@
      */
     public ToolbarControlContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mTabStripHeight = context.getResources().getDimension(R.dimen.tab_strip_height);
     }
 
     @Override
@@ -329,7 +326,6 @@
 
         @Nullable
         private Toolbar mToolbar;
-        private int mTabStripHeightPx;
         @Nullable
         private ConstraintsChecker mConstraintsObserver;
         @Nullable
@@ -376,7 +372,6 @@
                 FullscreenManager fullscreenManager) {
             assert mToolbar == null;
             mToolbar = toolbar;
-            mTabStripHeightPx = mToolbar.getTabStripHeight();
 
             // These dependencies only matter when ChromeFeatureList.SUPPRESS_TOOLBAR_CAPTURES is
             // enabled. Unfortunately this method is often called before native is initialized,
@@ -507,7 +502,9 @@
             mLocationBarRect.offset(mTempPosition[0], mTempPosition[1]);
 
             int shadowHeight =
-                    mToolbarContainer.getHeight() - mToolbar.getHeight() - mTabStripHeightPx;
+                    mToolbarContainer.getHeight()
+                            - mToolbar.getHeight()
+                            - mToolbar.getTabStripHeight();
             return ResourceFactory.createToolbarContainerResource(
                     mToolbarRect, mLocationBarRect, shadowHeight);
         }
@@ -606,7 +603,7 @@
     }
 
     private boolean isOnTabStrip(MotionEvent e) {
-        return e.getY() <= mTabStripHeight;
+        return e.getY() <= mToolbar.getTabStripHeight();
     }
 
     /**
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
index e1b6d49..efe03be 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
@@ -601,9 +601,10 @@
     }
 
     /**
-     * @return The height of the tab strip. Return 0 for toolbars that do not have a tabstrip.
+     * Return the height of the tab strip from the layout resource. Return 0 for toolbars that do
+     * not have a tab strip.
      */
-    protected int getTabStripHeight() {
+    protected int getTabStripHeightFromResource() {
         return getResources().getDimensionPixelSize(R.dimen.tab_strip_height);
     }
 
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
index 2ab7e8f..32477fc 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -18,9 +18,10 @@
 import org.chromium.base.supplier.OneShotCallback;
 import org.chromium.base.supplier.OneshotSupplier;
 import org.chromium.base.supplier.Supplier;
-import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
+import org.chromium.chrome.browser.browser_controls.BrowserControlsVisibilityManager;
 import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate;
 import org.chromium.chrome.browser.device.DeviceClassManager;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.fullscreen.FullscreenManager;
 import org.chromium.chrome.browser.hub.HubFieldTrial;
 import org.chromium.chrome.browser.layouts.LayoutManager;
@@ -42,6 +43,7 @@
 import org.chromium.chrome.browser.toolbar.menu_button.MenuButton;
 import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator;
 import org.chromium.chrome.browser.toolbar.top.NavigationPopup.HistoryDelegate;
+import org.chromium.chrome.browser.toolbar.top.TabStripTransitionCoordinator.TabStripHeightObserver;
 import org.chromium.chrome.browser.toolbar.top.ToolbarTablet.OfflineDownloader;
 import org.chromium.chrome.browser.ui.appmenu.AppMenuButtonHelper;
 import org.chromium.chrome.browser.ui.appmenu.AppMenuDelegate;
@@ -111,6 +113,9 @@
     private ObservableSupplier<AppMenuButtonHelper> mAppMenuButtonHelperSupplier;
     private ObservableSupplier<TabModelSelector> mTabModelSelectorSupplier;
 
+    /** Null until {@link #initializeWithNative} is called. * */
+    private @Nullable TabStripTransitionCoordinator mTabStripTransitionCoordinator;
+
     private ToolbarControlContainer mControlContainer;
     private Supplier<ResourceManager> mResourceManagerSupplier;
     private TopToolbarOverlayCoordinator mOverlayCoordinator;
@@ -255,8 +260,8 @@
 
     /**
      * Initialize the coordinator with the components that have native initialization dependencies.
-     * <p>
-     * Calling this must occur after the native library have completely loaded.
+     *
+     * <p>Calling this must occur after the native library have completely loaded.
      *
      * @param layoutUpdater A {@link Runnable} used to request layout update upon scene change.
      * @param tabSwitcherClickHandler The click handler for the tab switcher button.
@@ -266,16 +271,20 @@
      * @param appMenuDelegate Allows interacting with the app menu.
      * @param layoutManager A {@link LayoutManager} used to watch for scene changes.
      * @param tabSupplier Supplier of the activity tab.
-     * @param browserControlsStateProvider {@link BrowserControlsStateProvider} to access browser
-     *                                     controls offsets.
+     * @param browserControlsVisibilityManager {@link BrowserControlsVisibilityManager} to access
+     *     browser controls offsets and visibility.
      * @param topUiThemeColorProvider {@link ThemeColorProvider} for top UI.
      */
-    public void initializeWithNative(Runnable layoutUpdater,
-            OnClickListener tabSwitcherClickHandler, OnClickListener newTabClickHandler,
-            OnClickListener bookmarkClickHandler, OnClickListener customTabsBackClickHandler,
-            AppMenuDelegate appMenuDelegate, LayoutManager layoutManager,
+    public void initializeWithNative(
+            Runnable layoutUpdater,
+            OnClickListener tabSwitcherClickHandler,
+            OnClickListener newTabClickHandler,
+            OnClickListener bookmarkClickHandler,
+            OnClickListener customTabsBackClickHandler,
+            AppMenuDelegate appMenuDelegate,
+            LayoutManager layoutManager,
             ObservableSupplier<Tab> tabSupplier,
-            BrowserControlsStateProvider browserControlsStateProvider,
+            BrowserControlsVisibilityManager browserControlsVisibilityManager,
             TopUiThemeColorProvider topUiThemeColorProvider) {
         assert mTabModelSelectorSupplier.get() != null;
         Callback<Integer> tabSwitcherLongClickCallback =
@@ -308,14 +317,37 @@
         // If fullscreen is disabled, don't bother creating this overlay; only the android view will
         // ever be shown.
         if (DeviceClassManager.enableFullscreen()) {
-            mOverlayCoordinator = new TopToolbarOverlayCoordinator(mToolbarLayout.getContext(),
-                    layoutManager, mControlContainer::getProgressBarDrawingInfo, tabSupplier,
-                    browserControlsStateProvider, mResourceManagerSupplier, topUiThemeColorProvider,
-                    LayoutType.BROWSING | LayoutType.SIMPLE_ANIMATION | LayoutType.TAB_SWITCHER,
-                    false);
+            mOverlayCoordinator =
+                    new TopToolbarOverlayCoordinator(
+                            mToolbarLayout.getContext(),
+                            layoutManager,
+                            mControlContainer::getProgressBarDrawingInfo,
+                            tabSupplier,
+                            browserControlsVisibilityManager,
+                            mResourceManagerSupplier,
+                            topUiThemeColorProvider,
+                            LayoutType.BROWSING
+                                    | LayoutType.SIMPLE_ANIMATION
+                                    | LayoutType.TAB_SWITCHER,
+                            false);
             layoutManager.addSceneOverlay(mOverlayCoordinator);
             mToolbarLayout.setOverlayCoordinator(mOverlayCoordinator);
         }
+
+        if (ChromeFeatureList.isEnabled(ChromeFeatureList.DYNAMIC_TOP_CHROME)) {
+            mTabStripTransitionCoordinator =
+                    new TabStripTransitionCoordinator(
+                            browserControlsVisibilityManager,
+                            mControlContainer,
+                            mToolbarLayout,
+                            mToolbarLayout.getTabStripHeightFromResource());
+            mToolbarLayout.getContext().registerComponentCallbacks(mTabStripTransitionCoordinator);
+            mTabStripTransitionCoordinator.addObserver(
+                    (height) ->
+                            // Invalid the snapshot to make sure the tab strip is rendering
+                            // correctly.
+                            mControlContainer.invalidateBitmap());
+        }
     }
 
     /**
@@ -353,9 +385,13 @@
         mToolbarLayout.removeOnAttachStateChangeListener(listener);
     }
 
-    /**
-     * Cleans up any code as necessary.
-     */
+    /** Add an observer that listens to tab strip height update. */
+    public void addTabStripHeightObserver(TabStripHeightObserver observer) {
+        if (mTabStripTransitionCoordinator == null) return;
+        mTabStripTransitionCoordinator.addObserver(observer);
+    }
+
+    /** Cleans up any code as necessary. */
     public void destroy() {
         if (mOverlayCoordinator != null) {
             mOverlayCoordinator.destroy();
@@ -382,6 +418,10 @@
         if (mControlContainer != null) {
             mControlContainer = null;
         }
+        if (mTabStripTransitionCoordinator != null) {
+            mTabStripTransitionCoordinator.destroy();
+            mTabStripTransitionCoordinator = null;
+        }
     }
 
     @Override
@@ -569,7 +609,9 @@
 
     @Override
     public int getTabStripHeight() {
-        return mToolbarLayout.getTabStripHeight();
+        return mTabStripTransitionCoordinator != null
+                ? mTabStripTransitionCoordinator.getTabStripHeight()
+                : mToolbarLayout.getTabStripHeightFromResource();
     }
 
     /**
diff --git a/chrome/browser/ui/ash/api/tasks/chrome_tasks_delegate.cc b/chrome/browser/ui/ash/api/tasks/chrome_tasks_delegate.cc
index 1cae473..b8769c32 100644
--- a/chrome/browser/ui/ash/api/tasks/chrome_tasks_delegate.cc
+++ b/chrome/browser/ui/ash/api/tasks/chrome_tasks_delegate.cc
@@ -9,6 +9,7 @@
 
 #include "ash/api/tasks/tasks_client.h"
 #include "base/functional/bind.h"
+#include "base/functional/callback_helpers.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
@@ -156,6 +157,23 @@
   client->OnGlanceablesBubbleClosed();
 }
 
+void ChromeTasksDelegate::AddTask(const std::string& task_list_id,
+                                  const std::string& title) {
+  CHECK(active_account_id_.is_valid());
+  TasksClientImpl* client = GetActiveAccountClient();
+  CHECK(client);
+  client->AddTask(task_list_id, title);
+}
+
+void ChromeTasksDelegate::UpdateTaskTitle(const std::string& task_list_id,
+                                          const std::string& task_id,
+                                          const std::string& title) {
+  CHECK(active_account_id_.is_valid());
+  TasksClientImpl* client = GetActiveAccountClient();
+  CHECK(client);
+  client->UpdateTask(task_list_id, task_id, title, base::DoNothing());
+}
+
 TasksClientImpl* ChromeTasksDelegate::GetActiveAccountClient() const {
   const auto iter = clients_.find(active_account_id_);
   return iter != clients_.end() ? iter->second.get() : nullptr;
diff --git a/chrome/browser/ui/ash/api/tasks/chrome_tasks_delegate.h b/chrome/browser/ui/ash/api/tasks/chrome_tasks_delegate.h
index 9146c8d..86c3504a 100644
--- a/chrome/browser/ui/ash/api/tasks/chrome_tasks_delegate.h
+++ b/chrome/browser/ui/ash/api/tasks/chrome_tasks_delegate.h
@@ -31,6 +31,11 @@
                        const std::string& task_id,
                        bool completed) override;
   void SendCompletedTasks() override;
+  void AddTask(const std::string& task_list_id,
+               const std::string& title) override;
+  void UpdateTaskTitle(const std::string& task_list_id,
+                       const std::string& task_id,
+                       const std::string& title) override;
 
  private:
   // Returns the `TasksClientImpl` associated with the `active_account_id_`.
diff --git a/chrome/browser/ui/ash/clipboard_history_browsertest.cc b/chrome/browser/ui/ash/clipboard_history_browsertest.cc
index 454c34d..1560fff 100644
--- a/chrome/browser/ui/ash/clipboard_history_browsertest.cc
+++ b/chrome/browser/ui/ash/clipboard_history_browsertest.cc
@@ -1420,15 +1420,17 @@
            (*data_src->GetURL() == allowed_url_);
   }
 
-  void PasteIfAllowed(const ui::DataTransferEndpoint* const data_src,
-                      const ui::DataTransferEndpoint* const data_dst,
-                      const absl::optional<size_t> size,
-                      content::RenderFrameHost* rfh,
-                      base::OnceCallback<void(bool)> callback) override {}
+  void PasteIfAllowed(
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      const absl::optional<size_t> size,
+      content::RenderFrameHost* rfh,
+      base::OnceCallback<void(bool)> callback) override {}
 
-  void DropIfAllowed(const ui::OSExchangeData* drag_data,
-                     const ui::DataTransferEndpoint* data_dst,
-                     base::OnceClosure drop_cb) override {}
+  void DropIfAllowed(
+      const ui::OSExchangeData* drag_data,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      base::OnceClosure drop_cb) override {}
 
  private:
   const GURL allowed_url_;
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
index 8ec144e..cfd51d1 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_unittest.cc
@@ -6379,7 +6379,7 @@
   const ash::ShelfItem* item = shelf_controller_->GetItem(id);
   SkBitmap result_bitmap = *item->image.bitmap();
   SkBitmap expected_bitmap =
-      ApplyEffectsToBitmap(base_bitmap, apps::IconEffects::kCrOsStandardMask);
+      ApplyEffectsToBitmap(base_bitmap, apps::IconEffects::kCrOsStandardIcon);
   EXPECT_TRUE(gfx::BitmapsAreEqual(result_bitmap, expected_bitmap));
 }
 
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index 3ec5c3397..7e1a70aa 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -1973,8 +1973,7 @@
     ua_override.ua_metadata_override = embedder_support::GetUserAgentMetadata(
         g_browser_process->local_state());
     ua_override.ua_metadata_override->mobile = true;
-    ua_override.ua_metadata_override->form_factor =
-        embedder_support::kMobileFormFactor;
+    ua_override.ua_metadata_override->form_factor = {blink::kTabletFormFactor};
     ua_override.ua_metadata_override->platform =
         kChPlatformOverrideForTabletSite;
     ua_override.ua_metadata_override->platform_version = std::string();
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h
index 4a65ef7..17e53a68 100644
--- a/chrome/browser/ui/color/chrome_color_id.h
+++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -432,6 +432,7 @@
   E_CPONLY(kColorSidePanelDivider) \
   E_CPONLY(kColorSidePanelEditFooterBorder) \
   E_CPONLY(kColorSidePanelComboboxEntryIcon) \
+  E_CPONLY(kColorSidePanelComboboxEntryTitle) \
   E_CPONLY(kColorSidePanelEntryIcon) \
   E_CPONLY(kColorSidePanelEntryDropdownIcon) \
   E_CPONLY(kColorSidePanelEntryTitle) \
@@ -575,12 +576,14 @@
   E_CPONLY(kColorTabThrobber) \
   E_CPONLY(kColorTabThrobberPreconnect) \
   /* Tab Search colors */ \
+  E_CPONLY(kColorTabSearchCardBackground) \
   E_CPONLY(kColorTabSearchBackground) \
   E_CPONLY(kColorTabSearchDivider) \
   E_CPONLY(kColorTabSearchMediaIcon) \
   E_CPONLY(kColorTabSearchMediaRecordingIcon) \
   E_CPONLY(kColorTabSearchPrimaryForeground) \
   E_CPONLY(kColorTabSearchSecondaryForeground) \
+  E_CPONLY(kColorTabSearchSelected) \
   E_CPONLY(kColorTabSearchScrollbarThumb) \
   /* Thumbnail tab colors. */ \
   E_CPONLY(kColorThumbnailTabBackground) \
diff --git a/chrome/browser/ui/color/material_chrome_color_mixer.cc b/chrome/browser/ui/color/material_chrome_color_mixer.cc
index 34943b47..165776a 100644
--- a/chrome/browser/ui/color/material_chrome_color_mixer.cc
+++ b/chrome/browser/ui/color/material_chrome_color_mixer.cc
@@ -84,12 +84,14 @@
   mixer[kColorProfileMenuSyncPausedIcon] = {ui::kColorSysPrimary};
 
   // Tab Search colors.
+  mixer[kColorTabSearchCardBackground] = {ui::kColorSysSurface5};
   mixer[kColorTabSearchBackground] = {ui::kColorSysSurface};
   mixer[kColorTabSearchDivider] = {ui::kColorSysDivider};
   mixer[kColorTabSearchMediaIcon] = {ui::kColorSysOnSurfaceSubtle};
   mixer[kColorTabSearchMediaRecordingIcon] = {ui::kColorSysError};
   mixer[kColorTabSearchPrimaryForeground] = {ui::kColorSysOnSurface};
   mixer[kColorTabSearchSecondaryForeground] = {ui::kColorSysOnSurfaceSubtle};
+  mixer[kColorTabSearchSelected] = {ui::kColorSysPrimary};
   mixer[kColorTabSearchScrollbarThumb] = {ui::kColorSysPrimary};
 
   // Side Panel colors.
diff --git a/chrome/browser/ui/color/material_side_panel_color_mixer.cc b/chrome/browser/ui/color/material_side_panel_color_mixer.cc
index 2d0fdce3..64cd964d 100644
--- a/chrome/browser/ui/color/material_side_panel_color_mixer.cc
+++ b/chrome/browser/ui/color/material_side_panel_color_mixer.cc
@@ -16,6 +16,7 @@
   ui::ColorMixer& mixer = provider->AddMixer();
   mixer[kColorSidePanelContentBackground] = {ui::kColorSysBaseContainer};
   mixer[kColorSidePanelComboboxEntryIcon] = {ui::kColorSysPrimary};
+  mixer[kColorSidePanelComboboxEntryTitle] = {ui::kColorSysOnSurface};
   mixer[kColorSidePanelEntryDropdownIcon] = {ui::kColorSysOnSurfaceSubtle};
   mixer[kColorSidePanelContentAreaSeparator] = {ui::kColorSysBaseContainer};
 
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
index cbcedd7..8fbad93 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
+++ b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
@@ -848,9 +848,7 @@
   EXPECT_EQ(2u, g_browser_process->profile_manager()->GetNumberOfProfiles());
   // Get the profile that was used to load the `force_signin_webui_url`.
   Profile* force_signin_profile = Profile::FromBrowserContext(
-      content::Source<content::NavigationController>(url_observer.source())
-          .ptr()
-          ->GetBrowserContext());
+      url_observer.web_contents()->GetBrowserContext());
   EXPECT_TRUE(force_signin_profile);
   // Make sure that the force_signin profile is different from the main one.
   EXPECT_FALSE(force_signin_profile->IsSameOrParent(browser()->profile()));
diff --git a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
index cd3f6710..21b6710 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
+++ b/chrome/browser/ui/views/side_panel/side_panel_coordinator.cc
@@ -925,7 +925,7 @@
   combobox->SetBorderColorId(ui::kColorSidePanelComboboxBorder);
   combobox->SetBackgroundColorId(ui::kColorSidePanelComboboxBackground);
   if (features::IsChromeRefresh2023()) {
-    combobox->SetForegroundColorId(kColorSidePanelEntryTitle);
+    combobox->SetForegroundColorId(kColorSidePanelComboboxEntryTitle);
     combobox->SetForegroundIconColorId(kColorSidePanelComboboxEntryIcon);
     combobox->SetForegroundTextStyle(views::style::STYLE_HEADLINE_5);
   }
diff --git a/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.cc b/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.cc
index c0876fe5..348b9d6b 100644
--- a/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.cc
+++ b/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.cc
@@ -12,6 +12,7 @@
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/metrics/user_metrics.h"
+#include "base/task/single_thread_task_runner.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_element_identifiers.h"
 #include "chrome/browser/ui/layout_constants.h"
@@ -107,6 +108,8 @@
 void PinnedToolbarActionsContainer::PinnedActionToolbarButton::ButtonPressed() {
   base::RecordAction(
       base::UserMetricsAction("Actions.PinnedToolbarButtonActivation"));
+
+  base::AutoReset<bool> invoking_action(&invoking_action_, true);
   action_item_->InvokeAction(
       actions::ActionInvocationContext::Builder()
           .SetProperty(
@@ -116,6 +119,11 @@
           .Build());
 }
 
+bool PinnedToolbarActionsContainer::PinnedActionToolbarButton::
+    IsInvokingAction() {
+  return invoking_action_;
+}
+
 bool PinnedToolbarActionsContainer::PinnedActionToolbarButton::IsActive() {
   return anchor_higlight_.has_value();
 }
@@ -478,8 +486,7 @@
   if (iter == popped_out_buttons_.end()) {
     return;
   }
-  // This returns a unique_ptr which is immediately destroyed.
-  RemoveChildViewT(*iter);
+  RemoveButton(*iter);
   popped_out_buttons_.erase(iter);
   ReorderViews();
 }
@@ -515,7 +522,7 @@
     return;
   }
   if (!(*iter)->IsActive()) {
-    RemoveChildViewT(*iter);
+    RemoveButton(*iter);
   } else {
     popped_out_buttons_.push_back(*iter);
   }
@@ -539,6 +546,18 @@
   return iter == popped_out_buttons_.end() ? nullptr : *iter;
 }
 
+void PinnedToolbarActionsContainer::RemoveButton(
+    PinnedActionToolbarButton* button) {
+  if (button->IsInvokingAction()) {
+    // Defer deletion of the view to allow the pressed event handler
+    // that triggers its removal to run to completion.
+    base::SingleThreadTaskRunner::GetCurrentDefault()->DeleteSoon(
+        FROM_HERE, RemoveChildViewT(button));
+  } else {
+    RemoveChildViewT(button);
+  }
+}
+
 void PinnedToolbarActionsContainer::ReorderViews() {
   size_t index = 0;
   // Pinned buttons appear first. Use the model's ordering of pinned ActionIds
diff --git a/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.h b/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.h
index ed385415..0a5d7ac7 100644
--- a/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.h
+++ b/chrome/browser/ui/views/toolbar/pinned_toolbar_actions_container.h
@@ -24,9 +24,6 @@
 class BrowserView;
 
 // Container for pinned actions shown in the toolbar.
-// TODO(b/303064829): Handle pop-out behavior including separator in this class
-// as well.
-// TODO(b/299463183): Handle highlighting of pinned/popped-out buttons.
 class PinnedToolbarActionsContainer
     : public ToolbarIconContainerView,
       public PinnedToolbarActionsModel::Observer,
@@ -51,6 +48,7 @@
     void SetIconVisibility(bool visible);
 
     bool IsActive();
+    bool IsInvokingAction();
 
     // Button:
     gfx::Size CalculatePreferredSize() const override;
@@ -63,6 +61,7 @@
     base::CallbackListSubscription action_changed_subscription_;
     // Used to ensure the button remains highlighted while active.
     absl::optional<Button::ScopedAnchorHighlight> anchor_higlight_;
+    bool invoking_action_ = false;
   };
 
   explicit PinnedToolbarActionsContainer(BrowserView* browser_view);
@@ -122,6 +121,8 @@
   // Sorts child views to display them in the correct order.
   void ReorderViews();
 
+  void RemoveButton(PinnedActionToolbarButton* button);
+
   void SetActionButtonIconVisibility(actions::ActionId id, bool visible);
 
   // Moves the dragged action `action_id`.
diff --git a/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.cc b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.cc
index 8f25729..f9b867e 100644
--- a/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.cc
+++ b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.cc
@@ -25,6 +25,15 @@
 #include "ui/views/view.h"
 #include "ui/views/window/dialog_delegate.h"
 
+#if BUILDFLAG(IS_CHROMEOS)
+#include "chrome/browser/apps/app_service/app_service_proxy.h"
+#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
+#include "components/services/app_service/public/cpp/app_launch_util.h"
+#include "ui/events/event_constants.h"
+#else
+#include "base/command_line.h"
+#endif  // BUILDFLAG(IS_CHROMEOS)
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/webui/settings/public/constants/routes.mojom.h"
 #include "chrome/browser/ui/settings_window_manager_chromeos.h"
@@ -134,9 +143,23 @@
       return false;
     }
 
-    case IsolatedWebAppInstallerModel::Step::kInstallSuccess:
-      // TODO(crbug.com/1479140): Launch the app.
-      break;
+    case IsolatedWebAppInstallerModel::Step::kInstallSuccess: {
+      webapps::AppId app_id = model_->bundle_metadata().app_id();
+#if BUILDFLAG(IS_CHROMEOS)
+      apps::AppServiceProxyFactory::GetForProfile(profile_)->Launch(
+          app_id, ui::EF_NONE, apps::LaunchSource::kFromInstaller,
+          /*window_info=*/nullptr);
+#else
+      web_app_provider_->scheduler().LaunchApp(
+          app_id, *base::CommandLine::ForCurrentProcess(),
+          /*current_directory=*/base::FilePath(),
+          /*url_handler_launch_url=*/absl::nullopt,
+          /*protocol_handler_launch_url=*/absl::nullopt,
+          /*file_launch_url=*/absl::nullopt, /*launch_files=*/{},
+          base::DoNothing());
+#endif  // BUILDFLAG(IS_CHROMEOS)
+      return true;
+    }
 
     default:
       NOTREACHED();
diff --git a/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.h b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.h
index 582ee0f..d831b1a1 100644
--- a/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.h
+++ b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller.h
@@ -59,6 +59,8 @@
                            InstallationErrorShowsErrorDialog);
   FRIEND_TEST_ALL_PREFIXES(IsolatedWebAppInstallerViewControllerTest,
                            InstallationErrorRetryRestartsFlow);
+  FRIEND_TEST_ALL_PREFIXES(IsolatedWebAppInstallerViewControllerTest,
+                           CanLaunchAppAfterInstall);
 
   // Handles returning a default value if the controller has been deleted.
   static bool OnAcceptWrapper(
diff --git a/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller_unittest.cc b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller_unittest.cc
index 29ec237..f319b21 100644
--- a/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller_unittest.cc
+++ b/chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view_controller_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/test/scoped_feature_list.h"
 #include "base/test/test_future.h"
 #include "base/version.h"
+#include "chrome/browser/apps/app_service/app_launch_params.h"
 #include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_model.h"
 #include "chrome/browser/ui/views/web_apps/isolated_web_apps/isolated_web_app_installer_view.h"
 #include "chrome/browser/ui/web_applications/test/isolated_web_app_builder.h"
@@ -22,9 +23,11 @@
 #include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_url_info.h"
 #include "chrome/browser/web_applications/isolated_web_apps/signed_web_bundle_metadata.h"
 #include "chrome/browser/web_applications/test/fake_web_app_provider.h"
+#include "chrome/browser/web_applications/test/fake_web_app_ui_manager.h"
 #include "chrome/browser/web_applications/test/fake_web_contents_manager.h"
 #include "chrome/browser/web_applications/test/web_app_icon_test_utils.h"
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
+#include "chrome/browser/web_applications/web_app_ui_manager.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/generated_resources.h"
@@ -38,6 +41,16 @@
 #include "third_party/blink/public/common/manifest/manifest.h"
 #include "url/gurl.h"
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+#include "chrome/browser/ash/app_restore/full_restore_service_factory.h"
+#include "components/keyed_service/core/keyed_service.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "chrome/browser/extensions/extension_keeplist_chromeos.h"
+#include "chrome/browser/web_applications/app_service/test/loopback_crosapi_app_service_proxy.h"
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
 namespace web_app {
 namespace {
 
@@ -45,6 +58,7 @@
 using ::testing::Exactly;
 using ::testing::ExplainMatchResult;
 using ::testing::Field;
+using ::testing::IgnoreResult;
 using ::testing::Invoke;
 using ::testing::Property;
 using DialogContent = IsolatedWebAppInstallerModel::DialogContent;
@@ -114,6 +128,12 @@
   return manifest;
 }
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+std::unique_ptr<KeyedService> NullServiceFactory(content::BrowserContext*) {
+  return nullptr;
+}
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
 class MockView : public IsolatedWebAppInstallerView {
  public:
   explicit MockView(IsolatedWebAppInstallerView::Delegate* delegate)
@@ -163,6 +183,19 @@
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
     profile_ = profile_builder.Build();
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+    ash::full_restore::FullRestoreServiceFactory::GetInstance()
+        ->SetTestingFactory(profile_.get(),
+                            base::BindRepeating(&NullServiceFactory));
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+    // Set up Lacros so the AppService -> LaunchWebAppCommand plumbing works.
+    extensions::SetEmptyAshKeeplistForTest();
+    app_service_proxy_ =
+        std::make_unique<LoopbackCrosapiAppServiceProxy>(profile_.get());
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
     test::AwaitStartWebAppProviderAndSubsystems(profile());
   }
 
@@ -206,6 +239,10 @@
   base::ScopedTempDir scoped_temp_dir_;
   data_decoder::test::InProcessDataDecoder in_process_data_decoder_;
   std::unique_ptr<TestingProfile> profile_;
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  std::unique_ptr<LoopbackCrosapiAppServiceProxy> app_service_proxy_;
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
 };
 
 TEST_F(IsolatedWebAppInstallerViewControllerTest,
@@ -341,6 +378,39 @@
       fake_provider()->registrar_unsafe().IsInstalled(url_info.app_id()));
 }
 
+TEST_F(IsolatedWebAppInstallerViewControllerTest, CanLaunchAppAfterInstall) {
+  base::FilePath bundle_path = CreateBundlePath("test_bundle.swbn");
+  IsolatedWebAppUrlInfo url_info = CreateAndWriteTestBundle(bundle_path, "1.0");
+  MockIconAndPageState(url_info, "1.0");
+
+  IsolatedWebAppInstallerModel model(bundle_path);
+  IsolatedWebAppInstallerViewController controller(profile(), fake_provider(),
+                                                   &model);
+  testing::StrictMock<MockView> view(&controller);
+  controller.SetViewForTesting(&view);
+
+  auto metadata = SignedWebBundleMetadata::CreateForTesting(
+      url_info, InstalledBundle(bundle_path), u"app name", base::Version("1.0"),
+      IconBitmaps());
+  model.SetSignedWebBundleMetadata(metadata);
+  model.SetStep(IsolatedWebAppInstallerModel::Step::kConfirmInstall);
+  model.SetDialogContent(CreateDummyDialog());
+
+  EXPECT_CALL(view, ShowInstallScreen(metadata));
+  EXPECT_CALL(view, ShowInstallSuccessScreen(metadata))
+      .WillOnce(IgnoreResult(Invoke(
+          &controller, &IsolatedWebAppInstallerViewController::OnAccept)));
+
+  base::test::TestFuture<apps::AppLaunchParams, LaunchWebAppWindowSetting>
+      future;
+  static_cast<FakeWebAppUiManager*>(&fake_provider()->ui_manager())
+      ->SetOnLaunchWebAppCallback(future.GetRepeatingCallback());
+
+  controller.OnChildDialogAccepted();
+
+  EXPECT_EQ(future.Get<0>().app_id, metadata.app_id());
+}
+
 TEST_F(IsolatedWebAppInstallerViewControllerTest,
        InstallationErrorShowsErrorDialog) {
   base::FilePath bundle_path = CreateBundlePath("test_bundle.swbn");
diff --git a/chrome/browser/ui/webui/ash/arc_graphics_tracing/arc_graphics_tracing_handler.cc b/chrome/browser/ui/webui/ash/arc_graphics_tracing/arc_graphics_tracing_handler.cc
index cdb4750..e5dabf85 100644
--- a/chrome/browser/ui/webui/ash/arc_graphics_tracing/arc_graphics_tracing_handler.cc
+++ b/chrome/browser/ui/webui/ash/arc_graphics_tracing/arc_graphics_tracing_handler.cc
@@ -30,6 +30,7 @@
 #include "chrome/browser/ash/arc/tracing/arc_system_stat_collector.h"
 #include "chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.h"
 #include "chrome/browser/ash/arc/tracing/arc_tracing_model.h"
+#include "chrome/browser/ash/arc/tracing/present_frames_tracer.h"
 #include "chrome/browser/ash/file_manager/path_util.h"
 #include "chrome/browser/platform_util.h"
 #include "chrome/browser/profiles/profile.h"
@@ -70,7 +71,7 @@
   // with absl::optional.
   absl::optional<base::OneShotTimer> stop_timer;
 
-  arc::TraceTimestamps stamps;
+  arc::PresentFramesTracer present_frames;
 };
 
 namespace {
@@ -181,7 +182,7 @@
                                      &common_model.system_model());
 
   trace->model.set_skip_structure_validation();
-  if (!trace->model.Build(common_model, trace->stamps)) {
+  if (!trace->model.Build(common_model, trace->present_frames)) {
     return std::make_pair(base::Value(), "Failed to build tracing model");
   }
 
@@ -370,10 +371,8 @@
     return;
   }
 
-  active_trace_->stamps.AddCommit(SystemTicksNow());
-  surface->RequestPresentationCallback(
-      base::BindRepeating(&ArcGraphicsTracingHandler::RecordPresentedFrame,
-                          weak_ptr_factory_.GetWeakPtr()));
+  active_trace_->present_frames.AddCommit(SystemTicksNow());
+  active_trace_->present_frames.ListenForPresent(surface);
 }
 
 void ArcGraphicsTracingHandler::UpdateActiveArcWindowInfo() {
@@ -535,17 +534,6 @@
                      weak_ptr_factory_.GetWeakPtr()));
 }
 
-void ArcGraphicsTracingHandler::RecordPresentedFrame(
-    const gfx::PresentationFeedback& frame) {
-  if (frame.failed()) {
-    VLOG(5) << "Presentation failed";
-  } else if (frame.timestamp == base::TimeTicks()) {
-    VLOG(5) << "Discarded frame";
-  } else if (active_trace_) {
-    active_trace_->stamps.AddPresent(frame.timestamp);
-  }
-}
-
 void ArcGraphicsTracingHandler::OnGraphicsModelReady(
     std::pair<base::Value, std::string> result) {
   SetStatus(result.second);
diff --git a/chrome/browser/ui/webui/ash/arc_graphics_tracing/arc_graphics_tracing_handler.h b/chrome/browser/ui/webui/ash/arc_graphics_tracing/arc_graphics_tracing_handler.h
index bff6464b..ba69449a 100644
--- a/chrome/browser/ui/webui/ash/arc_graphics_tracing/arc_graphics_tracing_handler.h
+++ b/chrome/browser/ui/webui/ash/arc_graphics_tracing/arc_graphics_tracing_handler.h
@@ -25,14 +25,9 @@
 }  // namespace base
 
 namespace exo {
-class Surface;
 class WMHelper;
 }  // namespace exo
 
-namespace gfx {
-struct PresentationFeedback;
-}  // namespace gfx
-
 namespace aura {
 class Window;
 }  // namespace aura
@@ -114,7 +109,6 @@
   void OnTracingStarted();
   void OnTracingStopped(std::unique_ptr<ActiveTrace> trace,
                         std::unique_ptr<std::string> trace_data);
-  void RecordPresentedFrame(const gfx::PresentationFeedback& present);
 
   // Called when graphics model is built or load. Extra string parameter
   // contains a status. In case model cannot be built/load empty |base::Value|
diff --git a/chrome/browser/ui/webui/ash/arc_power_control/arc_power_control_handler.cc b/chrome/browser/ui/webui/ash/arc_power_control/arc_power_control_handler.cc
index 392938e..9ac301b 100644
--- a/chrome/browser/ui/webui/ash/arc_power_control/arc_power_control_handler.cc
+++ b/chrome/browser/ui/webui/ash/arc_power_control/arc_power_control_handler.cc
@@ -18,6 +18,7 @@
 #include "chrome/browser/ash/arc/tracing/arc_tracing_graphics_model.h"
 #include "chrome/browser/ash/arc/tracing/arc_tracing_model.h"
 #include "chrome/browser/ash/arc/tracing/arc_value_event_trimmer.h"
+#include "chrome/browser/ash/arc/tracing/present_frames_tracer.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 
@@ -101,7 +102,7 @@
   graphics_model.set_skip_structure_validation();
   graphics_model.set_platform(base::GetLinuxDistro());
   graphics_model.set_timestamp(timestamp);
-  graphics_model.Build(common_model, arc::TraceTimestamps() /* commits */);
+  graphics_model.Build(common_model, arc::PresentFramesTracer() /* commits */);
 
   return base::Value(graphics_model.Serialize());
 }
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/display_settings/display_settings_provider.cc b/chrome/browser/ui/webui/ash/settings/pages/device/display_settings/display_settings_provider.cc
index 621c9b6..a07aae80 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/display_settings/display_settings_provider.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/display_settings/display_settings_provider.cc
@@ -57,8 +57,7 @@
   display_configuration_observers_.Add(std::move(observer));
 }
 
-void DisplaySettingsProvider::OnDidProcessDisplayChanges(
-    const DisplayConfigurationChange& configuration_change) {
+void DisplaySettingsProvider::OnDidProcessDisplayChanges() {
   for (auto& observer : display_configuration_observers_) {
     observer->OnDisplayConfigurationChanged();
   }
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/display_settings/display_settings_provider.h b/chrome/browser/ui/webui/ash/settings/pages/device/display_settings/display_settings_provider.h
index 2e89f8e..d5586669 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/display_settings/display_settings_provider.h
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/display_settings/display_settings_provider.h
@@ -41,8 +41,7 @@
   void OnTabletModeEventsBlockingChanged() override;
 
   // display::DisplayManagerObserver:
-  void OnDidProcessDisplayChanges(
-      const DisplayConfigurationChange& configuration_change) override;
+  void OnDidProcessDisplayChanges() override;
 
  private:
   mojo::RemoteSet<mojom::TabletModeObserver> tablet_mode_observers_;
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/display_settings/display_settings_provider_unittest.cc b/chrome/browser/ui/webui/ash/settings/pages/device/display_settings/display_settings_provider_unittest.cc
index ee5b0d6..6c0d43e 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/display_settings/display_settings_provider_unittest.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/display_settings/display_settings_provider_unittest.cc
@@ -131,7 +131,7 @@
       fake_observer.receiver.BindNewPipeAndPassRemote());
   base::RunLoop().RunUntilIdle();
 
-  provider_->OnDidProcessDisplayChanges(/*configuration_change=*/{{}, {}, {}});
+  provider_->OnDidProcessDisplayChanges();
   fake_observer.WaitForDisplayConfigurationChanged();
 
   EXPECT_EQ(1u, fake_observer.num_display_configuration_changed_calls());
diff --git a/chrome/browser/ui/webui/ash/shortcut_customization/integration_tests/add_custom_accelerator_and_reset_interactive_uitest.cc b/chrome/browser/ui/webui/ash/shortcut_customization/integration_tests/add_custom_accelerator_and_reset_interactive_uitest.cc
index d381182..573a794 100644
--- a/chrome/browser/ui/webui/ash/shortcut_customization/integration_tests/add_custom_accelerator_and_reset_interactive_uitest.cc
+++ b/chrome/browser/ui/webui/ash/shortcut_customization/integration_tests/add_custom_accelerator_and_reset_interactive_uitest.cc
@@ -31,29 +31,27 @@
       WaitForWebContentsReady(kShortcutAppWebContentsId,
                               GURL("chrome://shortcut-customization")),
       InAnyContext(Steps(
-          FocusWebContents(webcontents_id_),
-          SendAccelerator(webcontents_id_, new_accel),
+          SendShortcutAccelerator(new_accel),
           EnsureNotPresent(kCalendarViewElementId),
           Log("Verify that the custom shortcut does not open the calendar "
               "before it's added as a shortcut"),
           OpenCalendarShortcutDialog(), AddCustomCalendarShortcut(new_accel),
           Log("Adding Search + Ctrl + n as a custom open/close calendar "
               "shortcut"),
-          FocusWebContents(webcontents_id_), EnsureAcceleratorsAreProcessed(),
-          SendAccelerator(webcontents_id_, new_accel), FlushEvents(),
+          EnsureAcceleratorsAreProcessed(), SendShortcutAccelerator(new_accel),
           WaitForShow(kCalendarViewElementId),
           Log("Custom shortcut opens calendar"),
-          SendAccelerator(webcontents_id_, new_accel), FlushEvents(),
+          SendShortcutAccelerator(new_accel),
           WaitForHide(kCalendarViewElementId),
           Log("Custom shortcut closes calendar"), ResetCalendarShortcuts(),
           Log("Open/Close calendar shortcut reset to defaults"),
-          FocusWebContents(webcontents_id_), EnsureAcceleratorsAreProcessed(),
-          SendAccelerator(webcontents_id_, default_accel), FlushEvents(),
+          EnsureAcceleratorsAreProcessed(),
+          SendShortcutAccelerator(default_accel),
           WaitForShow(kCalendarViewElementId),
-          SendAccelerator(webcontents_id_, default_accel), FlushEvents(),
+          SendShortcutAccelerator(default_accel),
           WaitForHide(kCalendarViewElementId),
           Log("Default shortcut still works"),
-          SendAccelerator(webcontents_id_, new_accel), FlushEvents(),
+          SendShortcutAccelerator(new_accel),
           EnsureNotPresent(kCalendarViewElementId),
           Log("Custom shortcut no longer works"))));
 }
diff --git a/chrome/browser/ui/webui/ash/shortcut_customization/integration_tests/add_custom_accelerator_to_unlocked_action_interactive_uitest.cc b/chrome/browser/ui/webui/ash/shortcut_customization/integration_tests/add_custom_accelerator_to_unlocked_action_interactive_uitest.cc
index 52bb638..23258fc 100644
--- a/chrome/browser/ui/webui/ash/shortcut_customization/integration_tests/add_custom_accelerator_to_unlocked_action_interactive_uitest.cc
+++ b/chrome/browser/ui/webui/ash/shortcut_customization/integration_tests/add_custom_accelerator_to_unlocked_action_interactive_uitest.cc
@@ -47,7 +47,7 @@
       WaitForWebContentsReady(kShortcutAppWebContentsId,
                               GURL("chrome://shortcut-customization")),
       InAnyContext(Steps(
-          SendAccelerator(webcontents_id_, new_accel),
+          SendShortcutAccelerator(new_accel),
           EnsureNotPresent(kCalendarViewElementId),
           Log("Verify that the custom shortcut does not open the calendar "
               "before it's added as a shortcut"),
@@ -56,20 +56,20 @@
               "shortcut"),
           EnsurePresent(webcontents_id_, kCustomAcceleratorViewQuery),
           Log("New shortcut is present in the UI"),
-          SendAccelerator(webcontents_id_, new_accel), FlushEvents(),
+          SendShortcutAccelerator(new_accel),
           WaitForShow(kCalendarViewElementId),
           Log("Custom shortcut opens calendar"),
-          SendAccelerator(webcontents_id_, new_accel), FlushEvents(),
+          SendShortcutAccelerator(new_accel),
           WaitForHide(kCalendarViewElementId),
           Log("Custom shortcut closes calendar"), ResetCalendarShortcuts(),
           Log("Open/Close calendar shortcut reset to defaults"),
-          FocusWebContents(webcontents_id_), EnsureAcceleratorsAreProcessed(),
-          SendAccelerator(webcontents_id_, default_accel), FlushEvents(),
+          EnsureAcceleratorsAreProcessed(),
+          SendShortcutAccelerator(default_accel),
           WaitForShow(kCalendarViewElementId),
-          SendAccelerator(webcontents_id_, default_accel), FlushEvents(),
+          SendShortcutAccelerator(default_accel),
           WaitForHide(kCalendarViewElementId),
           Log("Default shortcut still works"),
-          SendAccelerator(webcontents_id_, new_accel), FlushEvents(),
+          SendShortcutAccelerator(new_accel),
           EnsureNotPresent(kCalendarViewElementId),
           Log("Custom shortcut no longer works"))));
 }
diff --git a/chrome/browser/ui/webui/ash/shortcut_customization/integration_tests/edit_default_accelerator_interactive_uitest.cc b/chrome/browser/ui/webui/ash/shortcut_customization/integration_tests/edit_default_accelerator_interactive_uitest.cc
index 61ff117..e3cea40 100644
--- a/chrome/browser/ui/webui/ash/shortcut_customization/integration_tests/edit_default_accelerator_interactive_uitest.cc
+++ b/chrome/browser/ui/webui/ash/shortcut_customization/integration_tests/edit_default_accelerator_interactive_uitest.cc
@@ -34,13 +34,13 @@
           OpenCalendarShortcutDialog(), EditDefaultShortcut(new_accel),
           Log("Setting Search + Ctrl + n as the default open/close calendar "
               "shortcut"),
-          SendAccelerator(webcontents_id_, new_accel), FlushEvents(),
+          SendShortcutAccelerator(new_accel),
           WaitForShow(kCalendarViewElementId),
           Log("New accelerator opens calendar"),
-          SendAccelerator(webcontents_id_, new_accel), FlushEvents(),
+          SendShortcutAccelerator(new_accel),
           WaitForHide(kCalendarViewElementId),
           Log("New accelerator closes calendar"),
-          SendAccelerator(webcontents_id_, default_accel), FlushEvents(),
+          SendShortcutAccelerator(default_accel),
           EnsureNotPresent(kCalendarViewElementId),
           Log("Default accelerator no longer opens the calendar"))));
 }
diff --git a/chrome/browser/ui/webui/ash/shortcut_customization/shortcut_customization_test_base.cc b/chrome/browser/ui/webui/ash/shortcut_customization/shortcut_customization_test_base.cc
index 33b0f39..152eb38 100644
--- a/chrome/browser/ui/webui/ash/shortcut_customization/shortcut_customization_test_base.cc
+++ b/chrome/browser/ui/webui/ash/shortcut_customization/shortcut_customization_test_base.cc
@@ -7,6 +7,7 @@
 #include "ash/webui/system_apps/public/system_web_app_type.h"
 #include "chrome/test/interaction/interactive_browser_test.h"
 #include "ui/base/interaction/interaction_sequence.h"
+#include "ui/base/interaction/interactive_test.h"
 
 namespace ash {
 
@@ -46,4 +47,11 @@
                    "shortcutProvider.preventProcessingAccelerators(false)");
 }
 
+ui::test::InteractiveTestApi::MultiStep
+ShortcutCustomizationInteractiveUiTestBase::SendShortcutAccelerator(
+    ui::Accelerator accel) {
+  CHECK(webcontents_id_);
+  return Steps(SendAccelerator(webcontents_id_, accel), FlushEvents());
+}
+
 }  // namespace ash
diff --git a/chrome/browser/ui/webui/ash/shortcut_customization/shortcut_customization_test_base.h b/chrome/browser/ui/webui/ash/shortcut_customization/shortcut_customization_test_base.h
index 5d725734..57fdc8b 100644
--- a/chrome/browser/ui/webui/ash/shortcut_customization/shortcut_customization_test_base.h
+++ b/chrome/browser/ui/webui/ash/shortcut_customization/shortcut_customization_test_base.h
@@ -7,6 +7,7 @@
 
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/ash/system_web_apps/test_support/system_web_app_browsertest_base.h"
+#include "ui/base/accelerators/accelerator.h"
 #include "ui/base/interaction/interaction_sequence.h"
 
 namespace ash {
@@ -113,6 +114,9 @@
   // prevent the system from processing Ash accelerators.
   ui::InteractionSequence::StepBuilder EnsureAcceleratorsAreProcessed();
 
+  ui::test::InteractiveTestApi::MultiStep SendShortcutAccelerator(
+      ui::Accelerator accel);
+
   void SetUpOnMainThread() override;
 
  protected:
diff --git a/chrome/browser/ui/webui/certificate_viewer_webui.cc b/chrome/browser/ui/webui/certificate_viewer_webui.cc
index 1f2afcc..c1b1404 100644
--- a/chrome/browser/ui/webui/certificate_viewer_webui.cc
+++ b/chrome/browser/ui/webui/certificate_viewer_webui.cc
@@ -117,6 +117,100 @@
   return std::move(node_);
 }
 
+std::string HandleOptionalOrError(
+    const x509_certificate_model::OptionalStringOrError& s) {
+  if (absl::holds_alternative<x509_certificate_model::Error>(s))
+    return l10n_util::GetStringUTF8(IDS_CERT_DUMP_ERROR);
+  else if (absl::holds_alternative<x509_certificate_model::NotPresent>(s))
+    return l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT);
+  return absl::get<std::string>(s);
+}
+
+std::string DialogArgsForCertList(
+    const std::vector<x509_certificate_model::X509CertificateModel>& certs) {
+  std::string data;
+
+  // Certificate information. The keys in this dictionary's general key
+  // correspond to the IDs in the Html page.
+  base::Value::Dict cert_info;
+  const x509_certificate_model::X509CertificateModel& model = certs.front();
+
+  cert_info.Set("isError", !model.is_valid());
+  cert_info.SetByDottedPath(
+      "general.title",
+      l10n_util::GetStringFUTF8(IDS_CERT_INFO_DIALOG_TITLE,
+                                base::UTF8ToUTF16(model.GetTitle())));
+
+  if (model.is_valid()) {
+    // Standard certificate details.
+    const std::string alternative_text =
+        l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT);
+
+    // Issued to information.
+    cert_info.SetByDottedPath(
+        "general.issued-cn",
+        HandleOptionalOrError(model.GetSubjectCommonName()));
+    cert_info.SetByDottedPath("general.issued-o",
+                              HandleOptionalOrError(model.GetSubjectOrgName()));
+    cert_info.SetByDottedPath(
+        "general.issued-ou",
+        HandleOptionalOrError(model.GetSubjectOrgUnitName()));
+
+    // Issuer information.
+    cert_info.SetByDottedPath(
+        "general.issuer-cn",
+        HandleOptionalOrError(model.GetIssuerCommonName()));
+    cert_info.SetByDottedPath("general.issuer-o",
+                              HandleOptionalOrError(model.GetIssuerOrgName()));
+    cert_info.SetByDottedPath(
+        "general.issuer-ou",
+        HandleOptionalOrError(model.GetIssuerOrgUnitName()));
+
+    // Validity period.
+    base::Time issued, expires;
+    std::string issued_str, expires_str;
+    if (model.GetTimes(&issued, &expires)) {
+      issued_str =
+          base::UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(issued));
+      expires_str =
+          base::UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(expires));
+    } else {
+      issued_str = alternative_text;
+      expires_str = alternative_text;
+    }
+    cert_info.SetByDottedPath("general.issue-date", issued_str);
+    cert_info.SetByDottedPath("general.expiry-date", expires_str);
+    cert_info.SetByDottedPath("general.spki", model.HashSpkiSHA256());
+  }
+
+  // We always have a cert hash. We don't always have a SPKI hash, if the cert
+  // is not valid.
+  cert_info.SetByDottedPath("general.sha256", model.HashCertSHA256());
+
+  // Certificate hierarchy is constructed from bottom up.
+  base::Value::List children;
+  int index = 0;
+  for (const auto& cert : certs) {
+    base::Value::Dict cert_node;
+    cert_node.Set("label", base::Value(cert.GetTitle()));
+    cert_node.SetByDottedPath("payload.index", base::Value(index));
+    // Add the child from the previous iteration.
+    if (!children.empty())
+      cert_node.Set("children", std::move(children));
+
+    // Add this node to the children list for the next iteration.
+    children = base::Value::List();
+    children.Append(std::move(cert_node));
+    ++index;
+  }
+  // Set the last node as the top of the certificate hierarchy.
+  cert_info.Set("hierarchy", std::move(children));
+
+  base::JSONWriter::Write(cert_info, &data);
+
+  return data;
+}
+
 }  // namespace
 
 // Shows a certificate using the WebUI certificate viewer.
@@ -203,162 +297,43 @@
 }
 
 CertificateViewerDialog::CertificateViewerDialog(
-    std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> certs,
+    std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> in_certs,
     std::vector<std::string> cert_nicknames) {
-  for (size_t i = 0; i < certs.size(); ++i) {
+  CHECK(!in_certs.empty());
+
+  std::vector<x509_certificate_model::X509CertificateModel> certs;
+  for (size_t i = 0; i < in_certs.size(); ++i) {
     std::string nickname;
-    if (i < cert_nicknames.size())
+    if (i < cert_nicknames.size()) {
       nickname = std::move(cert_nicknames[i]);
-    certs_.emplace_back(std::move(certs[i]), std::move(nickname));
+    }
+    certs.emplace_back(std::move(in_certs[i]), std::move(nickname));
   }
-  // Construct the dialog title from the certificate.
-  title_ = l10n_util::GetStringFUTF16(
-      IDS_CERT_INFO_DIALOG_TITLE, base::UTF8ToUTF16(certs_.front().GetTitle()));
+
+  constexpr gfx::Size kDefaultSize{544, 628};
+  set_can_close(true);
+  set_delete_on_close(false);
+  set_dialog_args(DialogArgsForCertList(certs));
+  set_dialog_modal_type(ui::MODAL_TYPE_NONE);
+  set_dialog_content_url(GURL(chrome::kChromeUICertificateViewerURL));
+  set_dialog_size(kDefaultSize);
+  set_dialog_title(l10n_util::GetStringFUTF16(
+      IDS_CERT_INFO_DIALOG_TITLE, base::UTF8ToUTF16(certs.front().GetTitle())));
+  set_show_dialog_title(true);
+
+  AddWebUIMessageHandler(
+      std::make_unique<CertificateViewerDialogHandler>(this, std::move(certs)));
 }
 
 CertificateViewerDialog::~CertificateViewerDialog() = default;
 
-ui::ModalType CertificateViewerDialog::GetDialogModalType() const {
-  return ui::MODAL_TYPE_NONE;
-}
-
-std::u16string CertificateViewerDialog::GetDialogTitle() const {
-  return title_;
-}
-
-GURL CertificateViewerDialog::GetDialogContentURL() const {
-  return GURL(chrome::kChromeUICertificateViewerURL);
-}
-
-void CertificateViewerDialog::GetWebUIMessageHandlers(
-    std::vector<WebUIMessageHandler*>* handlers) {
-  handlers->push_back(new CertificateViewerDialogHandler(
-      const_cast<CertificateViewerDialog*>(this), &certs_));
-}
-
-void CertificateViewerDialog::GetDialogSize(gfx::Size* size) const {
-  const int kDefaultWidth = 544;
-  const int kDefaultHeight = 628;
-  size->SetSize(kDefaultWidth, kDefaultHeight);
-}
-
-std::string HandleOptionalOrError(
-    const x509_certificate_model::OptionalStringOrError& s) {
-  if (absl::holds_alternative<x509_certificate_model::Error>(s))
-    return l10n_util::GetStringUTF8(IDS_CERT_DUMP_ERROR);
-  else if (absl::holds_alternative<x509_certificate_model::NotPresent>(s))
-    return l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT);
-  return absl::get<std::string>(s);
-}
-
-std::string CertificateViewerDialog::GetDialogArgs() const {
-  std::string data;
-
-  // Certificate information. The keys in this dictionary's general key
-  // correspond to the IDs in the Html page.
-  base::Value::Dict cert_info;
-  const x509_certificate_model::X509CertificateModel& model = certs_.front();
-
-  cert_info.Set("isError", !model.is_valid());
-  cert_info.SetByDottedPath(
-      "general.title",
-      l10n_util::GetStringFUTF8(IDS_CERT_INFO_DIALOG_TITLE,
-                                base::UTF8ToUTF16(model.GetTitle())));
-
-  if (model.is_valid()) {
-    // Standard certificate details.
-    const std::string alternative_text =
-        l10n_util::GetStringUTF8(IDS_CERT_INFO_FIELD_NOT_PRESENT);
-
-    // Issued to information.
-    cert_info.SetByDottedPath(
-        "general.issued-cn",
-        HandleOptionalOrError(model.GetSubjectCommonName()));
-    cert_info.SetByDottedPath("general.issued-o",
-                              HandleOptionalOrError(model.GetSubjectOrgName()));
-    cert_info.SetByDottedPath(
-        "general.issued-ou",
-        HandleOptionalOrError(model.GetSubjectOrgUnitName()));
-
-    // Issuer information.
-    cert_info.SetByDottedPath(
-        "general.issuer-cn",
-        HandleOptionalOrError(model.GetIssuerCommonName()));
-    cert_info.SetByDottedPath("general.issuer-o",
-                              HandleOptionalOrError(model.GetIssuerOrgName()));
-    cert_info.SetByDottedPath(
-        "general.issuer-ou",
-        HandleOptionalOrError(model.GetIssuerOrgUnitName()));
-
-    // Validity period.
-    base::Time issued, expires;
-    std::string issued_str, expires_str;
-    if (model.GetTimes(&issued, &expires)) {
-      issued_str =
-          base::UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(issued));
-      expires_str =
-          base::UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(expires));
-    } else {
-      issued_str = alternative_text;
-      expires_str = alternative_text;
-    }
-    cert_info.SetByDottedPath("general.issue-date", issued_str);
-    cert_info.SetByDottedPath("general.expiry-date", expires_str);
-    cert_info.SetByDottedPath("general.spki", model.HashSpkiSHA256());
-  }
-
-  // We always have a cert hash. We don't always have a SPKI hash, if the cert
-  // is not valid.
-  cert_info.SetByDottedPath("general.sha256", model.HashCertSHA256());
-
-  // Certificate hierarchy is constructed from bottom up.
-  base::Value::List children;
-  int index = 0;
-  for (const auto& cert : certs_) {
-    base::Value::Dict cert_node;
-    cert_node.Set("label", base::Value(cert.GetTitle()));
-    cert_node.SetByDottedPath("payload.index", base::Value(index));
-    // Add the child from the previous iteration.
-    if (!children.empty())
-      cert_node.Set("children", std::move(children));
-
-    // Add this node to the children list for the next iteration.
-    children = base::Value::List();
-    children.Append(std::move(cert_node));
-    ++index;
-  }
-  // Set the last node as the top of the certificate hierarchy.
-  cert_info.Set("hierarchy", std::move(children));
-
-  base::JSONWriter::Write(cert_info, &data);
-
-  return data;
-}
-
-void CertificateViewerDialog::OnDialogShown(content::WebUI* webui) {
-  webui_ = webui;
-}
-
-void CertificateViewerDialog::OnDialogClosed(const std::string& json_retval) {
-  // Don't |delete this|: owned by the constrained dialog manager.
-}
-
-void CertificateViewerDialog::OnCloseContents(WebContents* source,
-                                              bool* out_close_dialog) {
-  *out_close_dialog = true;
-}
-
-bool CertificateViewerDialog::ShouldShowDialogTitle() const {
-  return true;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // CertificateViewerDialogHandler
 
 CertificateViewerDialogHandler::CertificateViewerDialogHandler(
     CertificateViewerDialog* dialog,
-    const std::vector<x509_certificate_model::X509CertificateModel>* certs)
-    : dialog_(dialog), certs_(certs) {}
+    std::vector<x509_certificate_model::X509CertificateModel> certs)
+    : dialog_(dialog), certs_(std::move(certs)) {}
 
 CertificateViewerDialogHandler::~CertificateViewerDialogHandler() {
 }
@@ -387,12 +362,11 @@
           dialog_->GetNativeWebContentsModalDialog()));
 
   std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> export_certs;
-  for (const auto& cert : base::make_span(*certs_).subspan(cert_index)) {
+  for (const auto& cert : base::make_span(certs_).subspan(cert_index)) {
     export_certs.push_back(bssl::UpRef(cert.cert_buffer()));
   }
   ShowCertExportDialog(web_ui()->GetWebContents(), window,
-                       std::move(export_certs),
-                       (*certs_)[cert_index].GetTitle());
+                       std::move(export_certs), certs_[cert_index].GetTitle());
 }
 
 void CertificateViewerDialogHandler::HandleRequestCertificateFields(
@@ -404,7 +378,7 @@
     return;
 
   const x509_certificate_model::X509CertificateModel& model =
-      (*certs_)[cert_index];
+      certs_[cert_index];
 
   CertNodeBuilder contents_builder(IDS_CERT_DETAILS_CERTIFICATE);
 
@@ -502,7 +476,8 @@
 int CertificateViewerDialogHandler::GetCertificateIndex(
     int requested_index) const {
   int cert_index = requested_index;
-  if (cert_index < 0 || static_cast<size_t>(cert_index) >= certs_->size())
+  if (cert_index < 0 || static_cast<size_t>(cert_index) >= certs_.size()) {
     return -1;
+  }
   return cert_index;
 }
diff --git a/chrome/browser/ui/webui/certificate_viewer_webui.h b/chrome/browser/ui/webui/certificate_viewer_webui.h
index 377a9c7..0ba98ed 100644
--- a/chrome/browser/ui/webui/certificate_viewer_webui.h
+++ b/chrome/browser/ui/webui/certificate_viewer_webui.h
@@ -62,26 +62,6 @@
   CertificateViewerDialog(std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> certs,
                           std::vector<std::string> cert_nicknames);
 
-  // ui::WebDialogDelegate:
-  ui::ModalType GetDialogModalType() const override;
-  std::u16string GetDialogTitle() const override;
-  GURL GetDialogContentURL() const override;
-  void GetWebUIMessageHandlers(
-      std::vector<content::WebUIMessageHandler*>* handlers) override;
-  void GetDialogSize(gfx::Size* size) const override;
-  std::string GetDialogArgs() const override;
-  void OnDialogShown(content::WebUI* webui) override;
-  void OnDialogClosed(const std::string& json_retval) override;
-  void OnCloseContents(content::WebContents* source,
-                       bool* out_close_dialog) override;
-  bool ShouldShowDialogTitle() const override;
-
-  std::vector<x509_certificate_model::X509CertificateModel> certs_;
-
-  // The title of the certificate viewer dialog, Certificate Viewer: CN.
-  std::u16string title_;
-
-  raw_ptr<content::WebUI, DanglingUntriaged> webui_ = nullptr;
   raw_ptr<ConstrainedWebDialogDelegate, DanglingUntriaged> delegate_ = nullptr;
 };
 
@@ -91,7 +71,7 @@
  public:
   CertificateViewerDialogHandler(
       CertificateViewerDialog* dialog,
-      const std::vector<x509_certificate_model::X509CertificateModel>* certs);
+      std::vector<x509_certificate_model::X509CertificateModel> certs);
 
   CertificateViewerDialogHandler(const CertificateViewerDialogHandler&) =
       delete;
@@ -124,8 +104,7 @@
   // The dialog.
   raw_ptr<CertificateViewerDialog> dialog_;
 
-  raw_ptr<const std::vector<x509_certificate_model::X509CertificateModel>>
-      certs_;
+  std::vector<x509_certificate_model::X509CertificateModel> certs_;
 };
 
 #endif  // CHROME_BROWSER_UI_WEBUI_CERTIFICATE_VIEWER_WEBUI_H_
diff --git a/chrome/browser/ui/webui/compose/compose_ui.cc b/chrome/browser/ui/webui/compose/compose_ui.cc
index 98b0c68c..25d570f 100644
--- a/chrome/browser/ui/webui/compose/compose_ui.cc
+++ b/chrome/browser/ui/webui/compose/compose_ui.cc
@@ -64,6 +64,8 @@
       {"editCancelButton", IDS_CANCEL},
       {"editUpdateButton", IDS_COMPOSE_EDIT_UPDATE_BUTTON},
       {"fileBugText", IDS_COMPOSE_FILE_BUG},
+      {"thumbsDown", IDS_THUMBS_DOWN},
+      {"thumbsUp", IDS_THUMBS_UP},
   };
   source->AddLocalizedStrings(kStrings);
 }
diff --git a/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc b/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc
index bf0d296..68d7022 100644
--- a/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/constrained_web_dialog_ui_browsertest.cc
@@ -148,7 +148,8 @@
 // Tests that dialog autoresizes based on web contents when autoresizing
 // is enabled.
 // Flaky on CrOS: http://crbug.com/928924
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+// Flaky on Mac: http://crbug.com/1498848
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
 #define MAYBE_ContentResizeInAutoResizingDialog \
   DISABLED_ContentResizeInAutoResizingDialog
 #else
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
index 3dc9b61..ad5e9215 100644
--- a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
@@ -60,7 +60,7 @@
 #include "chrome/browser/policy/dm_token_utils.h"
 
 #if BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
-#include "chrome/browser/enterprise/connectors/analysis/fake_content_analysis_sdk_manager.h"  // nogncheck
+#include "chrome/browser/enterprise/connectors/test/fake_content_analysis_sdk_manager.h"  // nogncheck
 #endif  // BUILDFLAG(ENTERPRISE_LOCAL_CONTENT_ANALYSIS)
 #endif  // BUILDFLAG(ENABLE_PRINT_CONTENT_ANALYSIS)
 
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc
index 5d53d35..1b9d0a1 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc
@@ -103,6 +103,7 @@
       {"uploadImage", IDS_NTP_CUSTOM_BG_UPLOAD_AN_IMAGE},
       {"uploadedImage", IDS_NTP_CUSTOMIZE_UPLOADED_IMAGE_LABEL},
       {"yourUploadedImage", IDS_NTP_CUSTOMIZE_YOUR_UPLOADED_IMAGE_LABEL},
+      {"yourSearchedImage", IDS_NTP_CUSTOMIZE_YOUR_SEARCHED_IMAGE_LABEL},
       {"resetToClassicChrome",
        IDS_NTP_CUSTOMIZE_CHROME_RESET_TO_CLASSIC_CHROME_LABEL},
       {"followThemeToggle", IDS_NTP_CUSTOMIZE_CHROME_FOLLOW_THEME_LABEL},
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler.cc b/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler.cc
index 4bdf75a..302aba4 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler.cc
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler.cc
@@ -84,13 +84,21 @@
       receiver_(this, std::move(pending_handler)) {}
 
 WallpaperSearchHandler::~WallpaperSearchHandler() {
-  if (log_entry_) {
+  auto backround_id =
+      wallpaper_search_background_manager_->SaveCurrentBackgroundToHistory();
+  if (!log_entries_.empty()) {
     auto* quality =
-        log_entry_
+        log_entries_.back()
             ->quality_data<optimization_guide::WallpaperSearchFeatureTypeMap>();
     quality->set_final_request_in_session(true);
+    if (backround_id.has_value() &&
+        base::Contains(wallpaper_search_results_, *backround_id)) {
+      auto* image_quality = wallpaper_search_results_[*backround_id].first;
+      if (image_quality) {
+        image_quality->set_selected(true);
+      }
+    }
   }
-  wallpaper_search_background_manager_->SaveCurrentBackgroundToHistory();
 }
 
 void WallpaperSearchHandler::GetDescriptors(GetDescriptorsCallback callback) {
@@ -199,8 +207,12 @@
 void WallpaperSearchHandler::SetBackgroundToWallpaperSearchResult(
     const base::Token& result_id) {
   CHECK(base::Contains(wallpaper_search_results_, result_id));
-  wallpaper_search_background_manager_->SelectLocalBackgroundImage(
-      result_id, wallpaper_search_results_[result_id]);
+  auto& [image_quality, bitmap] = wallpaper_search_results_[result_id];
+  if (image_quality) {
+    image_quality->set_previewed(true);
+  }
+  wallpaper_search_background_manager_->SelectLocalBackgroundImage(result_id,
+                                                                   bitmap);
 }
 
 void WallpaperSearchHandler::OnDescriptorsRetrieved(
@@ -306,15 +318,16 @@
     base::ElapsedTimer request_timer,
     optimization_guide::OptimizationGuideModelExecutionResult result,
     std::unique_ptr<optimization_guide::ModelQualityLogEntry> log_entry) {
-  // Logs data of the previous log entry if it exists.
-  log_entry_ = std::move(log_entry);
-  if (log_entry_) {
+  if (log_entry) {
+    log_entries_.push_back(std::move(log_entry));
+  }
+  if (!log_entries_.empty()) {
     auto* quality =
-        log_entry_
+        log_entries_.back()
             ->quality_data<optimization_guide::WallpaperSearchFeatureTypeMap>();
     quality->set_session_id(session_id_);
-    quality->set_index(request_index_++);
-    // We will set this to true if the log entry still exist when the side panel
+    quality->set_index(log_entries_.size() - 1);
+    // We will set this to true for the respective log entry when the side panel
     // closes.
     quality->set_final_request_in_session(false);
     quality->set_request_latency_ms(request_timer.Elapsed().InMilliseconds());
@@ -337,7 +350,8 @@
   if (response->images().empty()) {
     return;
   }
-  auto barrier = base::BarrierCallback<SkBitmap>(
+  auto barrier = base::BarrierCallback<std::pair<
+      optimization_guide::proto::WallpaperSearchImageQuality*, SkBitmap>>(
       response->images_size(),
       base::BindOnce(&WallpaperSearchHandler::OnWallpaperSearchResultsDecoded,
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
@@ -346,20 +360,33 @@
   // from gfx::Image to SkBitmap before passing to the barrier callback because
   // of some issues with const gfx::Image& and base::BarrierCallback.
   for (auto& image : response->images()) {
-    if (log_entry_) {
-      auto* quality = log_entry_->quality_data<
-          optimization_guide::WallpaperSearchFeatureTypeMap>();
-      auto* image_quality = quality->add_images_quality();
+    optimization_guide::proto::WallpaperSearchImageQuality* image_quality =
+        nullptr;
+    if (!log_entries_.empty()) {
+      auto* quality =
+          log_entries_.back()
+              ->quality_data<
+                  optimization_guide::WallpaperSearchFeatureTypeMap>();
+      image_quality = quality->add_images_quality();
       image_quality->set_image_id(image.image_id());
+      // We default to false and will flip if image was previewed or selected.
+      image_quality->set_previewed(false);
+      image_quality->set_selected(false);
     }
     image_decoder_->DecodeImage(
         image.encoded_image(), gfx::Size(), nullptr,
         base::BindOnce(
-            [](base::RepeatingCallback<void(SkBitmap)> barrier,
+            [](base::RepeatingCallback<void(
+                   std::pair<
+                       optimization_guide::proto::WallpaperSearchImageQuality*,
+                       SkBitmap>)> barrier,
+               optimization_guide::proto::WallpaperSearchImageQuality*
+                   image_quality,
                const gfx::Image& image) {
-              std::move(barrier).Run(image.AsBitmap());
+              std::move(barrier).Run(
+                  std::make_pair(image_quality, image.AsBitmap()));
             },
-            barrier));
+            barrier, image_quality));
   }
 }
 
@@ -368,11 +395,13 @@
 // make it base64 for easy reading by the UI.
 void WallpaperSearchHandler::OnWallpaperSearchResultsDecoded(
     GetWallpaperSearchResultsCallback callback,
-    std::vector<SkBitmap> bitmaps) {
+    std::vector<
+        std::pair<optimization_guide::proto::WallpaperSearchImageQuality*,
+                  SkBitmap>> bitmaps) {
   std::vector<side_panel::customize_chrome::mojom::WallpaperSearchResultPtr>
       thumbnails;
 
-  for (auto& bitmap : bitmaps) {
+  for (auto& [image_quality, bitmap] : bitmaps) {
     auto dimensions =
         CalculateResizeDimensions(bitmap.width(), bitmap.height(), 100);
     SkBitmap small_bitmap = skia::ImageOperations::Resize(
@@ -386,7 +415,8 @@
       auto thumbnail =
           side_panel::customize_chrome::mojom::WallpaperSearchResult::New();
       auto id = base::Token::CreateRandom();
-      wallpaper_search_results_[id] = std::move(bitmap);
+      wallpaper_search_results_[id] =
+          std::make_pair(image_quality, std::move(bitmap));
       thumbnail->image = base::Base64Encode(encoded);
       thumbnail->id = std::move(id);
       thumbnails.push_back(std::move(thumbnail));
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler.h b/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler.h
index e285fc5..32734ca 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler.h
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_UI_WEBUI_SIDE_PANEL_CUSTOMIZE_CHROME_WALLPAPER_SEARCH_WALLPAPER_SEARCH_HANDLER_H_
 #define CHROME_BROWSER_UI_WEBUI_SIDE_PANEL_CUSTOMIZE_CHROME_WALLPAPER_SEARCH_WALLPAPER_SEARCH_HANDLER_H_
 
+#include <utility>
 #include <vector>
 
 #include "base/containers/flat_map.h"
@@ -72,7 +73,9 @@
       std::unique_ptr<optimization_guide::ModelQualityLogEntry> log_entry);
   void OnWallpaperSearchResultsDecoded(
       GetWallpaperSearchResultsCallback callback,
-      std::vector<SkBitmap> bitmaps);
+      std::vector<
+          std::pair<optimization_guide::proto::WallpaperSearchImageQuality*,
+                    SkBitmap>> bitmaps);
 
   raw_ptr<Profile> profile_;
   std::unique_ptr<network::SimpleURLLoader> simple_url_loader_;
@@ -80,10 +83,19 @@
   const raw_ref<image_fetcher::ImageDecoder> image_decoder_;
   const raw_ref<WallpaperSearchBackgroundManager>
       wallpaper_search_background_manager_;
-  base::flat_map<base::Token, SkBitmap> wallpaper_search_results_;
-  std::unique_ptr<optimization_guide::ModelQualityLogEntry> log_entry_;
+  // We keep all log entries alive until the session closes because whether and
+  // which image was selected will only be known then.
+  std::vector<std::unique_ptr<optimization_guide::ModelQualityLogEntry>>
+      log_entries_;
+  // `wallpaper_search_results_` points to entries in `log_entries_`. Therefore,
+  // `wallpaper_search_results_` is defined below so that the pointers get
+  // destructed before the pointed to objects in `log_entries_`.
+  base::flat_map<
+      base::Token,
+      std::pair<optimization_guide::proto::WallpaperSearchImageQuality*,
+                SkBitmap>>
+      wallpaper_search_results_;
   const int64_t session_id_;
-  int32_t request_index_ = 0;
 
   mojo::Receiver<side_panel::customize_chrome::mojom::WallpaperSearchHandler>
       receiver_;
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler_unittest.cc b/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler_unittest.cc
index cea6e952..e9dbe33 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler_unittest.cc
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_handler_unittest.cc
@@ -61,7 +61,7 @@
       : WallpaperSearchBackgroundManager(profile) {}
   MOCK_METHOD2(SelectLocalBackgroundImage,
                void(const base::Token&, const SkBitmap&));
-  MOCK_METHOD0(SaveCurrentBackgroundToHistory, void());
+  MOCK_METHOD0(SaveCurrentBackgroundToHistory, absl::optional<base::Token>());
 };
 
 std::unique_ptr<TestingProfile> MakeTestingProfile(
@@ -499,7 +499,11 @@
   EXPECT_EQ(321, quality.request_latency_ms());
   ASSERT_EQ(2, quality.images_quality_size());
   EXPECT_EQ(111, quality.images_quality(0).image_id());
+  EXPECT_FALSE(quality.images_quality(0).previewed());
+  EXPECT_FALSE(quality.images_quality(0).selected());
   EXPECT_EQ(222, quality.images_quality(1).image_id());
+  EXPECT_FALSE(quality.images_quality(1).previewed());
+  EXPECT_FALSE(quality.images_quality(1).selected());
 }
 
 TEST_F(WallpaperSearchHandlerTest, GetWallpaperSearchResults_MultipleRequests) {
@@ -969,6 +973,11 @@
   EXPECT_EQ(bitmap.getColor(0, 0), bitmap2.getColor(0, 0));
   EXPECT_EQ(token, images[1]->id);
 
+  // Simulate current background is saved to history.
+  ON_CALL(mock_wallpaper_search_background_manager(),
+          SaveCurrentBackgroundToHistory)
+      .WillByDefault(Return(absl::make_optional(token)));
+
   // Quality logs on destruction.
   handler.reset();
   EXPECT_EQ(123, quality.session_id());
@@ -977,5 +986,9 @@
   EXPECT_EQ(321, quality.request_latency_ms());
   ASSERT_EQ(2, quality.images_quality_size());
   EXPECT_EQ(111, quality.images_quality(0).image_id());
+  EXPECT_FALSE(quality.images_quality(0).previewed());
+  EXPECT_FALSE(quality.images_quality(0).selected());
   EXPECT_EQ(222, quality.images_quality(1).image_id());
+  EXPECT_TRUE(quality.images_quality(1).previewed());
+  EXPECT_TRUE(quality.images_quality(1).selected());
 }
diff --git a/chrome/browser/webauthn/passkey_model_factory.cc b/chrome/browser/webauthn/passkey_model_factory.cc
index f7092d79b..16d53194 100644
--- a/chrome/browser/webauthn/passkey_model_factory.cc
+++ b/chrome/browser/webauthn/passkey_model_factory.cc
@@ -7,8 +7,11 @@
 #include "base/check.h"
 #include "base/feature_list.h"
 #include "base/no_destructor.h"
+#include "chrome/browser/password_manager/affiliations_prefetcher_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/sync/model_type_store_service_factory.h"
+#include "components/password_manager/core/browser/affiliation/affiliations_prefetcher.h"
+#include "components/password_manager/core/browser/features/password_features.h"
 #include "components/sync/base/features.h"
 #include "components/sync/model/model_type_store.h"
 #include "components/sync/model/model_type_store_service.h"
@@ -34,6 +37,10 @@
               .WithGuest(ProfileSelection::kRedirectedToOriginal)
               .Build()) {
   DependsOn(ModelTypeStoreServiceFactory::GetInstance());
+  if (base::FeatureList::IsEnabled(
+          password_manager::features::kPasskeysPrefetchAffiliations)) {
+    DependsOn(AffiliationsPrefetcherFactory::GetInstance());
+  }
 }
 
 PasskeyModelFactory::~PasskeyModelFactory() = default;
@@ -41,9 +48,14 @@
 std::unique_ptr<KeyedService>
 PasskeyModelFactory::BuildServiceInstanceForBrowserContext(
     content::BrowserContext* context) const {
+  Profile* profile = Profile::FromBrowserContext(context);
   DCHECK(base::FeatureList::IsEnabled(syncer::kSyncWebauthnCredentials));
-  return std::make_unique<webauthn::PasskeySyncBridge>(
-      ModelTypeStoreServiceFactory::GetForProfile(
-          Profile::FromBrowserContext(context))
-          ->GetStoreFactory());
+  auto sync_bridge = std::make_unique<webauthn::PasskeySyncBridge>(
+      ModelTypeStoreServiceFactory::GetForProfile(profile)->GetStoreFactory());
+  if (base::FeatureList::IsEnabled(
+          password_manager::features::kPasskeysPrefetchAffiliations)) {
+    AffiliationsPrefetcherFactory::GetForProfile(profile)->RegisterPasskeyModel(
+        sync_bridge.get());
+  }
+  return sync_bridge;
 }
diff --git a/chrome/browser/webid/federated_identity_account_keyed_permission_context.cc b/chrome/browser/webid/federated_identity_account_keyed_permission_context.cc
index e377dfd..e66ad0f 100644
--- a/chrome/browser/webid/federated_identity_account_keyed_permission_context.cc
+++ b/chrome/browser/webid/federated_identity_account_keyed_permission_context.cc
@@ -146,16 +146,16 @@
   std::string key = BuildKey(relying_party_requester, relying_party_embedder,
                              identity_provider);
   const auto object = GetGrantedObject(relying_party_requester, key);
-  // TODO(crbug.com/1311268): If the provided `account_id` does not match the
-  // one we used when granting the permission, early return will leave an entry
-  // in the storage that cannot be removed afterwards.
   if (!object)
     return;
 
   base::Value::Dict new_object = object->value.Clone();
   base::Value::List* account_ids = new_object.FindList(kAccountIdsKey);
-  if (account_ids)
-    account_ids->EraseValue(base::Value(account_id));
+  if (account_ids) {
+    if (!account_ids->EraseValue(base::Value(account_id))) {
+      account_ids->clear();
+    }
+  }
 
   // Remove the permission object if there is no account left.
   if (!account_ids || account_ids->size() == 0) {
diff --git a/chrome/browser/webid/federated_identity_account_keyed_permission_context.h b/chrome/browser/webid/federated_identity_account_keyed_permission_context.h
index 2e9af47..ba54850 100644
--- a/chrome/browser/webid/federated_identity_account_keyed_permission_context.h
+++ b/chrome/browser/webid/federated_identity_account_keyed_permission_context.h
@@ -52,8 +52,11 @@
                        const url::Origin& identity_provider,
                        const std::string& account_id);
 
-  // Revokes previously-granted permission for the (relying_party_requester,
-  // relying_party_embedder, identity_provider, account_id) tuple.
+  // Revokes previously-granted permission for the (`relying_party_requester`,
+  // `relying_party_embedder`, `identity_provider`, `account_id`) tuple. If the
+  // `account_id` is not found, we revoke all accounts associated with the
+  // triple (`relying_party_requester`, `relying_party_embedder`,
+  // `identity_provider`).
   void RevokePermission(const url::Origin& relying_party_requester,
                         const url::Origin& relying_party_embedder,
                         const url::Origin& identity_provider,
diff --git a/chrome/browser/webid/federated_identity_account_keyed_permission_context_unittest.cc b/chrome/browser/webid/federated_identity_account_keyed_permission_context_unittest.cc
index 6bf9aff..9e1a3593 100644
--- a/chrome/browser/webid/federated_identity_account_keyed_permission_context_unittest.cc
+++ b/chrome/browser/webid/federated_identity_account_keyed_permission_context_unittest.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "base/memory/raw_ptr.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/content_settings/core/common/content_settings_types.h"
 #include "content/public/test/browser_task_environment.h"
@@ -16,8 +15,7 @@
 
 namespace {
 
-const char kTestIdpOriginKey[] = "identity-provider";
-
+constexpr char kTestIdpOriginKey[] = "identity-provider";
 }
 
 class FederatedIdentityAccountKeyedPermissionContextTest
@@ -273,3 +271,34 @@
   context()->GrantPermission(site, site, site, account);
   EXPECT_TRUE(context()->HasPermission(site, site, site, account));
 }
+
+TEST_F(FederatedIdentityAccountKeyedPermissionContextTest, RevokeNoMatch) {
+  constexpr char kAccountId[] = "account123";
+  const url::Origin rpRequester =
+      url::Origin::Create(GURL("https://rp.example"));
+  const url::Origin rpEmbedder =
+      url::Origin::Create(GURL("https://rp-embedder.example"));
+  const url::Origin idp = url::Origin::Create(GURL("https://idp.example"));
+
+  // Revoke will not crash if there are no previous permissions.
+  context()->RevokePermission(rpRequester, rpEmbedder, idp, kAccountId);
+
+  context()->GrantPermission(rpRequester, rpEmbedder, idp, kAccountId);
+  EXPECT_TRUE(
+      context()->HasPermission(rpRequester, rpEmbedder, idp, kAccountId));
+
+  // Revoke will remove the permission even if the account ID does not
+  // match.
+  context()->RevokePermission(rpRequester, rpEmbedder, idp, "noMatch");
+  EXPECT_FALSE(
+      context()->HasPermission(rpRequester, rpEmbedder, idp, kAccountId));
+
+  // Revoke will remove the permission when the account ID matches, but
+  // only that permission.
+  context()->GrantPermission(rpRequester, rpEmbedder, idp, kAccountId);
+  context()->GrantPermission(rpRequester, rpEmbedder, idp, "other");
+  context()->RevokePermission(rpRequester, rpEmbedder, idp, kAccountId);
+  EXPECT_FALSE(
+      context()->HasPermission(rpRequester, rpEmbedder, idp, kAccountId));
+  EXPECT_TRUE(context()->HasPermission(rpRequester, rpEmbedder, idp, "other"));
+}
diff --git a/chrome/browser/webid/federated_identity_permission_context.cc b/chrome/browser/webid/federated_identity_permission_context.cc
index ee3edb195..7f9c952d 100644
--- a/chrome/browser/webid/federated_identity_permission_context.cc
+++ b/chrome/browser/webid/federated_identity_permission_context.cc
@@ -88,8 +88,6 @@
     const url::Origin& relying_party_embedder,
     const url::Origin& identity_provider,
     const std::string& account_id) {
-  // TODO(crbug.com/1473134): ensure that a permission is revoked in this call
-  // if there is none matching the provided account id.
   sharing_context_->RevokePermission(relying_party_requester,
                                      relying_party_embedder, identity_provider,
                                      account_id);
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt
index c0e02bc..0ef014f0 100644
--- a/chrome/build/android-arm32.pgo.txt
+++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@
-chrome-android32-main-1700049589-6e2b43f8f6d82525aea02df1a320dc8c19b9966d.profdata
+chrome-android32-main-1700071120-8f540727c4a6bfba4978b720d0c21efb6bfa0178.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt
index 54a0249..ab95266d 100644
--- a/chrome/build/android-arm64.pgo.txt
+++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@
-chrome-android64-main-1700049589-3563d69c2929d6903f39816c7215ad3fda641870.profdata
+chrome-android64-main-1700071120-ae01bb1c056255c4448dba18abde33ea82b2cd5c.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 683212b..04db9c9f6 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1700049589-bf101cd4d72aa9cb7b61b8b108b0c6326783b53d.profdata
+chrome-linux-main-1700071120-0205b8fa40b5c56d9893d75542bb5c49a958a03c.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 53bb2c6..0b9bd32 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1700049589-779e1ab0797742e886418724b67f187b2850d190.profdata
+chrome-mac-main-1700071120-f26c5b62fc8ad7d95e71b19fd2c12a018f917d7d.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index 1d16c03..6e2317c 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1700049589-475f7f364a67434f834f61ef0057aedaeace19d5.profdata
+chrome-win-arm64-main-1700071120-827f9414c16941b83aee7b43355648c60256f80b.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 311c473..a17818d 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1700049589-0d9de2cc73aa9bcdc0e7bff6509d9b4704e99c41.profdata
+chrome-win32-main-1700060383-5252395bf868c375cf3799d1be99f27ef1a775e6.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index b59b6431..fc25c8cd 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1700049589-f6995d84f697238fbb39fb54fbe857780cc58f0d.profdata
+chrome-win64-main-1700071120-31e31f7c5699c2aa57dcef728a028d57df5fa21b.profdata
diff --git a/chrome/common/pepper_permission_util.cc b/chrome/common/pepper_permission_util.cc
index 3fd8543e..798462a34 100644
--- a/chrome/common/pepper_permission_util.cc
+++ b/chrome/common/pepper_permission_util.cc
@@ -22,9 +22,8 @@
 namespace {
 
 std::string HashHost(const std::string& host) {
-  const std::string id_hash = base::SHA1HashString(host);
-  DCHECK_EQ(id_hash.length(), base::kSHA1Length);
-  return base::HexEncode(id_hash.c_str(), id_hash.length());
+  return base::HexEncode(
+      base::SHA1HashSpan(base::as_bytes(base::make_span(host))));
 }
 
 bool HostIsInSet(const std::string& host, const std::set<std::string>& set) {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 1ace5f9..c398ef5 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1098,6 +1098,7 @@
         "../browser/ash/power/ml/smart_dim/smart_dim_integration_test.cc",
         "../browser/ash/screenshot_integration_test.cc",
         "../browser/ash/system_web_apps/apps/terminal_integration_test.cc",
+        "../browser/ash/web_handwriting_integration_test.cc",
         "../browser/ui/ash/app_list/app_list_integration_test.cc",
         "../browser/ui/ash/quick_settings_integration_test.cc",
         "../browser/ui/ash/shelf/shelf_integration_test.cc",
@@ -1115,6 +1116,8 @@
         sources += [ "base/chromeos/crosier/test_accounts_test.cc" ]
       }
 
+      data = [ "//chrome/test/data/chromeos/web_handwriting/" ]
+
       deps += [
         "//chrome/browser/ash:test_support",
         "//chrome/test/base/chromeos/crosier:proto",
@@ -5339,7 +5342,7 @@
         "../browser/ui/views/profiles/profile_picker_view_browsertest.cc",
         "../browser/ui/views/web_apps/web_app_integration_browsertest_mac_win_linux.cc",
       ]
-      deps += [ "../browser/enterprise/connectors/analysis:test_support" ]
+      deps += [ "../browser/enterprise/connectors/test:test_support" ]
     }
 
     if (is_chrome_branded) {
@@ -8668,6 +8671,7 @@
     deps += [
       "//chrome/browser/policy:onc",
       "//chrome/browser/policy:unit_tests",
+      "//chrome/browser/web_applications/app_service:test_support",
       "//chromeos/components/onc:onc",
       "//chromeos/crosapi/mojom",
       "//chromeos/dbus/dlp:dlp",
@@ -9106,7 +9110,7 @@
         "../common/extensions/api/system_indicator/system_indicator_handler_unittest.cc",
       ]
 
-      deps += [ "../browser/enterprise/connectors/analysis:test_support" ]
+      deps += [ "../browser/enterprise/connectors/test:test_support" ]
     }
 
     if (is_chromeos_lacros || is_chromeos_ash) {
@@ -9597,7 +9601,7 @@
 
   if (is_win || is_mac || is_linux) {
     deps += [
-      "../browser/enterprise/connectors/analysis:test_support",
+      "../browser/enterprise/connectors/test:test_support",
       "../services/system_signals:unit_tests",
     ]
   }
diff --git a/chrome/test/base/testing_browser_process.cc b/chrome/test/base/testing_browser_process.cc
index 697c7778..03e0e249 100644
--- a/chrome/test/base/testing_browser_process.cc
+++ b/chrome/test/base/testing_browser_process.cc
@@ -17,6 +17,7 @@
 #include "chrome/browser/browser_process_impl.h"
 #include "chrome/browser/download/download_request_limiter.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/browser/media/webrtc/webrtc_log_uploader.h"
 #include "chrome/browser/notifications/notification_platform_bridge.h"
 #include "chrome/browser/notifications/stub_notification_platform_bridge.h"
 #include "chrome/browser/notifications/system_notification_helper.h"
@@ -346,6 +347,10 @@
   return sb_service_.get();
 }
 
+WebRtcLogUploader* TestingBrowserProcess::webrtc_log_uploader() {
+  return webrtc_log_uploader_.get();
+}
+
 subresource_filter::RulesetService*
 TestingBrowserProcess::subresource_filter_ruleset_service() {
   return subresource_filter_ruleset_service_.get();
@@ -467,10 +472,6 @@
 #endif
 }
 
-WebRtcLogUploader* TestingBrowserProcess::webrtc_log_uploader() {
-  return nullptr;
-}
-
 network_time::NetworkTimeTracker*
 TestingBrowserProcess::network_time_tracker() {
   if (!network_time_tracker_) {
@@ -603,6 +604,11 @@
   sb_service_ = sb_service;
 }
 
+void TestingBrowserProcess::SetWebRtcLogUploader(
+    std::unique_ptr<WebRtcLogUploader> uploader) {
+  webrtc_log_uploader_ = std::move(uploader);
+}
+
 void TestingBrowserProcess::SetRulesetService(
     std::unique_ptr<subresource_filter::RulesetService> ruleset_service) {
   subresource_filter_ruleset_service_.swap(ruleset_service);
diff --git a/chrome/test/base/testing_browser_process.h b/chrome/test/base/testing_browser_process.h
index 445052f..c5734ea 100644
--- a/chrome/test/base/testing_browser_process.h
+++ b/chrome/test/base/testing_browser_process.h
@@ -170,6 +170,7 @@
   void SetMetricsService(metrics::MetricsService* metrics_service);
   void SetProfileManager(std::unique_ptr<ProfileManager> profile_manager);
   void SetSafeBrowsingService(safe_browsing::SafeBrowsingService* sb_service);
+  void SetWebRtcLogUploader(std::unique_ptr<WebRtcLogUploader> uploader);
   void SetRulesetService(
       std::unique_ptr<subresource_filter::RulesetService> ruleset_service);
   void SetSharedURLLoaderFactory(
@@ -238,6 +239,7 @@
   scoped_refptr<safe_browsing::SafeBrowsingService> sb_service_;
   std::unique_ptr<subresource_filter::RulesetService>
       subresource_filter_ruleset_service_;
+  std::unique_ptr<WebRtcLogUploader> webrtc_log_uploader_;
 
   std::unique_ptr<network_time::NetworkTimeTracker> network_time_tracker_;
 
diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc
index 648b3f3..dbec14f 100644
--- a/chrome/test/base/ui_test_utils.cc
+++ b/chrome/test/base/ui_test_utils.cc
@@ -57,6 +57,7 @@
 #include "content/public/browser/download_manager.h"
 #include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
@@ -198,6 +199,22 @@
       scoped_observation_{this};
 };
 
+// Helper class to notify AllTabsObserver that a WebContents has been destroyed.
+class WebContentsDestructionObserver : public content::WebContentsObserver {
+ public:
+  WebContentsDestructionObserver(base::OnceClosure destruction_cb,
+                                 content::WebContents* web_contents)
+      : WebContentsObserver(web_contents),
+        destruction_cb_(std::move(destruction_cb)) {}
+  ~WebContentsDestructionObserver() override = default;
+
+  // WebContentsObserver
+  void WebContentsDestroyed() override { std::move(destruction_cb_).Run(); }
+
+ private:
+  base::OnceClosure destruction_cb_;
+};
+
 }  // namespace
 
 bool GetCurrentTabTitle(const Browser* browser, std::u16string* title) {
@@ -506,25 +523,151 @@
   }
 }
 
-UrlLoadObserver::UrlLoadObserver(const GURL& url,
-                                 const content::NotificationSource& source)
-    : WindowedNotificationObserver(content::NOTIFICATION_LOAD_STOP, source),
-      url_(url) {
+// It would be nice to `AddAllBrowsers()` here, but we have to wait until our
+// subclass is constructed to `ProcessOneBrowser()`.  We can't put it off
+// until `Wait()` since we need to watch for anything that happens between now
+// and then.
+AllTabsObserver::AllTabsObserver() = default;
+
+AllTabsObserver::~AllTabsObserver() {
+  BrowserList::RemoveObserver(this);
+  // We're tracking all browsers, so remove us from all of all of them.
+  for (Browser* browser : *BrowserList::GetInstance()) {
+    browser->tab_strip_model()->RemoveObserver(this);
+  }
 }
 
-UrlLoadObserver::~UrlLoadObserver() {}
+void AllTabsObserver::AddAllBrowsers() {
+  added_all_browsers_ = true;
+  BrowserList::AddObserver(this);
+  for (Browser* browser : *BrowserList::GetInstance()) {
+    AddBrowser(browser);
+  }
+}
 
-void UrlLoadObserver::Observe(
-    int type,
-    const content::NotificationSource& source,
-    const content::NotificationDetails& details) {
-  NavigationController* controller =
-      content::Source<NavigationController>(source).ptr();
-  NavigationEntry* entry = controller->GetVisibleEntry();
-  if (!entry || entry->GetVirtualURL() != url_)
+void AllTabsObserver::Wait() {
+  // For subclasses that can detect if their condition is met without
+  // necessarily needing to watch for transitions, we could wait until now to
+  // call `AddAllBrowsers()` if it hasn't happened yet.
+  CHECK(added_all_browsers_)
+      << "Subclasses must call `AddAllBrowsers()` during construction";
+
+  if (!condition_met_) {
+    run_loop_ = std::make_unique<base::RunLoop>();
+    run_loop_->Run();
+    run_loop_.reset();
+  }
+  EXPECT_TRUE(condition_met_);
+}
+
+// impls should call this to tell us to stop waiting.
+void AllTabsObserver::ConditionMet() {
+  condition_met_ = true;
+  if (run_loop_) {
+    run_loop_->Quit();
+  }
+}
+
+void AllTabsObserver::OnTabStripModelChanged(
+    TabStripModel* tab_strip_model,
+    const TabStripModelChange& change,
+    const TabStripSelectionChange& selection) {
+  if (change.type() != TabStripModelChange::kInserted) {
     return;
+  }
 
-  WindowedNotificationObserver::Observe(type, source, details);
+  AddWebContents(change.GetInsert()->contents[0].contents.get());
+}
+
+void AllTabsObserver::OnBrowserAdded(Browser* browser) {
+  AddBrowser(browser);
+}
+
+void AllTabsObserver::AddBrowser(const Browser* browser) {
+  browser->tab_strip_model()->AddObserver(this);
+  // Enumerate all WebContents in this browser, and add a WebContentsObserver
+  // for it.
+  for (int index = 0; index < browser->tab_strip_model()->count(); index++) {
+    auto* web_contents = browser->tab_strip_model()->GetWebContentsAt(index);
+    AddWebContents(web_contents);
+  }
+}
+
+void AllTabsObserver::AddWebContents(content::WebContents* web_contents) {
+  // If the condition is already met, then don't bother.
+  if (condition_met_) {
+    return;
+  }
+
+  auto observer = ProcessOneContents(web_contents);
+  if (observer) {
+    // Store both the subclass's observer and our own with this WebContents.
+    // We'll handle cleaning them both up on destruction.  It's okay if our
+    // subclass does not create an observer, but does notify us to stop waiting
+    // before returning.
+    tab_navigation_map_[web_contents].subclass_observer = std::move(observer);
+    tab_navigation_map_[web_contents].destruction_observer =
+        std::make_unique<WebContentsDestructionObserver>(
+            base::BindOnce(&AllTabsObserver::OnWebContentsDestroyed,
+                           base::Unretained(this),
+                           base::Unretained(web_contents)),
+            web_contents);
+  }
+}
+
+// called by our destruction observers
+void AllTabsObserver::OnWebContentsDestroyed(WebContents* web_contents) {
+  auto iter = tab_navigation_map_.find(web_contents);
+  CHECK(iter != tab_navigation_map_.end());
+  // This clears both our observer and the one created by our subclass.
+  tab_navigation_map_.erase(iter);
+}
+
+AllTabsObserver::TabNavigationMapEntry::TabNavigationMapEntry() = default;
+AllTabsObserver::TabNavigationMapEntry::~TabNavigationMapEntry() = default;
+
+UrlLoadObserver::UrlLoadObserver(const GURL& url) : url_(url) {
+  AddAllBrowsers();
+}
+
+UrlLoadObserver::UrlLoadObserver(
+    const GURL& url,
+    const content::NotificationSource& unused_source)
+    : UrlLoadObserver(url) {
+  // For whatever reason, CHECK_EQ doesn't pick up the overloaded == .
+  CHECK(unused_source == content::NotificationService::AllSources())
+      << "does not support filtering by source";
+}
+
+UrlLoadObserver::~UrlLoadObserver() = default;
+
+std::unique_ptr<base::CheckedObserver> UrlLoadObserver::ProcessOneContents(
+    WebContents* web_contents) {
+  return std::make_unique<LoadStopObserver>(this, web_contents);
+}
+
+void UrlLoadObserver::OnDidStopLoading(WebContents* web_contents) {
+  NavigationController& controller = web_contents->GetController();
+  NavigationEntry* entry = controller.GetVisibleEntry();
+  if (!entry || entry->GetVirtualURL() != url_) {
+    return;
+  }
+
+  // Record the first match.
+  if (!web_contents_) {
+    web_contents_ = web_contents;
+  }
+  ConditionMet();
+}
+
+UrlLoadObserver::LoadStopObserver::LoadStopObserver(UrlLoadObserver* owner,
+                                                    WebContents* web_contents)
+    : WebContentsObserver(web_contents), owner_(owner) {}
+
+UrlLoadObserver::LoadStopObserver::~LoadStopObserver() = default;
+
+void UrlLoadObserver::LoadStopObserver::DidStopLoading() {
+  owner_->OnDidStopLoading(web_contents());
 }
 
 HistoryEnumerator::HistoryEnumerator(Profile* profile) {
diff --git a/chrome/test/base/ui_test_utils.h b/chrome/test/base/ui_test_utils.h
index 3cef270e..7d9d508e 100644
--- a/chrome/test/base/ui_test_utils.h
+++ b/chrome/test/base/ui_test_utils.h
@@ -206,25 +206,148 @@
                 int* value_size,
                 std::string* value);
 
-// Notification observer which waits for navigation events and blocks until
-// a specific URL is loaded. The URL must be an exact match.
-class UrlLoadObserver : public content::WindowedNotificationObserver {
+// Utility class to watch all existing and added tabs, until some interesting
+// thing has happened.  Subclasses get to decide what they consider to be
+// interesting.  In practice, usage is like this:
+//
+// - Subclass `AllTabsObserver`
+// - Override `ProcessOneWebContents()` to check for the interesting thing.
+// - Optionally return a `WebContentsObserver` that will watch for the
+//   interesting thing for this WebContents.
+// - Eventually call `ConditionMet()` to indicate that the interesting thing has
+//   happened, and no further waiting is needed.
+//
+// Users of this class just call `Wait()` at most once.
+class AllTabsObserver : public TabStripModelObserver,
+                        public BrowserListObserver {
  public:
-  // Register to listen for notifications of the given type from either a
-  // specific source, or from all sources if |source| is
-  // NotificationService::AllSources().
-  UrlLoadObserver(const GURL& url, const content::NotificationSource& source);
-  UrlLoadObserver(const UrlLoadObserver&) = delete;
-  UrlLoadObserver& operator=(const UrlLoadObserver&) = delete;
-  ~UrlLoadObserver() override;
+  AllTabsObserver(const AllTabsObserver&) = delete;
+  AllTabsObserver& operator=(const AllTabsObserver&) = delete;
 
-  // content::NotificationObserver:
-  void Observe(int type,
-               const content::NotificationSource& source,
-               const content::NotificationDetails& details) override;
+  ~AllTabsObserver() override;
+
+  // Waits until whatever interesting thing we're waiting for has happened.
+  // Will return immediately if it's already happened.
+  void Wait();
+
+ protected:
+  AllTabsObserver();
+
+  // Will be called for every tab's WebContents, including ones that exist when
+  // this class is constructed and any that are created afterwards until
+  // destruction or until `ConditionMet()` is called.
+  //
+  // This may choose not to return an observer if there's no need to watch this
+  // contents.  It may also call `ConditionMet()` before returning, presumably
+  // because the new contents already matches whatever condition our subclass is
+  // checking for.  In that case, it will presumably not bother to return an
+  // observer for the new contents.
+  //
+  // These will be deleted before `this` is deleted, so it's okay to have the
+  // observers hold raw_ptrs back to `this`.
+  virtual std::unique_ptr<base::CheckedObserver> ProcessOneContents(
+      content::WebContents* web_contents) = 0;
+
+  // Add all tabs from all browsers.  Must be called by the subclass ctor.
+  void AddAllBrowsers();
+
+  // Called by our subclass to let us know that whatever it's trying to wait for
+  // has happened.  May be called at any time, including during a call to
+  // `CreateObserverIfNeeded()`.  May be called more than once, though
+  // calls will be ignored.
+  void ConditionMet();
 
  private:
+  // Record for every tab we're watching.
+  struct TabNavigationMapEntry {
+    TabNavigationMapEntry();
+    ~TabNavigationMapEntry();
+
+    // Provided by the subclass to do whatever it does.
+    std::unique_ptr<base::CheckedObserver> subclass_observer;
+    // Provided by us to clean up properly.
+    std::unique_ptr<base::CheckedObserver> destruction_observer;
+  };
+  using TabNavigationMap =
+      std::map<const content::WebContents*, TabNavigationMapEntry>;
+
+  // Add all tabs from `browser`, and start watching for changes.
+  void AddBrowser(const Browser* browser);
+
+  // TabStripModelObserver:
+  void OnTabStripModelChanged(
+      TabStripModel* tab_strip_model,
+      const TabStripModelChange& change,
+      const TabStripSelectionChange& selection) override;
+
+  // BrowserListObserver
+  void OnBrowserAdded(Browser* browser) override;
+
+  // Called for every WebContents.  Notifies the subclass, and sets up observers
+  // if needed.
+  void AddWebContents(content::WebContents* web_contents);
+
+  // Called by our destruction observers.
+  void OnWebContentsDestroyed(content::WebContents* web_contents);
+
+  // Map of how many times each tab has navigated since |this| was created.
+  TabNavigationMap tab_navigation_map_;
+
+  // True if WaitForNavigations has been called, until
+  // |num_navigations_to_wait_for_| have been observed.
+  bool condition_met_ = false;
+
+  // Flag to make sure that subclasses call `AddAllBrowsers()`.
+  bool added_all_browsers_ = false;
+
+  std::unique_ptr<base::RunLoop> run_loop_;
+};
+
+// Notification observer which waits for navigation events and blocks until
+// a specific URL is loaded. The URL must be an exact match.
+class UrlLoadObserver : public AllTabsObserver {
+ public:
+  // `url` is the URL to look for.
+  explicit UrlLoadObserver(const GURL& url);
+
+  // Temporary constructor while callsites are updated.  `unused_source` must be
+  // `AllSources()`.  Do not use this for new code -- use the one-argument
+  // constructor instead.
+  UrlLoadObserver(const GURL& url,
+                  const content::NotificationSource& unused_source);
+  ~UrlLoadObserver() override;
+
+  // Returns the WebContents which navigated to `url`.
+  content::WebContents* web_contents() const { return web_contents_; }
+
+ protected:
+  // Helper class to watch for DidStopLoading on one WebContents and relay it to
+  // the UrlLoadObserver that created us.
+  class LoadStopObserver : public content::WebContentsObserver {
+   public:
+    LoadStopObserver(UrlLoadObserver* owner,
+                     content::WebContents* web_contents);
+    ~LoadStopObserver() override;
+
+    // WebContentsObserver
+    void DidStopLoading() override;
+
+   private:
+    raw_ptr<UrlLoadObserver> owner_ = nullptr;
+  };
+
+  // AllTabsObserver
+  std::unique_ptr<base::CheckedObserver> ProcessOneContents(
+      content::WebContents* web_contents) override;
+
+  // Called by `LoadStopObserver` when a WebContents DidStopLoading().
+  void OnDidStopLoading(content::WebContents* web_contents);
+
+ private:
+  friend class LoadStopObserver;
+
   GURL url_;
+  raw_ptr<content::WebContents> web_contents_ = nullptr;
 };
 
 // A helper that will wait until a tab is added to a specific Browser.
diff --git a/chrome/test/data/chromeos/web_handwriting/web_handwriting_recognition.html b/chrome/test/data/chromeos/web_handwriting/web_handwriting_recognition.html
new file mode 100644
index 0000000..fc056967
--- /dev/null
+++ b/chrome/test/data/chromeos/web_handwriting/web_handwriting_recognition.html
@@ -0,0 +1,112 @@
+<!-- Copyright 2021 The ChromiumOS Authors
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<!DOCTYPE html>
+
+<title>Web Handwriting Recognition Test</title>
+<h1>Drawing - English and Gesture</h1>
+
+<script>
+    const kTestHandwritingABC = [[{"x":143,"y":170,"t":4571},{"x":142,"y":164,"t":4612},{"x":142,"y":163,"t":4614},{"x":141,"y":162,"t":4617},{"x":141,"y":162,"t":4619},{"x":141,"y":161,"t":4622},{"x":141,"y":159,"t":4629},{"x":141,"y":159,"t":4632},{"x":141,"y":158,"t":4634},{"x":141,"y":158,"t":4637},{"x":140,"y":156,"t":4644},{"x":140,"y":156,"t":4647},{"x":140,"y":155,"t":4649},{"x":140,"y":155,"t":4652},{"x":140,"y":154,"t":4654},{"x":139,"y":153,"t":4657},{"x":139,"y":153,"t":4659},{"x":139,"y":152,"t":4662},{"x":139,"y":151,"t":4664},{"x":138,"y":151,"t":4667},{"x":138,"y":150,"t":4669},{"x":138,"y":149,"t":4671},{"x":137,"y":149,"t":4674},{"x":137,"y":148,"t":4677},{"x":136,"y":147,"t":4679},{"x":136,"y":147,"t":4682},{"x":135,"y":146,"t":4684},{"x":135,"y":146,"t":4687},{"x":134,"y":146,"t":4689},{"x":133,"y":145,"t":4691},{"x":133,"y":145,"t":4694},{"x":132,"y":145,"t":4696},{"x":131,"y":144,"t":4699},{"x":130,"y":144,"t":4701},{"x":129,"y":144,"t":4704},{"x":129,"y":145,"t":4706},{"x":128,"y":145,"t":4709},{"x":127,"y":145,"t":4711},{"x":126,"y":146,"t":4714},{"x":125,"y":146,"t":4716},{"x":124,"y":147,"t":4719},{"x":123,"y":148,"t":4721},{"x":122,"y":149,"t":4724},{"x":121,"y":150,"t":4726},{"x":120,"y":151,"t":4729},{"x":119,"y":153,"t":4731},{"x":118,"y":154,"t":4734},{"x":116,"y":156,"t":4736},{"x":115,"y":157,"t":4739},{"x":114,"y":159,"t":4741},{"x":113,"y":161,"t":4744},{"x":111,"y":163,"t":4746},{"x":110,"y":165,"t":4749},{"x":109,"y":167,"t":4751},{"x":108,"y":169,"t":4754},{"x":107,"y":171,"t":4756},{"x":106,"y":174,"t":4759},{"x":105,"y":176,"t":4761},{"x":104,"y":179,"t":4764},{"x":103,"y":181,"t":4766},{"x":102,"y":184,"t":4769},{"x":101,"y":186,"t":4771},{"x":101,"y":189,"t":4774},{"x":100,"y":192,"t":4776},{"x":99,"y":195,"t":4779},{"x":99,"y":198,"t":4781},{"x":98,"y":201,"t":4784},{"x":97,"y":204,"t":4786},{"x":97,"y":208,"t":4789},{"x":96,"y":211,"t":4791},{"x":95,"y":215,"t":4794},{"x":95,"y":218,"t":4796},{"x":94,"y":222,"t":4799},{"x":94,"y":226,"t":4801},{"x":93,"y":230,"t":4804},{"x":92,"y":233,"t":4806},{"x":92,"y":237,"t":4809},{"x":91,"y":241,"t":4811},{"x":91,"y":244,"t":4814},{"x":90,"y":248,"t":4816},{"x":90,"y":251,"t":4818},{"x":90,"y":254,"t":4821},{"x":90,"y":257,"t":4824},{"x":89,"y":260,"t":4826},{"x":89,"y":262,"t":4828},{"x":90,"y":264,"t":4831},{"x":90,"y":266,"t":4833},{"x":90,"y":268,"t":4836},{"x":91,"y":269,"t":4838},{"x":91,"y":270,"t":4841},{"x":92,"y":271,"t":4843},{"x":93,"y":272,"t":4846},{"x":94,"y":272,"t":4848},{"x":95,"y":273,"t":4851},{"x":96,"y":273,"t":4853},{"x":97,"y":273,"t":4856},{"x":98,"y":272,"t":4858},{"x":99,"y":272,"t":4861},{"x":100,"y":271,"t":4863},{"x":102,"y":270,"t":4866},{"x":103,"y":270,"t":4868},{"x":104,"y":269,"t":4871},{"x":105,"y":268,"t":4873},{"x":107,"y":266,"t":4876},{"x":108,"y":265,"t":4878},{"x":109,"y":264,"t":4881},{"x":110,"y":262,"t":4883},{"x":112,"y":260,"t":4886},{"x":113,"y":259,"t":4888},{"x":114,"y":257,"t":4891},{"x":116,"y":255,"t":4893},{"x":117,"y":253,"t":4896},{"x":118,"y":251,"t":4898},{"x":119,"y":249,"t":4901},{"x":120,"y":247,"t":4903},{"x":121,"y":245,"t":4906},{"x":122,"y":243,"t":4908},{"x":123,"y":240,"t":4911},{"x":124,"y":238,"t":4913},{"x":126,"y":236,"t":4916},{"x":127,"y":233,"t":4918},{"x":128,"y":231,"t":4921},{"x":129,"y":228,"t":4923},{"x":130,"y":225,"t":4926},{"x":131,"y":223,"t":4928},{"x":132,"y":220,"t":4931},{"x":133,"y":217,"t":4933},{"x":134,"y":214,"t":4936},{"x":135,"y":211,"t":4938},{"x":136,"y":208,"t":4941},{"x":137,"y":204,"t":4943},{"x":138,"y":201,"t":4946},{"x":139,"y":198,"t":4948},{"x":140,"y":194,"t":4951},{"x":141,"y":191,"t":4953},{"x":142,"y":188,"t":4956},{"x":142,"y":185,"t":4958},{"x":143,"y":181,"t":4961},{"x":144,"y":178,"t":4963},{"x":145,"y":175,"t":4966},{"x":146,"y":172,"t":4968},{"x":147,"y":170,"t":4970},{"x":147,"y":167,"t":4973},{"x":148,"y":165,"t":4976},{"x":149,"y":163,"t":4978},{"x":150,"y":161,"t":4980},{"x":150,"y":159,"t":4983},{"x":151,"y":158,"t":4985},{"x":151,"y":157,"t":4988},{"x":152,"y":155,"t":4990},{"x":152,"y":154,"t":4993},{"x":153,"y":154,"t":4995},{"x":153,"y":153,"t":4998},{"x":153,"y":153,"t":5000},{"x":153,"y":152,"t":5003},{"x":153,"y":152,"t":5005},{"x":153,"y":152,"t":5008},{"x":153,"y":152,"t":5010},{"x":153,"y":152,"t":5013},{"x":153,"y":152,"t":5015},{"x":153,"y":153,"t":5018},{"x":153,"y":153,"t":5020},{"x":152,"y":154,"t":5023},{"x":152,"y":155,"t":5025},{"x":152,"y":156,"t":5028},{"x":151,"y":157,"t":5030},{"x":151,"y":159,"t":5033},{"x":151,"y":160,"t":5035},{"x":150,"y":161,"t":5038},{"x":150,"y":163,"t":5040},{"x":149,"y":165,"t":5043},{"x":149,"y":167,"t":5045},{"x":148,"y":169,"t":5048},{"x":148,"y":171,"t":5050},{"x":147,"y":173,"t":5053},{"x":147,"y":175,"t":5055},{"x":147,"y":177,"t":5058},{"x":146,"y":180,"t":5060},{"x":146,"y":182,"t":5063},{"x":146,"y":185,"t":5065},{"x":146,"y":188,"t":5068},{"x":145,"y":190,"t":5070},{"x":145,"y":193,"t":5073},{"x":145,"y":196,"t":5075},{"x":145,"y":199,"t":5078},{"x":145,"y":202,"t":5080},{"x":145,"y":205,"t":5083},{"x":144,"y":208,"t":5085},{"x":144,"y":211,"t":5088},{"x":144,"y":213,"t":5090},{"x":144,"y":216,"t":5092},{"x":144,"y":219,"t":5095},{"x":144,"y":221,"t":5097},{"x":145,"y":224,"t":5100},{"x":145,"y":226,"t":5103},{"x":145,"y":228,"t":5105},{"x":145,"y":230,"t":5107},{"x":146,"y":232,"t":5110},{"x":146,"y":234,"t":5112},{"x":147,"y":235,"t":5115},{"x":147,"y":237,"t":5117},{"x":148,"y":238,"t":5120},{"x":148,"y":240,"t":5122},{"x":149,"y":241,"t":5125},{"x":150,"y":242,"t":5127},{"x":150,"y":243,"t":5130},{"x":151,"y":244,"t":5132},{"x":152,"y":245,"t":5135},{"x":153,"y":245,"t":5137},{"x":153,"y":246,"t":5140},{"x":154,"y":247,"t":5142},{"x":154,"y":247,"t":5145},{"x":155,"y":248,"t":5147},{"x":156,"y":248,"t":5150},{"x":156,"y":248,"t":5152},{"x":157,"y":249,"t":5155},{"x":157,"y":249,"t":5157},{"x":158,"y":249,"t":5160},{"x":158,"y":249,"t":5162},{"x":158,"y":249,"t":5165},{"x":159,"y":249,"t":5167},{"x":159,"y":249,"t":5170},{"x":160,"y":249,"t":5172},{"x":160,"y":249,"t":5175},{"x":161,"y":249,"t":5177},{"x":161,"y":249,"t":5180},{"x":162,"y":248,"t":5182},{"x":162,"y":248,"t":5185},{"x":163,"y":247,"t":5187},{"x":163,"y":246,"t":5190},{"x":164,"y":246,"t":5192},{"x":164,"y":245,"t":5195},{"x":165,"y":244,"t":5197},{"x":165,"y":242,"t":5200},{"x":166,"y":241,"t":5202},{"x":166,"y":239,"t":5205}],[{"x":198,"y":99,"t":5698},{"x":197,"y":105,"t":5710},{"x":197,"y":106,"t":5713},{"x":197,"y":107,"t":5715},{"x":197,"y":108,"t":5718},{"x":196,"y":128,"t":5740},{"x":196,"y":130,"t":5743},{"x":196,"y":133,"t":5745},{"x":196,"y":136,"t":5748},{"x":197,"y":139,"t":5750},{"x":197,"y":142,"t":5753},{"x":197,"y":145,"t":5755},{"x":197,"y":154,"t":5763},{"x":197,"y":158,"t":5765},{"x":197,"y":161,"t":5768},{"x":197,"y":165,"t":5770},{"x":197,"y":168,"t":5773},{"x":197,"y":172,"t":5775},{"x":197,"y":176,"t":5778},{"x":197,"y":180,"t":5780},{"x":197,"y":184,"t":5783},{"x":197,"y":188,"t":5785},{"x":197,"y":192,"t":5788},{"x":197,"y":196,"t":5790},{"x":196,"y":200,"t":5793},{"x":196,"y":204,"t":5795},{"x":196,"y":207,"t":5798},{"x":196,"y":211,"t":5800},{"x":196,"y":215,"t":5803},{"x":196,"y":219,"t":5805},{"x":196,"y":222,"t":5808},{"x":195,"y":226,"t":5810},{"x":195,"y":229,"t":5813},{"x":195,"y":232,"t":5815},{"x":195,"y":236,"t":5817},{"x":195,"y":239,"t":5820},{"x":194,"y":242,"t":5822},{"x":194,"y":244,"t":5825},{"x":194,"y":247,"t":5827},{"x":194,"y":250,"t":5830},{"x":193,"y":252,"t":5832},{"x":193,"y":254,"t":5835},{"x":193,"y":256,"t":5837},{"x":193,"y":258,"t":5840},{"x":192,"y":260,"t":5842},{"x":192,"y":261,"t":5845},{"x":192,"y":262,"t":5847},{"x":192,"y":264,"t":5850},{"x":192,"y":264,"t":5852},{"x":191,"y":265,"t":5855},{"x":191,"y":266,"t":5857},{"x":191,"y":266,"t":5860},{"x":191,"y":266,"t":5862},{"x":190,"y":266,"t":5865},{"x":190,"y":266,"t":5867},{"x":190,"y":266,"t":5870},{"x":189,"y":266,"t":5872},{"x":189,"y":266,"t":5875},{"x":189,"y":265,"t":5877},{"x":188,"y":264,"t":5880},{"x":188,"y":263,"t":5882},{"x":188,"y":262,"t":5885},{"x":187,"y":261,"t":5887},{"x":187,"y":259,"t":5890},{"x":187,"y":258,"t":5892},{"x":186,"y":256,"t":5895},{"x":186,"y":254,"t":5897},{"x":186,"y":252,"t":5900},{"x":185,"y":250,"t":5902},{"x":185,"y":248,"t":5905},{"x":185,"y":246,"t":5907},{"x":185,"y":244,"t":5910},{"x":185,"y":241,"t":5912},{"x":185,"y":239,"t":5915},{"x":185,"y":237,"t":5917},{"x":185,"y":234,"t":5920},{"x":185,"y":232,"t":5922},{"x":185,"y":230,"t":5925},{"x":185,"y":227,"t":5927},{"x":186,"y":225,"t":5930},{"x":186,"y":223,"t":5932},{"x":186,"y":221,"t":5935},{"x":187,"y":219,"t":5937},{"x":187,"y":217,"t":5940},{"x":188,"y":215,"t":5942},{"x":189,"y":213,"t":5944},{"x":189,"y":211,"t":5947},{"x":190,"y":210,"t":5950},{"x":191,"y":208,"t":5952},{"x":192,"y":206,"t":5954},{"x":192,"y":205,"t":5957},{"x":193,"y":204,"t":5959},{"x":194,"y":202,"t":5962},{"x":195,"y":201,"t":5965},{"x":195,"y":200,"t":5967},{"x":196,"y":199,"t":5969},{"x":197,"y":198,"t":5972},{"x":198,"y":197,"t":5974},{"x":199,"y":196,"t":5977},{"x":200,"y":195,"t":5979},{"x":201,"y":194,"t":5982},{"x":202,"y":193,"t":5984},{"x":203,"y":192,"t":5987},{"x":204,"y":192,"t":5989},{"x":205,"y":191,"t":5992},{"x":207,"y":191,"t":5994},{"x":208,"y":190,"t":5997},{"x":209,"y":190,"t":5999},{"x":211,"y":190,"t":6002},{"x":212,"y":189,"t":6004},{"x":213,"y":189,"t":6007},{"x":214,"y":189,"t":6009},{"x":216,"y":189,"t":6012},{"x":217,"y":189,"t":6014},{"x":218,"y":189,"t":6017},{"x":220,"y":189,"t":6019},{"x":221,"y":189,"t":6022},{"x":223,"y":189,"t":6024},{"x":224,"y":189,"t":6027},{"x":225,"y":189,"t":6029},{"x":227,"y":190,"t":6032},{"x":228,"y":190,"t":6034},{"x":229,"y":191,"t":6037},{"x":231,"y":191,"t":6039},{"x":232,"y":192,"t":6042},{"x":233,"y":192,"t":6044},{"x":234,"y":193,"t":6047},{"x":234,"y":194,"t":6049},{"x":235,"y":195,"t":6052},{"x":236,"y":196,"t":6054},{"x":237,"y":197,"t":6057},{"x":237,"y":198,"t":6059},{"x":238,"y":199,"t":6062},{"x":238,"y":200,"t":6064},{"x":238,"y":202,"t":6067},{"x":239,"y":203,"t":6069},{"x":239,"y":205,"t":6072},{"x":239,"y":207,"t":6074},{"x":239,"y":208,"t":6077},{"x":239,"y":210,"t":6079},{"x":239,"y":212,"t":6082},{"x":239,"y":214,"t":6084},{"x":238,"y":216,"t":6087},{"x":238,"y":218,"t":6089},{"x":238,"y":220,"t":6092},{"x":237,"y":222,"t":6094},{"x":237,"y":224,"t":6096},{"x":236,"y":226,"t":6099},{"x":236,"y":228,"t":6101},{"x":235,"y":229,"t":6104},{"x":234,"y":231,"t":6106},{"x":233,"y":233,"t":6109},{"x":233,"y":235,"t":6111},{"x":232,"y":236,"t":6114},{"x":231,"y":238,"t":6116},{"x":230,"y":239,"t":6119},{"x":229,"y":241,"t":6121},{"x":227,"y":242,"t":6124},{"x":226,"y":244,"t":6126},{"x":225,"y":245,"t":6129},{"x":224,"y":246,"t":6131},{"x":222,"y":248,"t":6134},{"x":221,"y":249,"t":6136},{"x":220,"y":250,"t":6139},{"x":219,"y":251,"t":6141},{"x":217,"y":252,"t":6144},{"x":216,"y":253,"t":6146},{"x":215,"y":254,"t":6149},{"x":214,"y":255,"t":6151},{"x":212,"y":255,"t":6154},{"x":211,"y":256,"t":6156},{"x":210,"y":257,"t":6159},{"x":208,"y":257,"t":6161},{"x":207,"y":257,"t":6164},{"x":206,"y":258,"t":6166},{"x":204,"y":258,"t":6169},{"x":203,"y":258,"t":6171},{"x":202,"y":258,"t":6174},{"x":201,"y":258,"t":6176},{"x":199,"y":258,"t":6179},{"x":198,"y":258,"t":6181},{"x":197,"y":258,"t":6184},{"x":196,"y":258,"t":6186},{"x":196,"y":258,"t":6189},{"x":195,"y":258,"t":6191},{"x":194,"y":258,"t":6194},{"x":194,"y":257,"t":6196},{"x":193,"y":257,"t":6199},{"x":193,"y":256,"t":6201},{"x":192,"y":255,"t":6204},{"x":192,"y":254,"t":6206},{"x":192,"y":253,"t":6209},{"x":192,"y":252,"t":6211},{"x":192,"y":251,"t":6214},{"x":192,"y":249,"t":6216},{"x":192,"y":247,"t":6219},{"x":192,"y":246,"t":6221},{"x":193,"y":244,"t":6224},{"x":193,"y":242,"t":6226},{"x":194,"y":240,"t":6229},{"x":195,"y":237,"t":6231},{"x":196,"y":235,"t":6233},{"x":196,"y":233,"t":6236},{"x":197,"y":230,"t":6238},{"x":198,"y":228,"t":6241}],[{"x":310,"y":199,"t":6557},{"x":308,"y":193,"t":6597},{"x":308,"y":193,"t":6600},{"x":307,"y":192,"t":6602},{"x":307,"y":192,"t":6605},{"x":307,"y":190,"t":6617},{"x":307,"y":189,"t":6620},{"x":307,"y":189,"t":6622},{"x":307,"y":188,"t":6625},{"x":306,"y":187,"t":6635},{"x":306,"y":186,"t":6637},{"x":305,"y":185,"t":6640},{"x":305,"y":185,"t":6642},{"x":304,"y":184,"t":6645},{"x":304,"y":184,"t":6647},{"x":304,"y":183,"t":6650},{"x":303,"y":182,"t":6652},{"x":302,"y":182,"t":6654},{"x":302,"y":181,"t":6657},{"x":301,"y":180,"t":6660},{"x":301,"y":179,"t":6662},{"x":300,"y":179,"t":6665},{"x":299,"y":178,"t":6667},{"x":299,"y":177,"t":6669},{"x":298,"y":177,"t":6672},{"x":297,"y":176,"t":6674},{"x":296,"y":176,"t":6677},{"x":296,"y":175,"t":6679},{"x":295,"y":175,"t":6682},{"x":294,"y":175,"t":6684},{"x":293,"y":174,"t":6687},{"x":292,"y":174,"t":6689},{"x":291,"y":174,"t":6692},{"x":291,"y":174,"t":6694},{"x":290,"y":175,"t":6697},{"x":289,"y":175,"t":6699},{"x":288,"y":176,"t":6702},{"x":287,"y":177,"t":6704},{"x":286,"y":179,"t":6707},{"x":285,"y":180,"t":6709},{"x":283,"y":182,"t":6712},{"x":282,"y":183,"t":6714},{"x":281,"y":185,"t":6717},{"x":280,"y":188,"t":6719},{"x":279,"y":190,"t":6722},{"x":278,"y":192,"t":6724},{"x":277,"y":195,"t":6727},{"x":276,"y":198,"t":6729},{"x":275,"y":201,"t":6732},{"x":274,"y":204,"t":6734},{"x":273,"y":207,"t":6737},{"x":272,"y":209,"t":6739},{"x":271,"y":213,"t":6742},{"x":271,"y":216,"t":6744},{"x":270,"y":219,"t":6747},{"x":269,"y":222,"t":6749},{"x":269,"y":225,"t":6752},{"x":268,"y":228,"t":6754},{"x":268,"y":231,"t":6757},{"x":268,"y":234,"t":6759},{"x":268,"y":237,"t":6762},{"x":267,"y":240,"t":6764},{"x":267,"y":242,"t":6767},{"x":267,"y":245,"t":6769},{"x":267,"y":248,"t":6772},{"x":267,"y":250,"t":6774},{"x":267,"y":253,"t":6777},{"x":267,"y":255,"t":6779},{"x":267,"y":257,"t":6782},{"x":268,"y":259,"t":6784},{"x":268,"y":260,"t":6787},{"x":269,"y":262,"t":6789},{"x":269,"y":263,"t":6792},{"x":270,"y":264,"t":6794},{"x":271,"y":265,"t":6796},{"x":271,"y":266,"t":6799},{"x":272,"y":267,"t":6801},{"x":274,"y":267,"t":6804},{"x":275,"y":268,"t":6806},{"x":276,"y":268,"t":6809},{"x":278,"y":268,"t":6811},{"x":279,"y":268,"t":6814},{"x":281,"y":268,"t":6816},{"x":283,"y":268,"t":6819},{"x":284,"y":268,"t":6821},{"x":286,"y":267,"t":6824},{"x":288,"y":267,"t":6826},{"x":290,"y":266,"t":6829},{"x":292,"y":266,"t":6831},{"x":294,"y":265,"t":6834},{"x":295,"y":264,"t":6836},{"x":297,"y":263,"t":6839},{"x":299,"y":262,"t":6841},{"x":301,"y":261,"t":6844},{"x":303,"y":260,"t":6846},{"x":305,"y":259,"t":6849},{"x":307,"y":258,"t":6851},{"x":309,"y":256,"t":6854},{"x":311,"y":255,"t":6856},{"x":313,"y":253,"t":6859},{"x":315,"y":252,"t":6861},{"x":316,"y":250,"t":6864},{"x":318,"y":248,"t":6866},{"x":320,"y":247,"t":6869},{"x":322,"y":245,"t":6871},{"x":323,"y":243,"t":6874},{"x":325,"y":241,"t":6876},{"x":326,"y":239,"t":6879},{"x":328,"y":237,"t":6881},{"x":329,"y":234,"t":6884},{"x":331,"y":232,"t":6886},{"x":332,"y":230,"t":6889},{"x":334,"y":228,"t":6891},{"x":335,"y":225,"t":6894},{"x":336,"y":223,"t":6896}]];
+
+    const kTestHandwritingCrossedOut = [[{"x":18.259796,"y":75.379456},{"x":17.889648,"y":75.626251},{"x":17.550415,"y":75.842163},{"x":17.21106,"y":76.088898},{"x":16.871765,"y":76.212311},{"x":16.563293,"y":76.366516},{"x":16.285675,"y":76.520782},{"x":15.946411,"y":76.736694},{"x":15.668762,"y":76.952637},{"x":15.391174,"y":77.106873},{"x":15.082733,"y":77.261108},{"x":14.86676,"y":77.384491},{"x":14.619965,"y":77.538696},{"x":14.404083,"y":77.662109},{"x":14.188141,"y":77.785492},{"x":14.003052,"y":77.878052},{"x":13.787109,"y":77.970581},{"x":13.602051,"y":78.06311},{"x":13.478668,"y":78.093933},{"x":13.324493,"y":78.093933},{"x":13.20108,"y":78.093933},{"x":13.108521,"y":78.093933},{"x":13.015991,"y":78.06311},{"x":12.923492,"y":78.06311},{"x":12.830933,"y":78.032288},{"x":12.769257,"y":77.908905},{"x":12.676666,"y":77.816345},{"x":12.61496,"y":77.692963},{"x":12.584137,"y":77.47702},{"x":12.553284,"y":77.261108},{"x":12.553284,"y":77.014343},{"x":12.553284,"y":76.675049},{"x":12.584137,"y":76.335693},{"x":12.61496,"y":75.873047},{"x":12.676666,"y":75.379456},{"x":12.769257,"y":74.824219},{"x":12.861786,"y":74.207275},{"x":12.985138,"y":73.497833},{"x":13.139374,"y":72.757477},{"x":13.293579,"y":71.924622},{"x":13.478668,"y":71.060913},{"x":13.725433,"y":70.197205},{"x":13.941345,"y":69.210144},{"x":14.218964,"y":68.222992},{"x":14.496582,"y":67.205078},{"x":14.835938,"y":66.125427},{"x":15.175201,"y":64.922424},{"x":15.483673,"y":63.750244},{"x":15.853851,"y":62.547241},{"x":16.22403,"y":61.282532},{"x":16.563293,"y":60.017792},{"x":16.933441,"y":58.691406},{"x":17.334473,"y":57.303284},{"x":17.704651,"y":55.976898},{"x":18.043884,"y":54.527039},{"x":18.444885,"y":53.046448},{"x":18.78421,"y":51.534943},{"x":19.154358,"y":50.023468},{"x":19.586182,"y":48.542816},{"x":19.956329,"y":47.062195},{"x":20.357422,"y":45.55072},{"x":20.758362,"y":44.039215},{"x":21.190186,"y":42.496887},{"x":21.62204,"y":40.954529},{"x":22.115601,"y":39.443054},{"x":22.609161,"y":37.900696},{"x":23.102661,"y":36.420074},{"x":23.627075,"y":34.970306},{"x":24.151428,"y":33.489624},{"x":24.706665,"y":31.978119},{"x":25.200195,"y":30.466644},{"x":25.786316,"y":28.95517},{"x":26.341522,"y":27.474518},{"x":26.927582,"y":26.086426},{"x":27.544495,"y":24.698303},{"x":28.099762,"y":23.310242},{"x":28.654938,"y":21.952972},{"x":29.148529,"y":20.595703},{"x":29.672882,"y":19.300171},{"x":30.197266,"y":18.035431},{"x":30.72168,"y":16.801575},{"x":31.21521,"y":15.629425},{"x":31.801239,"y":14.518951},{"x":32.356537,"y":13.43924},{"x":32.88092,"y":12.390503},{"x":33.436096,"y":11.495941},{"x":33.898834,"y":10.539673},{"x":34.484894,"y":9.6759949},{"x":34.978394,"y":8.9356995},{"x":35.502838,"y":8.1645203},{"x":36.058014,"y":7.5475769},{"x":36.582428,"y":7.0540161},{"x":37.137634,"y":6.5296326},{"x":37.600311,"y":6.0978088},{"x":38.063019,"y":5.7584534},{"x":38.46402,"y":5.4191589},{"x":38.895905,"y":5.14151},{"x":39.296844,"y":4.9564514},{"x":39.697906,"y":4.8022156},{"x":40.03717,"y":4.7096863},{"x":40.345612,"y":4.678833},{"x":40.654053,"y":4.678833},{"x":40.900848,"y":4.7096863},{"x":41.178497,"y":4.8947754},{"x":41.39444,"y":5.0798645},{"x":41.610352,"y":5.3265991},{"x":41.857056,"y":5.6659241},{"x":42.042145,"y":6.0052185},{"x":42.227264,"y":6.4370728},{"x":42.412323,"y":6.9614563},{"x":42.597443,"y":7.4858704},{"x":42.751648,"y":8.0719604},{"x":42.875031,"y":8.8431702},{"x":43.029236,"y":9.6451416},{"x":43.152618,"y":10.478027},{"x":43.27597,"y":11.465118},{"x":43.368591,"y":12.45224},{"x":43.430237,"y":13.593506},{"x":43.46109,"y":14.765686},{"x":43.522766,"y":15.968689},{"x":43.553619,"y":17.295135},{"x":43.584473,"y":18.775757},{"x":43.646149,"y":20.225555},{"x":43.646149,"y":21.767883},{"x":43.646149,"y":23.310242},{"x":43.646149,"y":24.883423},{"x":43.615295,"y":26.51828},{"x":43.615295,"y":28.184052},{"x":43.615295,"y":29.849731},{"x":43.615295,"y":31.638824},{"x":43.584473,"y":33.397095},{"x":43.553619,"y":35.155396},{"x":43.522766,"y":36.913605},{"x":43.46109,"y":38.702728},{"x":43.430237,"y":40.491882},{"x":43.399384,"y":42.311798},{"x":43.368591,"y":44.039215},{"x":43.368591,"y":45.797485},{"x":43.337708,"y":47.524872},{"x":43.27597,"y":49.159729},{"x":43.245209,"y":50.763763},{"x":43.214325,"y":52.367828},{"x":43.214325,"y":54.002716},{"x":43.183502,"y":55.60672},{"x":43.152618,"y":57.087341},{"x":43.121765,"y":58.506317},{"x":43.090973,"y":59.863556},{"x":43.060089,"y":61.220825},{"x":42.998444,"y":62.454681},{"x":42.936737,"y":63.688568},{"x":42.875031,"y":64.829895},{"x":42.875031,"y":65.940369},{"x":42.844147,"y":67.050812},{"x":42.813324,"y":68.007111},{"x":42.78244,"y":68.870819},{"x":42.751648,"y":69.703674},{"x":42.751648,"y":70.474823},{"x":42.720825,"y":71.184326},{"x":42.720825,"y":71.832092},{"x":42.720825,"y":72.387329},{"x":42.751648,"y":72.880859},{"x":42.78244,"y":73.312744},{"x":42.78244,"y":73.652039},{"x":42.844147,"y":73.898804},{"x":42.844147,"y":74.176453},{"x":42.875031,"y":74.299805},{"x":42.905884,"y":74.330627},{"x":42.967529,"y":74.392365},{"x":43.029236,"y":74.361542},{"x":43.121765,"y":74.145569},{"x":43.214325,"y":73.929657},{"x":43.306854,"y":73.682892},{"x":43.368591,"y":73.281891},{"x":43.522766,"y":72.850037},{"x":43.646149,"y":72.294769},{"x":43.800385,"y":71.585327},{"x":44.016357,"y":70.845001},{"x":44.201447,"y":69.981262},{"x":44.448151,"y":68.994202},{"x":44.694977,"y":67.945404},{"x":44.972534,"y":66.742401},{"x":45.311829,"y":65.415985},{"x":45.589478,"y":64.089569},{"x":45.959625,"y":62.608917},{"x":46.422302,"y":61.035736},{"x":46.823273,"y":59.462555},{"x":47.286041,"y":57.735107},{"x":47.810364,"y":55.853485},{"x":48.303925,"y":54.033539},{"x":48.890015,"y":52.09021},{"x":49.476074,"y":50.146851},{"x":50.093048,"y":48.141815},{"x":50.740753,"y":46.075104},{"x":51.357697,"y":44.070068},{"x":51.97464,"y":41.972473},{"x":52.622375,"y":39.874878},{"x":53.239288,"y":37.777313},{"x":53.856201,"y":35.679749},{"x":54.473175,"y":33.613007},{"x":55.120972,"y":31.638824},{"x":55.768677,"y":29.695496},{"x":56.38562,"y":27.69043},{"x":57.033386,"y":25.839661},{"x":57.650269,"y":24.050568},{"x":58.298035,"y":22.32312},{"x":58.976685,"y":20.626587},{"x":59.62442,"y":18.99173},{"x":60.303101,"y":17.480194},{"x":60.950836,"y":16.122955},{"x":61.629425,"y":14.796539},{"x":62.277222,"y":13.53183},{"x":62.863281,"y":12.45224},{"x":63.480255,"y":11.403412},{"x":64.066284,"y":10.478027},{"x":64.621552,"y":9.6759949},{"x":65.207581,"y":8.8431702},{"x":65.731934,"y":8.2261658},{"x":66.163788,"y":7.6709595},{"x":66.626495,"y":7.1773987},{"x":67.05838,"y":6.7763977},{"x":67.459351,"y":6.4987488},{"x":67.829529,"y":6.2211609},{"x":68.199646,"y":6.066925},{"x":68.53894,"y":5.9743958},{"x":68.909119,"y":5.8510132},{"x":69.186768,"y":5.8510132},{"x":69.526031,"y":5.9126892},{"x":69.80368,"y":6.0052185},{"x":70.112122,"y":6.2211609},{"x":70.389709,"y":6.4987488},{"x":70.667389,"y":6.7763977},{"x":70.9758,"y":7.1156921},{"x":71.191742,"y":7.5784607},{"x":71.500183,"y":8.0719604},{"x":71.716095,"y":8.6272278},{"x":71.932068,"y":9.3366394},{"x":72.117126,"y":10.076996},{"x":72.302216,"y":10.909882},{"x":72.425629,"y":11.866089},{"x":72.518097,"y":12.822357},{"x":72.610657,"y":13.932831},{"x":72.641479,"y":15.074158},{"x":72.641479,"y":16.277161},{"x":72.641479,"y":17.572754},{"x":72.548981,"y":19.053375},{"x":72.487305,"y":20.503174},{"x":72.333099,"y":22.045502},{"x":72.14798,"y":23.618713},{"x":71.96286,"y":25.161011},{"x":71.685242,"y":26.826782},{"x":71.407654,"y":28.585022},{"x":71.160889,"y":30.312408},{"x":70.852478,"y":32.132416},{"x":70.605682,"y":33.983185},{"x":70.328003,"y":35.772278},{"x":70.019562,"y":37.592224},{"x":69.772827,"y":39.350494},{"x":69.464386,"y":41.077942},{"x":69.217621,"y":42.867096},{"x":68.940002,"y":44.594452},{"x":68.662354,"y":46.352692},{"x":68.415558,"y":47.956726},{"x":68.168823,"y":49.529907},{"x":67.983765,"y":51.041412},{"x":67.706146,"y":52.522034},{"x":67.521027,"y":53.940979},{"x":67.305145,"y":55.390839},{"x":67.089203,"y":56.68634},{"x":66.873291,"y":57.889374},{"x":66.688202,"y":59.092377},{"x":66.533997,"y":60.202881},{"x":66.379791,"y":61.220825},{"x":66.225525,"y":62.238739},{"x":66.071259,"y":63.164154},{"x":66.009583,"y":63.966156},{"x":65.917023,"y":64.829895},{"x":65.824524,"y":65.539337},{"x":65.79364,"y":66.156281},{"x":65.731934,"y":66.742401},{"x":65.731934,"y":67.266754},{"x":65.731934,"y":67.729492},{"x":65.731934,"y":68.192169},{"x":65.731934,"y":68.531494},{"x":65.79364,"y":68.839966},{"x":65.855347,"y":69.117615},{"x":65.947906,"y":69.333466},{"x":66.009583,"y":69.487732},{"x":66.132996,"y":69.580261},{"x":66.225525,"y":69.641968},{"x":66.379791,"y":69.641968},{"x":66.533997,"y":69.611115},{"x":66.688202,"y":69.487732},{"x":66.873291,"y":69.302673}],[{"x":89.320984,"y":45.585114},{"x":89.07431,"y":45.430908},{"x":88.735046,"y":45.276703},{"x":87.501282,"y":44.598083},{"x":87.2854,"y":44.567291},{"x":86.976959,"y":44.443878},{"x":86.853546,"y":44.413025},{"x":86.637665,"y":44.443878},{"x":86.483429,"y":44.443878},{"x":86.39093,"y":44.505585},{"x":86.236725,"y":44.536438},{"x":86.236725,"y":44.721497},{"x":86.236725,"y":44.814056},{"x":86.267609,"y":44.999054},{"x":86.29837,"y":45.15329},{"x":86.29837,"y":45.307495},{"x":86.360077,"y":45.430908},{"x":86.421783,"y":45.585114},{"x":86.421783,"y":45.770142},{"x":86.514282,"y":45.893524}],[{"x":86.853546,"y":57.922485},{"x":86.637634,"y":58.415985},{"x":86.390869,"y":58.909485},{"x":86.082489,"y":59.341339},{"x":85.835724,"y":59.803955},{"x":85.527313,"y":60.235779},{"x":85.280579,"y":60.790955},{"x":85.064667,"y":61.315277},{"x":84.848755,"y":61.870483},{"x":84.632874,"y":62.456512},{"x":84.478668,"y":63.011688},{"x":84.262756,"y":63.597717},{"x":84.139404,"y":64.152893},{"x":83.985199,"y":64.708069},{"x":83.861755,"y":65.201538},{"x":83.738434,"y":65.725922},{"x":83.615051,"y":66.250244},{"x":83.522491,"y":66.743744},{"x":83.429993,"y":67.268066},{"x":83.337463,"y":67.79245},{"x":83.306671,"y":68.347626},{"x":83.214081,"y":68.871948},{"x":83.121582,"y":69.365448},{"x":83.059875,"y":69.858917},{"x":83.029022,"y":70.321564},{"x":82.967346,"y":70.815094},{"x":82.874817,"y":71.308563},{"x":82.843964,"y":71.77121},{"x":82.782349,"y":72.264709}],[{"x":94.071014,"y":65.570618},{"x":94.194397,"y":65.231293},{"x":94.379486,"y":64.891998},{"x":94.564575,"y":64.552704},{"x":94.71875,"y":64.151703},{"x":94.90387,"y":63.812378},{"x":95.119781,"y":63.411407},{"x":95.366516,"y":63.041199},{"x":95.705811,"y":62.609375},{"x":95.98349,"y":62.177521},{"x":96.291931,"y":61.745667},{"x":96.631226,"y":61.282959},{"x":97.032227,"y":60.789429},{"x":97.433258,"y":60.295868},{"x":97.865051,"y":59.802307},{"x":98.296906,"y":59.339661},{"x":98.759583,"y":58.784424},{"x":99.191406,"y":58.259979},{"x":99.654083,"y":57.735596},{"x":100.11679,"y":57.242065},{"x":100.61038,"y":56.779358},{"x":101.10388,"y":56.316681},{"x":101.59741,"y":55.853973},{"x":102.12177,"y":55.452972},{"x":102.5845,"y":55.082794},{"x":103.04718,"y":54.712646},{"x":103.44809,"y":54.435028},{"x":103.84915,"y":54.15744},{"x":104.28104,"y":53.910675},{"x":104.65118,"y":53.756409},{"x":105.05215,"y":53.540497},{"x":105.36063,"y":53.447937},{"x":105.6691,"y":53.386261},{"x":105.97754,"y":53.324585},{"x":106.2243,"y":53.324585},{"x":106.47107,"y":53.386261},{"x":106.68701,"y":53.47879},{"x":106.90286,"y":53.602173},{"x":107.08798,"y":53.818085},{"x":107.2731,"y":54.003204},{"x":107.45816,"y":54.280792},{"x":107.58151,"y":54.589264},{"x":107.70493,"y":54.928589},{"x":107.82831,"y":55.298737},{"x":107.85913,"y":55.730591},{"x":107.92078,"y":56.193298},{"x":107.92078,"y":56.748535},{"x":107.92078,"y":57.365479},{"x":107.88998,"y":57.951538},{"x":107.79742,"y":58.599335},{"x":107.67407,"y":59.277954},{"x":107.55066,"y":59.987396},{"x":107.3656,"y":60.758575},{"x":107.18051,"y":61.498871},{"x":107.02628,"y":62.27005},{"x":106.81039,"y":63.041199},{"x":106.62531,"y":63.812378},{"x":106.44022,"y":64.521851},{"x":106.2243,"y":65.262177},{"x":106.07004,"y":65.909943},{"x":105.91583,"y":66.619415},{"x":105.7616,"y":67.267151},{"x":105.60736,"y":67.884125},{"x":105.45312,"y":68.501007},{"x":105.36063,"y":69.056274},{"x":105.23721,"y":69.611511},{"x":105.14471,"y":70.135895},{"x":105.05215,"y":70.629425},{"x":104.99045,"y":71.092163},{"x":104.89795,"y":71.55484},{"x":104.83624,"y":71.986694},{"x":104.77454,"y":72.356842},{"x":104.68201,"y":72.757843},{"x":104.65118,"y":73.066284},{"x":104.65118,"y":73.374786},{"x":104.65118,"y":73.652405},{"x":104.65118,"y":73.89917},{"x":104.74371,"y":74.084259},{"x":104.77454,"y":74.269318},{"x":104.8671,"y":74.423523},{"x":104.95959,"y":74.516113},{"x":105.05215,"y":74.670319},{"x":105.17554,"y":74.732025},{"x":105.32977,"y":74.793701}],[{"x":136.97266,"y":57.275452},{"x":137.03436,"y":57.090424},{"x":137.09601,"y":56.905365},{"x":137.09601,"y":56.689423},{"x":137.12689,"y":56.504364},{"x":137.12689,"y":56.288483},{"x":137.12689,"y":56.134277},{"x":137.12689,"y":56.010925},{"x":137.12689,"y":55.887512},{"x":137.09601,"y":55.76416},{"x":137.06519,"y":55.671661},{"x":137.03436,"y":55.579102},{"x":136.97266,"y":55.517456},{"x":136.8801,"y":55.455719},{"x":136.75674,"y":55.394073},{"x":136.60254,"y":55.332397},{"x":136.44833,"y":55.270721},{"x":136.26328,"y":55.209045},{"x":136.07825,"y":55.178162},{"x":135.83148,"y":55.147308},{"x":135.61557,"y":55.147308},{"x":135.36884,"y":55.116455},{"x":135.02957,"y":55.116455},{"x":134.72116,"y":55.116455},{"x":134.3819,"y":55.116455},{"x":133.95007,"y":55.147308},{"x":133.51834,"y":55.178162},{"x":133.05569,"y":55.239838},{"x":132.56223,"y":55.36319},{"x":132.09958,"y":55.486572},{"x":131.54443,"y":55.609955},{"x":131.02008,"y":55.795013},{"x":130.46494,"y":55.949219},{"x":129.90982,"y":56.165131},{"x":129.32373,"y":56.381012},{"x":128.73776,"y":56.596893},{"x":128.18259,"y":56.874542},{"x":127.65826,"y":57.182922},{"x":127.13394,"y":57.491364},{"x":126.60962,"y":57.799835},{"x":126.11615,"y":58.169861},{"x":125.59186,"y":58.509186},{"x":125.09836,"y":58.910126},{"x":124.54321,"y":59.280273},{"x":124.04971,"y":59.619537},{"x":123.58707,"y":60.020508},{"x":123.12442,"y":60.452271},{"x":122.69269,"y":60.853241},{"x":122.23001,"y":61.285065},{"x":121.8291,"y":61.686005},{"x":121.42813,"y":62.117798},{"x":121.05804,"y":62.518768},{"x":120.74957,"y":62.888885},{"x":120.41031,"y":63.289795},{"x":120.13275,"y":63.659943},{"x":119.94766,"y":64.060883},{"x":119.70099,"y":64.461884},{"x":119.54675,"y":64.862823},{"x":119.42337,"y":65.171295},{"x":119.29999,"y":65.510529},{"x":119.23837,"y":65.849792},{"x":119.20752,"y":66.189056},{"x":119.14581,"y":66.497467},{"x":119.14581,"y":66.805939},{"x":119.14581,"y":67.083496},{"x":119.14581,"y":67.391937},{"x":119.20752,"y":67.638702},{"x":119.26917,"y":67.91629},{"x":119.36172,"y":68.163025},{"x":119.45425,"y":68.40976},{"x":119.60843,"y":68.687317},{"x":119.73181,"y":68.934082},{"x":119.88605,"y":69.180847},{"x":120.10193,"y":69.427551},{"x":120.28696,"y":69.61261},{"x":120.53369,"y":69.828552},{"x":120.81128,"y":70.013611},{"x":121.11972,"y":70.198639},{"x":121.45898,"y":70.352844},{"x":121.8291,"y":70.445404},{"x":122.16837,"y":70.50705},{"x":122.56927,"y":70.537903},{"x":122.93939,"y":70.537903},{"x":123.34036,"y":70.568756},{"x":123.74133,"y":70.537903},{"x":124.11142,"y":70.383698},{"x":124.54321,"y":70.229462},{"x":124.9133,"y":70.044434},{"x":125.34512,"y":69.766815},{"x":125.71518,"y":69.489258},{"x":126.11615,"y":69.149994},{"x":126.51709,"y":68.810699},{"x":126.88718,"y":68.440643},{"x":127.319,"y":67.977966},{"x":127.75082,"y":67.484467},{"x":128.18259,"y":66.960114},{"x":128.61441,"y":66.404999},{"x":129.04617,"y":65.880646},{"x":129.50882,"y":65.294617},{"x":129.97144,"y":64.677765},{"x":130.43411,"y":64.03006},{"x":130.86584,"y":63.382385},{"x":131.35938,"y":62.73468},{"x":131.85281,"y":62.025269},{"x":132.31543,"y":61.346771},{"x":132.80893,"y":60.637329},{"x":133.30243,"y":59.989624},{"x":133.76505,"y":59.311127},{"x":134.25851,"y":58.632599},{"x":134.72116,"y":57.984863},{"x":135.12213,"y":57.337158},{"x":135.55396,"y":56.720276},{"x":135.98569,"y":56.165131},{"x":136.38669,"y":55.579102},{"x":136.75674,"y":55.054779},{"x":137.06519,"y":54.592133},{"x":137.40448,"y":54.098633},{"x":137.68201,"y":53.636017},{"x":137.95963,"y":53.204193},{"x":138.23715,"y":52.803223},{"x":138.45306,"y":52.402283},{"x":138.6998,"y":52.062988},{"x":138.91571,"y":51.754608},{"x":139.10077,"y":51.446167},{"x":139.28583,"y":51.261108},{"x":139.47089,"y":51.014374},{"x":139.65594,"y":50.829315},{"x":139.81009,"y":50.675079},{"x":139.96439,"y":50.551697},{"x":140.11859,"y":50.490021},{"x":140.21112,"y":50.459198},{"x":140.3653,"y":50.459198},{"x":140.48865,"y":50.459198},{"x":140.55038,"y":50.520874},{"x":140.64288,"y":50.613403},{"x":140.70459,"y":50.736786},{"x":140.73541,"y":50.952667},{"x":140.73541,"y":51.199432},{"x":140.73541,"y":51.47702},{"x":140.67377,"y":51.816254},{"x":140.64288,"y":52.186432},{"x":140.5195,"y":52.618195},{"x":140.427,"y":53.142517},{"x":140.27277,"y":53.636017},{"x":140.08774,"y":54.222015},{"x":139.90268,"y":54.96225},{"x":139.68674,"y":55.671661},{"x":139.44006,"y":56.411865},{"x":139.19333,"y":57.244629},{"x":138.94656,"y":58.046539},{"x":138.6998,"y":58.971832},{"x":138.32968,"y":59.897095},{"x":137.95963,"y":60.791565},{"x":137.58948,"y":61.747681},{"x":137.15775,"y":62.673004},{"x":136.72589,"y":63.629089},{"x":136.23245,"y":64.585236},{"x":135.73895,"y":65.541351},{"x":135.24548,"y":66.497467},{"x":134.65948,"y":67.422791},{"x":134.01178,"y":68.348083},{"x":133.36411,"y":69.30423},{"x":132.74728,"y":70.260345},{"x":132.06873,"y":71.185638},{"x":131.42105,"y":72.172577},{"x":130.71167,"y":73.128693},{"x":130.03311,"y":74.054016},{"x":129.32373,"y":75.010132},{"x":128.58353,"y":75.966278},{"x":127.87418,"y":76.922394},{"x":127.13394,"y":77.87854},{"x":126.39377,"y":78.803802},{"x":125.65353,"y":79.729065},{"x":124.85159,"y":80.623566},{"x":124.08054,"y":81.518005},{"x":123.30951,"y":82.350769},{"x":122.56927,"y":83.152679},{"x":121.76736,"y":83.954575},{"x":120.96548,"y":84.694809},{"x":120.19446,"y":85.435043},{"x":119.36172,"y":86.082733},{"x":118.65231,"y":86.637894},{"x":117.94296,"y":87.223923},{"x":117.26447,"y":87.717407},{"x":116.6167,"y":88.210876},{"x":115.99988,"y":88.642685},{"x":115.41388,"y":89.043655},{"x":114.82785,"y":89.382919},{"x":114.21106,"y":89.722214},{"x":113.68671,"y":89.999756},{"x":113.16238,"y":90.215668},{"x":112.63809,"y":90.462418},{"x":112.11377,"y":90.647476},{"x":111.62027,"y":90.801697},{"x":111.1268,"y":90.925034},{"x":110.63333,"y":91.017609},{"x":110.10901,"y":91.048447},{"x":109.64636,"y":91.079285},{"x":109.21454,"y":91.079285},{"x":108.81363,"y":91.048447},{"x":108.47437,"y":90.955887},{"x":108.16595,"y":90.83255},{"x":107.95004,"y":90.678345}],[{"x":227.62009,"y":61.469879},{"x":227.55841,"y":61.068909},{"x":227.52762,"y":60.667938},{"x":227.46591,"y":60.328705},{"x":227.43509,"y":59.98941},{"x":227.37338,"y":59.742645},{"x":227.34256,"y":59.403381},{"x":227.28088,"y":59.156677},{"x":227.18832,"y":58.879089},{"x":227.18832,"y":58.694031},{"x":227.1575,"y":58.447296},{"x":227.12665,"y":58.262177},{"x":227.12665,"y":58.108002},{"x":227.06503,"y":57.89209},{"x":227.06503,"y":57.737885},{"x":227.00336,"y":57.552826},{"x":226.91074,"y":57.336945},{"x":226.87991,"y":57.121033},{"x":226.84903,"y":56.966827},{"x":226.78738,"y":56.750916},{"x":226.72574,"y":56.627533},{"x":226.66403,"y":56.442444},{"x":226.54062,"y":56.257416},{"x":226.44809,"y":56.103241},{"x":226.35559,"y":55.948975},{"x":226.20135,"y":55.7948},{"x":226.04718,"y":55.671417},{"x":225.86212,"y":55.548004},{"x":225.73871,"y":55.424652},{"x":225.52283,"y":55.332184},{"x":225.30695,"y":55.270477},{"x":225.02933,"y":55.208801},{"x":224.78262,"y":55.177948},{"x":224.47421,"y":55.147064},{"x":224.13492,"y":55.147064},{"x":223.79572,"y":55.177948},{"x":223.42563,"y":55.208801},{"x":223.05545,"y":55.332184},{"x":222.77786,"y":55.39386},{"x":222.3461,"y":55.548004},{"x":221.82181,"y":55.763916},{"x":221.39001,"y":55.918121},{"x":220.92731,"y":56.164886},{"x":220.37216,"y":56.473328},{"x":219.87869,"y":56.781708},{"x":219.32361,"y":57.121033},{"x":218.79926,"y":57.522003},{"x":218.27487,"y":57.922943},{"x":217.6889,"y":58.354736},{"x":217.13373,"y":58.848236},{"x":216.51688,"y":59.372589},{"x":215.9617,"y":59.927734},{"x":215.46823,"y":60.48291},{"x":214.94394,"y":61.068909},{"x":214.48132,"y":61.68576},{"x":213.98782,"y":62.302612},{"x":213.55603,"y":62.950317},{"x":213.15506,"y":63.598053},{"x":212.8158,"y":64.214874},{"x":212.44568,"y":64.862549},{"x":212.13727,"y":65.510315},{"x":211.85971,"y":66.15799},{"x":211.6438,"y":66.805725},{"x":211.42792,"y":67.422577},{"x":211.27368,"y":68.131897},{"x":211.08865,"y":68.810455},{"x":210.96527,"y":69.519836},{"x":210.90356,"y":70.229248},{"x":210.81113,"y":70.907806},{"x":210.81113,"y":71.617188},{"x":210.78018,"y":72.264862},{"x":210.78018,"y":72.94342},{"x":210.81113,"y":73.591156},{"x":210.90356,"y":74.177185},{"x":211.02695,"y":74.855713},{"x":211.15039,"y":75.410889},{"x":211.36621,"y":75.873535},{"x":211.55127,"y":76.397797},{"x":211.76718,"y":76.829651},{"x":212.01389,"y":77.230621},{"x":212.26062,"y":77.631531},{"x":212.59998,"y":78.032501},{"x":213.03171,"y":78.340942},{"x":213.43268,"y":78.680206},{"x":213.89532,"y":78.957794},{"x":214.41965,"y":79.173737},{"x":214.94394,"y":79.358734},{"x":215.52994,"y":79.543793},{"x":216.14679,"y":79.636353},{"x":216.76364,"y":79.728851},{"x":217.47299,"y":79.759705},{"x":218.15152,"y":79.759705},{"x":218.83008,"y":79.728851},{"x":219.50864,"y":79.636353},{"x":220.24881,"y":79.420441},{"x":220.92731,"y":79.235382},{"x":221.60587,"y":78.988647},{"x":222.28445,"y":78.680206},{"x":222.99377,"y":78.371796},{"x":223.67233,"y":78.001648},{"x":224.38168,"y":77.569855},{"x":225.12189,"y":77.076355},{"x":225.89294,"y":76.552063},{"x":226.66403,"y":75.966034},{"x":227.43509,"y":75.410889},{"x":228.23697,"y":74.763153},{"x":228.94638,"y":74.115448},{"x":229.74826,"y":73.406097},{"x":230.51929,"y":72.63501},{"x":231.25952,"y":71.894745},{"x":231.96887,"y":71.15451},{"x":232.67831,"y":70.3526},{"x":233.32596,"y":69.581543},{"x":233.94278,"y":68.810455},{"x":234.55963,"y":68.008575},{"x":235.14566,"y":67.268311},{"x":235.73166,"y":66.528137},{"x":236.31769,"y":65.818756},{"x":236.84201,"y":65.078522},{"x":237.39719,"y":64.338257},{"x":237.92142,"y":63.628845},{"x":238.35321,"y":62.919495},{"x":238.81583,"y":62.210114},{"x":239.27853,"y":61.531586},{"x":239.61783,"y":60.852997},{"x":240.01877,"y":60.205322},{"x":240.29633,"y":59.526764},{"x":240.57385,"y":58.909882},{"x":240.82065,"y":58.262177},{"x":241.03656,"y":57.645355},{"x":241.12909,"y":57.090149},{"x":241.1907,"y":56.535034},{"x":241.25241,"y":56.010712},{"x":241.1907,"y":55.548004},{"x":241.12909,"y":55.054565},{"x":241.00568,"y":54.591888},{"x":240.85144,"y":54.190918},{"x":240.69727,"y":53.820801},{"x":240.38882,"y":53.481567},{"x":240.04962,"y":53.203979},{"x":239.61783,"y":52.895538},{"x":239.18597,"y":52.648804},{"x":238.75418,"y":52.402069},{"x":238.32239,"y":52.21701},{"x":237.79807,"y":52.062775},{"x":237.27377,"y":51.970245},{"x":236.71866,"y":51.877716},{"x":236.10172,"y":51.846893},{"x":235.45407,"y":51.846893},{"x":234.8064,"y":51.846893},{"x":234.15872,"y":51.9086},{"x":233.44928,"y":52.031952},{"x":232.77078,"y":52.124481},{"x":231.99976,"y":52.30954},{"x":231.2287,"y":52.525452},{"x":230.45764,"y":52.71051},{"x":229.62491,"y":52.957214},{"x":228.85385,"y":53.234833},{"x":228.1445,"y":53.481567},{"x":227.37338,"y":53.789978},{"x":226.72574,"y":54.036743},{"x":225.98553,"y":54.345184},{"x":225.36862,"y":54.622711},{"x":224.78262,"y":54.931183},{"x":224.19659,"y":55.270477},{"x":223.70319,"y":55.578888},{"x":223.30222,"y":55.918121},{"x":222.87039,"y":56.257416},{"x":222.53119,"y":56.59668},{"x":222.28445,"y":56.935974},{"x":221.88348,"y":57.275208},{"x":221.66757,"y":57.676208},{"x":221.45166,"y":57.984619},{"x":221.26657,"y":58.354736},{"x":221.1124,"y":58.724823},{"x":220.98901,"y":59.064148},{"x":220.89651,"y":59.403381},{"x":220.80402,"y":59.711823},{"x":220.74234,"y":59.98941},{"x":220.71143,"y":60.267029},{"x":220.6806,"y":60.513763}],[{"x":243.81314,"y":79.327148},{"x":243.59726,"y":79.327148},{"x":243.47388,"y":79.327148},{"x":243.31973,"y":79.357971},{"x":243.16537,"y":79.296326},{"x":243.10373,"y":79.203766},{"x":243.0112,"y":79.111206},{"x":242.98038,"y":79.080353},{"x":242.94955,"y":78.957001},{"x":242.94955,"y":78.864441},{"x":243.0112,"y":78.771912},{"x":243.13461,"y":78.617645},{"x":243.258,"y":78.494324},{"x":243.44305,"y":78.309235},{"x":243.68982,"y":78.062439},{"x":243.9057,"y":77.815674},{"x":244.1525,"y":77.507202},{"x":244.46097,"y":77.167877},{"x":244.73856,"y":76.797699},{"x":245.07782,"y":76.396729},{"x":245.47882,"y":75.995758},{"x":245.91071,"y":75.53302},{"x":246.34256,"y":75.03952},{"x":246.74353,"y":74.545929},{"x":247.17538,"y":73.959839},{"x":247.63803,"y":73.404633},{"x":248.13162,"y":72.756836},{"x":248.62515,"y":72.170746},{"x":249.14951,"y":71.492126},{"x":249.7356,"y":70.906036},{"x":250.25998,"y":70.258301},{"x":250.81519,"y":69.579651},{"x":251.40128,"y":68.931885},{"x":251.89484,"y":68.314972},{"x":252.44998,"y":67.697998},{"x":253.00525,"y":67.111938},{"x":253.56046,"y":66.587524},{"x":254.08487,"y":66.063171},{"x":254.60922,"y":65.631317},{"x":255.10275,"y":65.16864},{"x":255.59628,"y":64.767609},{"x":256.02817,"y":64.397461},{"x":256.46005,"y":64.058105},{"x":256.89188,"y":63.749664},{"x":257.26193,"y":63.50293},{"x":257.66299,"y":63.256165},{"x":258.00229,"y":63.040192},{"x":258.34158,"y":62.91684},{"x":258.7117,"y":62.762573},{"x":258.98941,"y":62.670074},{"x":259.20523,"y":62.639191},{"x":259.45206,"y":62.577515},{"x":259.66794,"y":62.577515},{"x":259.88382,"y":62.670074},{"x":260.09976,"y":62.762573},{"x":260.28494,"y":62.91684},{"x":260.43912,"y":63.132721},{"x":260.62424,"y":63.31781},{"x":260.71677,"y":63.595459},{"x":260.84018,"y":63.934753},{"x":260.87094,"y":64.243256},{"x":260.96347,"y":64.644226},{"x":261.02518,"y":65.076111},{"x":261.08688,"y":65.569611},{"x":261.08688,"y":66.063171},{"x":261.08688,"y":66.649292},{"x":261.08688,"y":67.204498},{"x":261.02518,"y":67.852264},{"x":260.96347,"y":68.5},{"x":260.90182,"y":69.17868},{"x":260.77853,"y":69.888123},{"x":260.68582,"y":70.597595},{"x":260.56247,"y":71.307037},{"x":260.43912,"y":72.016541},{"x":260.25406,"y":72.726013},{"x":260.09976,"y":73.435455},{"x":259.91476,"y":74.144897},{"x":259.72958,"y":74.823547},{"x":259.60629,"y":75.53302},{"x":259.39035,"y":76.180786},{"x":259.23611,"y":76.828583},{"x":259.05106,"y":77.476349},{"x":258.866,"y":78.093262},{"x":258.68088,"y":78.710205},{"x":258.46494,"y":79.357971},{"x":258.34158,"y":79.974945},{"x":258.15659,"y":80.561005},{"x":258.00229,"y":81.147095},{"x":257.81723,"y":81.702332},{"x":257.66299,"y":82.165039},{"x":257.50876,"y":82.658569},{"x":257.35458,"y":83.121277},{"x":257.20029,"y":83.522263},{"x":257.07693,"y":83.98497},{"x":256.9227,"y":84.324265},{"x":256.79922,"y":84.694427},{"x":256.73758,"y":84.972061}],[{"x":0.92529297,"y":0.40097046},{"x":0.83279419,"y":0.33929443},{"x":0.74023438,"y":0.21591187},{"x":0.40097046,"y":0.061676025},{"x":0.24676514,"y":0.061676025},{"x":0.12341309,"y":0},{"x":0,"y":0.030853271},{"x":0,"y":0.18508911},{"x":0.030853271,"y":0.33929443},{"x":0.24676514,"y":0.61685181},{"x":0.49346924,"y":0.92532349},{"x":0.83279419,"y":1.3262634},{"x":1.2645569,"y":1.8197937},{"x":1.6655273,"y":2.2824097},{"x":2.1898499,"y":2.7759094},{"x":2.7142334,"y":3.3310852},{"x":3.3002014,"y":3.886261},{"x":3.947937,"y":4.5648499},{"x":4.6264648,"y":5.2434082},{"x":5.3358154,"y":5.8602905},{"x":6.1069031,"y":6.6622009},{"x":6.9397278,"y":7.4024353},{"x":7.8032837,"y":8.1118469},{"x":8.6976929,"y":8.9137573},{"x":9.7772217,"y":9.6231995},{"x":10.825836,"y":10.394257},{"x":11.936249,"y":11.103638},{"x":13.108215,"y":11.843933},{"x":14.218567,"y":12.584137},{"x":15.483124,"y":13.293549},{"x":16.778503,"y":14.033813},{"x":18.135651,"y":14.774048},{"x":19.492706,"y":15.545105},{"x":21.034821,"y":16.254486},{"x":22.546143,"y":16.994751},{"x":24.119171,"y":17.765839},{"x":25.59964,"y":18.536957},{"x":27.172577,"y":19.277161},{"x":28.868927,"y":19.986603},{"x":30.59613,"y":20.726868},{"x":32.323395,"y":21.436218},{"x":34.112274,"y":22.083954},{"x":35.901123,"y":22.762482},{"x":37.720856,"y":23.441071},{"x":39.509735,"y":24.119598},{"x":41.391174,"y":24.82901},{"x":43.210876,"y":25.538391},{"x":45.123138,"y":26.278656},{"x":47.035431,"y":26.988037},{"x":48.91684,"y":27.728271},{"x":50.829071,"y":28.49939},{"x":52.741333,"y":29.208771},{"x":54.653595,"y":29.979828},{"x":56.627533,"y":30.720123},{"x":58.570618,"y":31.398651},{"x":60.513763,"y":32.108063},{"x":62.425995,"y":32.786591},{"x":64.399933,"y":33.46521},{"x":66.373901,"y":34.112885},{"x":68.347839,"y":34.76059},{"x":70.229279,"y":35.439148},{"x":72.172394,"y":36.05603},{"x":74.084595,"y":36.703705},{"x":76.02771,"y":37.382324},{"x":77.909119,"y":38.029999},{"x":79.821442,"y":38.73941},{"x":81.702789,"y":39.417938},{"x":83.645874,"y":40.065643},{"x":85.465637,"y":40.775085},{"x":87.223724,"y":41.453613},{"x":88.98172,"y":42.132172},{"x":90.770599,"y":42.810791},{"x":92.621185,"y":43.489319},{"x":94.379211,"y":44.229523},{"x":96.075592,"y":44.908112},{"x":97.64856,"y":45.648376},{"x":99.314087,"y":46.357758},{"x":100.91791,"y":47.097961},{"x":102.52173,"y":47.961609},{"x":104.09473,"y":48.732697},{"x":105.66776,"y":49.565491},{"x":107.14813,"y":50.367401},{"x":108.6286,"y":51.169342},{"x":110.07828,"y":52.032928},{"x":111.46622,"y":52.804077},{"x":112.8541,"y":53.605927},{"x":114.242,"y":54.377045},{"x":115.62994,"y":55.11731},{"x":117.01791,"y":55.91922},{"x":118.31323,"y":56.597778},{"x":119.5162,"y":57.245483},{"x":120.71902,"y":57.893219},{"x":121.9527,"y":58.510071},{"x":123.09393,"y":59.096069},{"x":124.20422,"y":59.682098},{"x":125.25293,"y":60.237305},{"x":126.27078,"y":60.854156},{"x":127.2886,"y":61.37851},{"x":128.18298,"y":61.902863},{"x":129.04663,"y":62.396332},{"x":129.91025,"y":62.828156},{"x":130.6813,"y":63.259918},{"x":131.42154,"y":63.599243},{"x":132.10007,"y":63.938507},{"x":132.77859,"y":64.246979},{"x":133.36459,"y":64.555359},{"x":133.98148,"y":64.832977},{"x":134.5058,"y":65.018036},{"x":134.96844,"y":65.172241}],[{"x":7.4640503,"y":75.227203},{"x":7.309845,"y":74.918793},{"x":7.0939331,"y":74.517822},{"x":6.9705811,"y":74.240234},{"x":6.8163452,"y":73.90097},{"x":6.7854919,"y":73.623352},{"x":6.6929321,"y":73.098999},{"x":6.6004333,"y":72.543854},{"x":6.6929321,"y":72.081177},{"x":6.7854919,"y":71.556885},{"x":7.0322266,"y":71.155884},{"x":7.4023438,"y":70.693268},{"x":7.834137,"y":70.292267},{"x":8.4201965,"y":69.92215},{"x":9.1912231,"y":69.459473},{"x":9.9623413,"y":69.027679},{"x":10.918457,"y":68.595856},{"x":11.936279,"y":68.133209},{"x":12.954102,"y":67.670563},{"x":14.187805,"y":67.177063},{"x":15.421478,"y":66.65274},{"x":16.778564,"y":66.128387},{"x":18.197388,"y":65.573242},{"x":19.739502,"y":64.956329},{"x":21.3125,"y":64.3703},{"x":22.916321,"y":63.722595},{"x":24.550964,"y":63.105743},{"x":26.216553,"y":62.488861},{"x":27.974548,"y":61.810333},{"x":29.825134,"y":61.100922},{"x":31.644836,"y":60.422333},{"x":33.557129,"y":59.712952},{"x":35.531067,"y":58.880188},{"x":37.504974,"y":58.139923},{"x":39.478943,"y":57.368896},{"x":41.637939,"y":56.536072},{"x":43.6427,"y":55.672455},{"x":45.801758,"y":54.777985},{"x":47.899048,"y":53.821869},{"x":50.088928,"y":52.834869},{"x":52.247894,"y":51.817047},{"x":54.437775,"y":50.768341},{"x":56.720123,"y":49.688843},{"x":58.971649,"y":48.578491},{"x":61.254028,"y":47.37558},{"x":63.56723,"y":46.203522},{"x":65.849579,"y":45.000641},{"x":68.070282,"y":43.705231},{"x":70.352631,"y":42.50235},{"x":72.665894,"y":41.206879},{"x":75.009918,"y":39.973145},{"x":77.292267,"y":38.73941},{"x":79.60553,"y":37.474854},{"x":81.733704,"y":36.210266},{"x":84.016052,"y":34.914795},{"x":86.236755,"y":33.681061},{"x":88.457428,"y":32.416473},{"x":90.647247,"y":31.151917},{"x":92.837067,"y":29.918213},{"x":94.996155,"y":28.746124},{"x":97.24765,"y":27.604889},{"x":99.375793,"y":26.402039},{"x":101.53482,"y":25.260803},{"x":103.60126,"y":24.088745},{"x":105.79114,"y":22.978394},{"x":107.95013,"y":21.868011},{"x":110.07828,"y":20.75766},{"x":112.17557,"y":19.709015},{"x":114.24207,"y":18.752838},{"x":116.33939,"y":17.734985},{"x":118.375,"y":16.748016},{"x":120.37982,"y":15.853546},{"x":122.41541,"y":14.959106},{"x":124.38937,"y":14.09549},{"x":126.23996,"y":13.324432},{"x":128.18307,"y":12.553314},{"x":130.03366,"y":11.874756},{"x":131.76083,"y":11.227051},{"x":133.54971,"y":10.610138},{"x":135.21524,"y":10.054962},{"x":136.91159,"y":9.4689331},{"x":138.5463,"y":8.9754333},{"x":140.11923,"y":8.4820251},{"x":141.66138,"y":8.0809631},{"x":143.1727,"y":7.5874939},{"x":144.62234,"y":7.1556702}]];
+
+    // Construct a drawing from |data|, get prediction from |recognizer|, and verify the output
+    // prediction texts contains |expectedText|, and the segmentation result has
+    // |expectedGraphemeCount| number of graphemes.
+    async function testDrawing(recognizer, recognizerName, data, dataName, expectedText, expectedGraphemeCount) {
+        console.log(`Testing "${recognizerName}", using "${dataName}"".`)
+        // Build JS Drawing from |dataPath|.
+        const jsDrawing = await recognizer.startDrawing();
+        for (const stroke of data) {
+            const jsStroke = new HandwritingStroke();
+            for (const point of stroke) {
+                jsStroke.addPoint(point);
+            }
+            jsDrawing.addStroke(jsStroke);
+        }
+
+        // Check at least one prediction matches |expectedText|.
+        const predictions = await jsDrawing.getPrediction();
+        const wantedPrediction = predictions.find(pred => pred.text === expectedText);
+        if (!wantedPrediction) {
+            throw new Error(`Can't find expected text "${expectedText}", predictions are: ${predictions.map(p => p.text).join(", ")}, test recognizer: ${recognizerName}, test data: ${dataName}`);
+        }
+
+        // Check the number of segments matches |expectedGraphemeCount|.
+        const graphemeCount = wantedPrediction.segmentationResult.length;
+        if (graphemeCount !== expectedGraphemeCount) {
+            throw new Error(`Number of graphemes doesn't match, got ${graphemeCount}, want ${expectedText}, test recognizer: ${recognizerName}, test data: ${dataName}`);
+        }
+    }
+
+    async function testEnglishModel() {
+        const constraints = { languages: ['en'] };
+
+        if (navigator.queryHandwritingRecognizerSupport) {
+            // V1 query API.
+            const featureSupport = await navigator.queryHandwritingRecognizerSupport(constraints);
+            if (!featureSupport.languages) {
+                throw new Error("Handwriting recognizer doesn't support 'en' language");
+            }
+        }
+
+        if (navigator.queryHandwritingRecognizer) {
+            // V2 query API.
+            const featureSupport = await navigator.queryHandwritingRecognizer(constraints);
+            if (!featureSupport) {
+                throw new Error("Handwriting recognizer doesn't support 'en' language");
+            }
+        }
+
+        const recognizer = await navigator.createHandwritingRecognizer(constraints);
+
+        await testDrawing(recognizer, "English", kTestHandwritingABC, "text_abc", "abc", 3);
+    }
+
+    async function testGestureModel() {
+        const constraints = { languages: ['zxx-x-Gesture'] };
+
+        if (navigator.queryHandwritingRecognizerSupport) {
+            // V1 query API.
+            const featureSupport = await navigator.queryHandwritingRecognizerSupport(constraints);
+            if (!featureSupport.languages) {
+                throw new Error("Handwriting recognizer doesn't support gesture model");
+            }
+        }
+
+        if (navigator.queryHandwritingRecognizer) {
+            // V2 query API.
+            const featureSupport = await navigator.queryHandwritingRecognizer(constraints);
+            if (!featureSupport) {
+                throw new Error("Handwriting recognizer doesn't support gesture model");
+            }
+        }
+
+        const recognizer = await navigator.createHandwritingRecognizer(constraints);
+
+        await testDrawing(recognizer, "Gesture", kTestHandwritingABC, "text_abc", "NO_GESTURE", 0);
+        await testDrawing(recognizer, "Gesture", kTestHandwritingCrossedOut, "gesture_crossed_out", "X_OUT", 0);
+    }
+
+    // Tast test should wait for this Promise.
+    // This method should throw an Error with a description if test fails.
+    window.resultPromise = (async function () {
+        if ((!navigator.queryHandwritingRecognizerSupport && !navigator.queryHandwritingRecognizer)
+            || !navigator.createHandwritingRecognizer) {
+            throw new Error("Web Handwriting Recognition API is not available");
+        }
+
+        await testEnglishModel();
+        await testGestureModel();
+
+        if (navigator.queryHandwritingRecognizer) {
+            // V2 query, when the constraints can't be met.
+            const featureSupport = await navigator.queryHandwritingRecognizer({ languages: ['invalid_lang'] });
+            if (featureSupport !== null) {
+                throw new Error("queryHandwritingRecognizer didn't return null for unsupported languages");
+            }
+        }
+    })();
+</script>
\ No newline at end of file
diff --git a/chrome/test/data/chromeos/web_handwriting/web_handwriting_recognition_not_supported.html b/chrome/test/data/chromeos/web_handwriting/web_handwriting_recognition_not_supported.html
new file mode 100644
index 0000000..6c29f60
--- /dev/null
+++ b/chrome/test/data/chromeos/web_handwriting/web_handwriting_recognition_not_supported.html
@@ -0,0 +1,57 @@
+<!-- Copyright 2021 The ChromiumOS Authors
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<!DOCTYPE html>
+
+<title>Web Handwriting Recognition Test</title>
+<h1>Device doesn't support on-device handwriting</h1>
+
+<script>
+    // Tast test should wait for this Promise.
+    // This method should throw an Error with a description if test fails.
+    window.resultPromise = (async function () {
+        if ((!navigator.queryHandwritingRecognizerSupport && !navigator.queryHandwritingRecognizer)
+            || !navigator.createHandwritingRecognizer) {
+            throw new Error("Web Handwriting Recognition API is not available");
+        }
+
+        // Test that calling JS API will return (doesn't crash or hang), so JS
+        // knows that handwriting isn't supported.
+        if (navigator.queryHandwritingRecognizerSupport) {
+            // V1 API.
+            const { languages } = await navigator.queryHandwritingRecognizerSupport({ languages: ['en'] });
+            if (languages !== false) {
+                throw new Error("Feature query shouldn't report as supported");
+            }
+        }
+
+        if (navigator.queryHandwritingRecognizer) {
+            // V2 API.
+            const featureSupport = await navigator.queryHandwritingRecognizer({ languages: ['en'] });
+            if (featureSupport !== null) {
+                throw new Error("Feature query should return null");
+            }
+        }
+
+        // Test that a JS error is thrown (via Promise rejection) when creating a recognizer.
+        const didCreateRecognizer = await navigator.createHandwritingRecognizer({ languages: ['en'] }).then(
+            _ => true,
+            error => false,
+        );
+        if (didCreateRecognizer) {
+            throw new Error("Recognizer shouldn't be created, should have thrown an Error");
+        }
+
+        // It's okay to create and manipulate handwriting strokes.
+        const stroke = new HandwritingStroke()
+        stroke.addPoint({ x: 1, y: 2, t: 0 })
+        if (stroke.getPoints().length !== 1) {
+            throw new Error("Can't add point to stroke");
+        }
+        stroke.clear();
+        if (stroke.getPoints().length !== 0) {
+            throw new Error("Can't clear stroke");
+        }
+    })();
+</script>
\ No newline at end of file
diff --git a/chrome/test/data/extensions/api_test/automation/tests/basic/manifest.json b/chrome/test/data/extensions/api_test/automation/tests/basic/manifest.json
index 5da6481..09ecc9bc 100644
--- a/chrome/test/data/extensions/api_test/automation/tests/basic/manifest.json
+++ b/chrome/test/data/extensions/api_test/automation/tests/basic/manifest.json
@@ -5,7 +5,8 @@
   "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8xv6iO+j4kzj1HiBL93+XVJH/CRyAQMUHS/Z0l8nCAzaAFkW/JsNwxJqQhrZspnxLqbQxNncXs6g6bsXAwKHiEs+LSs+bIv0Gc/2ycZdhXJ8GhEsSMakog5dpQd1681c2gLK/8CrAoewE/0GIKhaFcp7a2iZlGh4Am6fgMKy0iQIDAQAB",
   "description": "Extension which simply calls chrome.automation.getDesktop().",
   "background": {
-    "scripts": [ "background.js" ]
+    "scripts": [ "background.js" ],
+    "persistent": true
   },
   "permissions": ["tabs", "http://a.com/"],
   "automation": {"desktop": true}
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn
index cb9ea80..1f9a43b 100644
--- a/chrome/test/data/webui/BUILD.gn
+++ b/chrome/test/data/webui/BUILD.gn
@@ -331,17 +331,11 @@
 
   if (is_chromeos_ash) {
     in_files += [
-      "cr_focus_row_behavior_test.ts",
       "mocha_adapter.js",
       "mojo_webui_test_support.js",
     ]
   }
 
-  if (enable_webui_certificate_viewer) {
-    in_files +=
-        [ "certificate_viewer_dialog/certificate_viewer_dialog_test.js" ]
-  }
-
   if (!is_chromeos_lacros) {
     in_files += [
       "bluetooth_internals/bluetooth_internals_test.js",
@@ -470,6 +464,11 @@
     grdp_files += [ "$target_gen_dir/print_preview/resources.grdp" ]
   }
 
+  if (enable_webui_certificate_viewer) {
+    deps += [ "certificate_viewer_dialog:build_grdp" ]
+    grdp_files += [ "$target_gen_dir/certificate_viewer_dialog/resources.grdp" ]
+  }
+
   if (enable_webui_tab_strip) {
     deps += [ "tab_strip:build_grdp" ]
     grdp_files += [ "$target_gen_dir/tab_strip/resources.grdp" ]
diff --git a/chrome/test/data/webui/certificate_viewer_dialog/BUILD.gn b/chrome/test/data/webui/certificate_viewer_dialog/BUILD.gn
new file mode 100644
index 0000000..562fbe9
--- /dev/null
+++ b/chrome/test/data/webui/certificate_viewer_dialog/BUILD.gn
@@ -0,0 +1,23 @@
+# Copyright 2022 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//chrome/common/features.gni")
+import("../build_webui_tests.gni")
+
+assert(enable_webui_certificate_viewer)
+
+build_webui_tests("build") {
+  files = [ "certificate_viewer_dialog_test.ts" ]
+
+  ts_path_mappings =
+      [ "chrome://view-cert/*|" + rebase_path(
+            "$root_gen_dir/chrome/browser/resources/certificate_viewer/tsc/*",
+            target_gen_dir) ]
+  ts_deps = [
+    "//chrome/browser/resources/certificate_viewer:build_ts",
+    "//ui/webui/resources/cr_elements:build_ts",
+    "//ui/webui/resources/js:build_ts",
+  ]
+  ts_definitions = [ "//tools/typescript/definitions/chrome_send.d.ts" ]
+}
diff --git a/chrome/test/data/webui/certificate_viewer_dialog/certificate_viewer_dialog_browsertest.cc b/chrome/test/data/webui/certificate_viewer_dialog/certificate_viewer_dialog_browsertest.cc
index 9fc0c39..dad53d7 100644
--- a/chrome/test/data/webui/certificate_viewer_dialog/certificate_viewer_dialog_browsertest.cc
+++ b/chrome/test/data/webui/certificate_viewer_dialog/certificate_viewer_dialog_browsertest.cc
@@ -9,6 +9,7 @@
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/browser/ui/webui/certificate_viewer_webui.h"
+#include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/common/webui_url_constants.h"
 #include "chrome/test/base/ui_test_utils.h"
@@ -66,7 +67,8 @@
         browser()->tab_strip_model()->GetActiveWebContents(),
         browser()->window()->GetNativeWindow());
 
-    content::WebContents* webui_webcontents = dialog->webui_->GetWebContents();
+    content::WebContents* webui_webcontents =
+        dialog->delegate_->GetWebContents();
     EXPECT_TRUE(content::WaitForLoadStop(webui_webcontents));
     webui_webcontents->GetPrimaryMainFrame()->SetWebUIProperty(
         "expectedUrl", chrome::kChromeUICertificateViewerURL);
diff --git a/chrome/test/data/webui/certificate_viewer_dialog/certificate_viewer_dialog_test.js b/chrome/test/data/webui/certificate_viewer_dialog/certificate_viewer_dialog_test.js
deleted file mode 100644
index cb14c72..0000000
--- a/chrome/test/data/webui/certificate_viewer_dialog/certificate_viewer_dialog_test.js
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2012 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {assertEquals, assertFalse, assertLT, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
-import {eventToPromise} from 'chrome://webui-test/test_util.js';
-
-/**
- * Find the first tree item (in the certificate fields tree) with a value.
- * @param {!Element} tree Certificate fields subtree to search.
- * @return {?Element} The first found element with a value, null if not found.
- */
-function getElementWithValue(tree) {
-  for (let i = 0; i < tree.items.length; i++) {
-    let element = tree.items[i];
-    if (element.detail && element.detail.payload &&
-        element.detail.payload.val) {
-      return element;
-    }
-    if (element = getElementWithValue(element)) {
-      return element;
-    }
-  }
-  return null;
-}
-
-suite('CertificateViewer', function() {
-  // Tests that the dialog opened to the correct URL.
-  test('DialogURL', function() {
-    assertEquals(chrome.getVariableValue('expectedUrl'), window.location.href);
-  });
-
-  // Tests for the correct common name in the test certificate.
-  test('CommonName', function() {
-    assertTrue(document.querySelector('#general-error').hidden);
-    assertFalse(document.querySelector('#general-fields').hidden);
-
-    assertEquals(
-        'www.google.com', document.querySelector('#issued-cn').textContent);
-  });
-
-  test('Details', async function() {
-    const certHierarchy = document.querySelector('#hierarchy');
-    const certFields = document.querySelector('#cert-fields');
-    const certFieldVal = document.querySelector('#cert-field-value');
-
-    // Select the second tab, causing its data to be loaded if needed.
-    document.querySelector('cr-tab-box').setAttribute('selected-index', '1');
-
-    // There must be at least one certificate in the hierarchy.
-    assertLT(0, certHierarchy.items.length);
-
-    // Wait for the '-for-testing' event to fire only if |certFields| is not
-    // populated yet, otherwise don't wait, the event has already fired.
-    const whenLoaded = certFields.items.length === 0 ?
-        eventToPromise(
-            'certificate-fields-updated-for-testing', document.body) :
-        Promise.resolve();
-
-    // Select the first certificate on the chain and ensure the details show up.
-    await whenLoaded;
-    assertLT(0, certFields.items.length);
-
-    // Test that a field can be selected to see the details for that
-    // field.
-    const item = getElementWithValue(certFields);
-    assertNotEquals(null, item);
-    certFields.selectedItem = item;
-    assertEquals(item.detail.payload.val, certFieldVal.textContent);
-
-    // Test that selecting an item without a value empties the field.
-    certFields.selectedItem = certFields.items[0];
-    assertEquals('', certFieldVal.textContent);
-  });
-
-  test('InvalidCert', async function() {
-    // Error should be shown instead of cert fields.
-    assertFalse(document.querySelector('#general-error').hidden);
-    assertTrue(document.querySelector('#general-fields').hidden);
-
-    // Cert hash should still be shown.
-    assertEquals(
-        '787188ffa5cca48212ed291e62cb03e1' +
-            '1c1f8279df07feb1d2b0e02e0e4aa9e4',
-        document.querySelector('#sha256').textContent);
-  });
-});
diff --git a/chrome/test/data/webui/certificate_viewer_dialog/certificate_viewer_dialog_test.ts b/chrome/test/data/webui/certificate_viewer_dialog/certificate_viewer_dialog_test.ts
new file mode 100644
index 0000000..c68727d
--- /dev/null
+++ b/chrome/test/data/webui/certificate_viewer_dialog/certificate_viewer_dialog_test.ts
@@ -0,0 +1,91 @@
+// Copyright 2012 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {assertEquals, assertFalse, assertLT, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {eventToPromise} from 'chrome://webui-test/test_util.js';
+import {CrTreeBaseElement} from 'chrome://resources/cr_elements/cr_tree/cr_tree_base.js';
+import {getRequiredElement} from 'chrome://resources/js/util.js';
+import {TreeItemDetail} from 'chrome://view-cert/certificate_viewer.js';
+
+/**
+ * Find the first tree item (in the certificate fields tree) with a value.
+ * @param tree Certificate fields subtree to search.
+ * @return The first found element with a value, null if not found.
+ */
+function getElementWithValue(tree: CrTreeBaseElement): CrTreeBaseElement|null {
+  for (let i = 0; i < tree.items.length; i++) {
+    let element: CrTreeBaseElement|null = tree.items[i]!;
+    const detail = element.detail as TreeItemDetail|null;
+    if (detail && detail.payload && detail.payload.val) {
+      return element;
+    }
+    element = getElementWithValue(element);
+    if (element) {
+      return element;
+    }
+  }
+  return null;
+}
+
+suite('CertificateViewer', function() {
+  // Tests that the dialog opened to the correct URL.
+  test('DialogURL', function() {
+    assertEquals(chrome.getVariableValue('expectedUrl'), window.location.href);
+  });
+
+  // Tests for the correct common name in the test certificate.
+  test('CommonName', function() {
+    assertTrue(getRequiredElement('general-error').hidden);
+    assertFalse(getRequiredElement('general-fields').hidden);
+
+    assertEquals(
+        'www.google.com', getRequiredElement('issued-cn').textContent);
+  });
+
+  test('Details', async function() {
+    const certHierarchy = getRequiredElement<CrTreeBaseElement>('hierarchy');
+    const certFields = getRequiredElement<CrTreeBaseElement>('cert-fields');
+    const certFieldVal = getRequiredElement('cert-field-value');
+
+    // Select the second tab, causing its data to be loaded if needed.
+    getRequiredElement('tabbox').setAttribute('selected-index', '1');
+
+    // There must be at least one certificate in the hierarchy.
+    assertLT(0, certHierarchy.items.length);
+
+    // Wait for the '-for-testing' event to fire only if |certFields| is not
+    // populated yet, otherwise don't wait, the event has already fired.
+    const whenLoaded = certFields.items.length === 0 ?
+        eventToPromise(
+            'certificate-fields-updated-for-testing', document.body) :
+        Promise.resolve();
+
+    // Select the first certificate on the chain and ensure the details show up.
+    await whenLoaded;
+    assertLT(0, certFields.items.length);
+
+    // Test that a field can be selected to see the details for that
+    // field.
+    const item = getElementWithValue(certFields);
+    assertTrue(!!item);
+    certFields.selectedItem = item;
+    assertEquals((item.detail as TreeItemDetail).payload.val, certFieldVal.textContent);
+
+    // Test that selecting an item without a value empties the field.
+    certFields.selectedItem = certFields.items[0]!;
+    assertEquals('', certFieldVal.textContent);
+  });
+
+  test('InvalidCert', async function() {
+    // Error should be shown instead of cert fields.
+    assertFalse(getRequiredElement('general-error').hidden);
+    assertTrue(getRequiredElement('general-fields').hidden);
+
+    // Cert hash should still be shown.
+    assertEquals(
+        '787188ffa5cca48212ed291e62cb03e1' +
+            '1c1f8279df07feb1d2b0e02e0e4aa9e4',
+        getRequiredElement('sha256').textContent);
+  });
+});
diff --git a/chrome/test/data/webui/chromeos/BUILD.gn b/chrome/test/data/webui/chromeos/BUILD.gn
index a7d1450..bd1abc5 100644
--- a/chrome/test/data/webui/chromeos/BUILD.gn
+++ b/chrome/test/data/webui/chromeos/BUILD.gn
@@ -177,6 +177,7 @@
   in_files = [
     "bluetooth_pairing_test.js",
     "chai_assert.js",
+    "cr_focus_row_behavior_test.ts",
     "crostini_installer_app_test.js",
     "crostini_upgrader_app_test.js",
     "fake_network_config_mojom.js",
diff --git a/chrome/test/data/webui/chromeos/cr_focus_row_behavior_interactive_test.js b/chrome/test/data/webui/chromeos/cr_focus_row_behavior_interactive_test.js
index 03e81da5..d1809bce18 100644
--- a/chrome/test/data/webui/chromeos/cr_focus_row_behavior_interactive_test.js
+++ b/chrome/test/data/webui/chromeos/cr_focus_row_behavior_interactive_test.js
@@ -15,7 +15,7 @@
 var CrFocusRowBehaviorTest = class extends PolymerInteractiveUITest {
   /** @override */
   get browsePreload() {
-    return 'chrome://webui-test/test_loader.html?module=cr_focus_row_behavior_test.js';
+    return 'chrome://webui-test/test_loader.html?module=chromeos/cr_focus_row_behavior_test.js';
   }
 
   /** @override */
diff --git a/chrome/test/data/webui/cr_focus_row_behavior_test.ts b/chrome/test/data/webui/chromeos/cr_focus_row_behavior_test.ts
similarity index 96%
rename from chrome/test/data/webui/cr_focus_row_behavior_test.ts
rename to chrome/test/data/webui/chromeos/cr_focus_row_behavior_test.ts
index ef8bb3d..50a155a 100644
--- a/chrome/test/data/webui/cr_focus_row_behavior_test.ts
+++ b/chrome/test/data/webui/chromeos/cr_focus_row_behavior_test.ts
@@ -8,9 +8,9 @@
 import {down, pressAndReleaseKeyOn, up} from 'chrome://resources/polymer/v3_0/iron-test-helpers/mock-interactions.js';
 import {html, PolymerElement, mixinBehaviors} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
-import {eventToPromise} from './test_util.js';
-import {assertFalse, assertTrue, assertEquals} from './chai_assert.js';
-import {waitAfterNextRender} from './polymer_test_util.js';
+import {eventToPromise} from 'chrome://webui-test/test_util.js';
+import {assertFalse, assertTrue, assertEquals} from 'chrome://webui-test/chai_assert.js';
+import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
 
 // clang-format on
 
diff --git a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.ts b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.ts
index 7d44fd8e..29648cfc 100644
--- a/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.ts
+++ b/chrome/test/data/webui/chromeos/shortcut_customization/accelerator_edit_dialog_test.ts
@@ -746,6 +746,46 @@
     assertFalse(addButtonContainer.hidden);
   });
 
+  test('showEmptyState', async () => {
+    // Create disabled accelerator info.
+    const acceleratorInfo: AcceleratorInfo =
+        createCustomStandardAcceleratorInfo(
+            Modifier.CONTROL | Modifier.SHIFT,
+            /*key=*/ 71,
+            /*keyDisplay=*/ 'g', AcceleratorState.kDisabledByUser);
+
+    viewElement!.acceleratorInfos = [acceleratorInfo];
+    viewElement!.description = 'test shortcut';
+    await flush();
+
+    // Open dialog.
+    const dialog =
+        viewElement!.shadowRoot!.querySelector('cr-dialog') as CrDialogElement;
+    assertTrue(dialog.open);
+
+    let noShortcutAssigned = viewElement!.shadowRoot!.querySelector(
+                                 '#noShortcutAssigned') as HTMLDivElement;
+
+    // Expect "No shortcut assigned" message is shown when there's no enabled
+    // accelerators in the dialog.
+    assertTrue(!!noShortcutAssigned);
+    assertEquals(
+        'No shortcut assigned', noShortcutAssigned.textContent!.trim());
+
+    // Click add button, ViewState change to ADD.
+    const addButton =
+        dialog!.querySelector('#addAcceleratorButton') as CrButtonElement;
+    assertTrue(!!addButton);
+    addButton!.click();
+    await flush();
+
+    // Expect "No shortcut assigned" message is not displayed when ViewState
+    // becomes ADD.
+    noShortcutAssigned = viewElement!.shadowRoot!.querySelector(
+                             '#noShortcutAssigned') as HTMLDivElement;
+    assertFalse(!!noShortcutAssigned);
+  });
+
   test('buttonsVisibility', async () => {
     // Set the default accelerators the same as the initialized accelerators.
     const defaultAccelerators: Accelerator[] = [{
diff --git a/chrome/test/data/webui/compose/BUILD.gn b/chrome/test/data/webui/compose/BUILD.gn
index 3ef989e..e2512966 100644
--- a/chrome/test/data/webui/compose/BUILD.gn
+++ b/chrome/test/data/webui/compose/BUILD.gn
@@ -16,6 +16,7 @@
                     target_gen_dir) ]
   ts_deps = [
     "//chrome/browser/resources/compose:build_ts",
+    "//ui/webui/resources/cr_elements:build_ts",
     "//ui/webui/resources/js:build_ts",
   ]
 }
diff --git a/chrome/test/data/webui/compose/compose_app_test.ts b/chrome/test/data/webui/compose/compose_app_test.ts
index b497474..c14248dc 100644
--- a/chrome/test/data/webui/compose/compose_app_test.ts
+++ b/chrome/test/data/webui/compose/compose_app_test.ts
@@ -7,13 +7,13 @@
 import {ComposeAppElement, ComposeAppState} from 'chrome://compose/app.js';
 import {CloseReason, ComposeDialogCallbackRouter, ComposeState, ComposeStatus, Length, OpenMetadata, StyleModifiers, Tone} from 'chrome://compose/compose.mojom-webui.js';
 import {ComposeApiProxy, ComposeApiProxyImpl} from 'chrome://compose/compose_api_proxy.js';
+import {CrFeedbackOption} from 'chrome://resources/cr_elements/cr_feedback_buttons/cr_feedback_buttons.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
 import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
 import {isVisible, whenCheck} from 'chrome://webui-test/test_util.js';
 
-
 class TestingApiProxy extends TestBrowserProxy implements ComposeApiProxy {
   private initialInput_: string = '';
   private initialState_: ComposeState = {
@@ -31,6 +31,7 @@
       'acceptComposeResult',
       'closeUi',
       'compose',
+      'openBugReportingLink',
       'requestInitialState',
       'saveWebuiState',
       'undo',
@@ -59,7 +60,9 @@
     return this.router_;
   }
 
-  openBugReportingLink() {}
+  openBugReportingLink() {
+    this.methodCalled('openBugReportingLink');
+  }
 
   requestInitialState(): Promise<OpenMetadata> {
     this.methodCalled('requestInitialState');
@@ -549,4 +552,15 @@
     assertEquals(Length.kLonger, Number(appWithUndo.$.lengthMenu.value));
     assertEquals(Tone.kCasual, Number(appWithUndo.$.toneMenu.value));
   });
+
+  test('Feedback', async () => {
+    const feedbackButtons =
+        app.shadowRoot!.querySelector('cr-feedback-buttons')!;
+    feedbackButtons.dispatchEvent(new CustomEvent('selected-option-changed', {
+      bubbles: true,
+      composed: true,
+      detail: {value: CrFeedbackOption.THUMBS_DOWN},
+    }));
+    await testProxy.whenCalled('openBugReportingLink');
+  });
 });
diff --git a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/BUILD.gn b/chrome/test/data/webui/cr_components/chromeos/cellular_setup/BUILD.gn
deleted file mode 100644
index 7290ec4..0000000
--- a/chrome/test/data/webui/cr_components/chromeos/cellular_setup/BUILD.gn
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2020 The Chromium Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/chrome/test/data/webui/cr_elements/BUILD.gn b/chrome/test/data/webui/cr_elements/BUILD.gn
index 2686f17f..5cb322ea 100644
--- a/chrome/test/data/webui/cr_elements/BUILD.gn
+++ b/chrome/test/data/webui/cr_elements/BUILD.gn
@@ -19,6 +19,7 @@
     "cr_dialog_test.ts",
     "cr_drawer_test.ts",
     "cr_expand_button_test.ts",
+    "cr_feedback_buttons_test.ts",
     "cr_fingerprint_progress_arc_test.ts",
     "cr_focus_row_mixin_test.ts",
     "cr_grid_focus_test.ts",
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.cc b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.cc
index 788a001..93a15ba6 100644
--- a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.cc
+++ b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.cc
@@ -151,6 +151,10 @@
   RunTest("cr_elements/cr_loading_gradient_test.js", "mocha.run()");
 }
 
+IN_PROC_BROWSER_TEST_F(CrElementsTest, CrFeedbackButtons) {
+  RunTest("cr_elements/cr_feedback_buttons_test.js", "mocha.run()");
+}
+
 // Test with --enable-pixel-output-in-tests enabled, required by a few test
 // cases using HTML canvas.
 class CrElementsWithPixelOutputTest : public WebUIMochaBrowserTest {
diff --git a/chrome/test/data/webui/cr_elements/cr_feedback_buttons_test.ts b/chrome/test/data/webui/cr_elements/cr_feedback_buttons_test.ts
new file mode 100644
index 0000000..ce295e2
--- /dev/null
+++ b/chrome/test/data/webui/cr_elements/cr_feedback_buttons_test.ts
@@ -0,0 +1,89 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://resources/cr_elements/cr_feedback_buttons/cr_feedback_buttons.js';
+
+import {CrFeedbackButtonsElement, CrFeedbackOption} from 'chrome://resources/cr_elements/cr_feedback_buttons/cr_feedback_buttons.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
+import {assertEquals} from 'chrome://webui-test/chai_assert.js';
+import {flushTasks} from 'chrome://webui-test/polymer_test_util.js';
+import {eventToPromise} from 'chrome://webui-test/test_util.js';
+
+suite('CrFeedbackButtonsTest', () => {
+  let element: CrFeedbackButtonsElement;
+
+  suiteSetup(() => {
+    loadTimeData.resetForTesting({
+      thumbsDown: 'thumbs down',
+      thumbsUp: 'thumbs up',
+    });
+  });
+
+  setup(async () => {
+    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    element = document.createElement('cr-feedback-buttons');
+    document.body.appendChild(element);
+    await flushTasks();
+  });
+
+  test('SetsLabels', () => {
+    assertEquals('thumbs up', element.$.thumbsUp.ariaLabel);
+    assertEquals('thumbs down', element.$.thumbsDown.ariaLabel);
+  });
+
+  test('TogglesIconState', () => {
+    assertEquals('cr:thumbs-up', element.$.thumbsUp.ironIcon);
+    assertEquals('false', element.$.thumbsUp.ariaPressed);
+    assertEquals('cr:thumbs-down', element.$.thumbsDown.ironIcon);
+    assertEquals('false', element.$.thumbsDown.ariaPressed);
+
+    element.$.thumbsUp.click();
+    assertEquals('cr:thumbs-up-filled', element.$.thumbsUp.ironIcon);
+    assertEquals('true', element.$.thumbsUp.ariaPressed);
+    assertEquals('cr:thumbs-down', element.$.thumbsDown.ironIcon);
+    assertEquals('false', element.$.thumbsDown.ariaPressed);
+
+    element.$.thumbsUp.click();
+    assertEquals('cr:thumbs-up', element.$.thumbsUp.ironIcon);
+    assertEquals('false', element.$.thumbsUp.ariaPressed);
+    assertEquals('cr:thumbs-down', element.$.thumbsDown.ironIcon);
+    assertEquals('false', element.$.thumbsDown.ariaPressed);
+
+    element.$.thumbsDown.click();
+    assertEquals('cr:thumbs-up', element.$.thumbsUp.ironIcon);
+    assertEquals('false', element.$.thumbsUp.ariaPressed);
+    assertEquals('cr:thumbs-down-filled', element.$.thumbsDown.ironIcon);
+    assertEquals('true', element.$.thumbsDown.ariaPressed);
+
+    element.$.thumbsDown.click();
+    assertEquals('cr:thumbs-up', element.$.thumbsUp.ironIcon);
+    assertEquals('false', element.$.thumbsUp.ariaPressed);
+    assertEquals('cr:thumbs-down', element.$.thumbsDown.ironIcon);
+    assertEquals('false', element.$.thumbsDown.ariaPressed);
+  });
+
+  test('SendsEvent', async () => {
+    const thumbsUpEvent = eventToPromise('selected-option-changed', element);
+    element.$.thumbsUp.click();
+    const thumbsUpEventArgs = await thumbsUpEvent;
+    assertEquals(CrFeedbackOption.THUMBS_UP, thumbsUpEventArgs.detail.value);
+
+    const thumbsDownEvent = eventToPromise('selected-option-changed', element);
+    element.$.thumbsDown.click();
+    const thumbsDownEventArgs = await thumbsDownEvent;
+    assertEquals(
+        CrFeedbackOption.THUMBS_DOWN, thumbsDownEventArgs.detail.value);
+
+    const noThumbsEvent = eventToPromise('selected-option-changed', element);
+    element.$.thumbsDown.click();
+    const noThumbsEventArgs = await noThumbsEvent;
+    assertEquals(CrFeedbackOption.UNSPECIFIED, noThumbsEventArgs.detail.value);
+  });
+
+  test('AcceptsSelectedOptionBinding', () => {
+    element.selectedOption = CrFeedbackOption.THUMBS_UP;
+    assertEquals('cr:thumbs-up-filled', element.$.thumbsUp.ironIcon);
+    assertEquals('true', element.$.thumbsUp.ariaPressed);
+  });
+});
diff --git a/chrome/test/data/webui/side_panel/customize_chrome/appearance_test.ts b/chrome/test/data/webui/side_panel/customize_chrome/appearance_test.ts
index dceb78a..1f622e7 100644
--- a/chrome/test/data/webui/side_panel/customize_chrome/appearance_test.ts
+++ b/chrome/test/data/webui/side_panel/customize_chrome/appearance_test.ts
@@ -281,6 +281,7 @@
       assertStyle(appearanceElement.$.thirdPartyLinkButton, 'display', 'none');
       assertNotStyle(
           appearanceElement.$.uploadedImageButton, 'display', 'none');
+      assertStyle(appearanceElement.$.searchedImageButton, 'display', 'none');
       assertNotStyle(
           appearanceElement.$.setClassicChromeButton, 'display', 'none');
       assertStyle(appearanceElement.$.themeSnapshot, 'display', 'none');
@@ -300,5 +301,31 @@
       appearanceElement.$.uploadedImageButton.click();
       assertEquals(1, handler.getCallCount('chooseLocalCustomBackground'));
     });
+
+    test('searched image shows button', async () => {
+      const theme = createTheme();
+      theme.backgroundImage = createBackgroundImage('searched');
+      theme.backgroundImage.isUploadedImage = true;
+      theme.backgroundImage.localBackgroundId = {
+        low: BigInt(10),
+        high: BigInt(20),
+      };
+      callbackRouterRemote.setTheme(theme);
+      await callbackRouterRemote.$.flushForTesting();
+
+      assertStyle(appearanceElement.$.thirdPartyLinkButton, 'display', 'none');
+      assertStyle(appearanceElement.$.uploadedImageButton, 'display', 'none');
+      assertNotStyle(
+          appearanceElement.$.searchedImageButton, 'display', 'none');
+      assertNotStyle(
+          appearanceElement.$.setClassicChromeButton, 'display', 'none');
+      assertStyle(appearanceElement.$.themeSnapshot, 'display', 'none');
+      assertNotStyle(appearanceElement.$.chromeColors, 'display', 'none');
+
+      const clickEvent =
+          eventToPromise('wallpaper-search-click', appearanceElement);
+      appearanceElement.$.searchedImageButton.click();
+      await clickEvent;
+    });
   });
 });
diff --git a/chrome/test/data/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_test.ts b/chrome/test/data/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_test.ts
index f5f8f2f0..373a9e2 100644
--- a/chrome/test/data/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_test.ts
+++ b/chrome/test/data/webui/side_panel/customize_chrome/wallpaper_search/wallpaper_search_test.ts
@@ -140,6 +140,38 @@
       assertEquals('cr:expand-more', categoryLabelIcon.icon);
     });
 
+    test('check marks selected descriptorComboboxB option', async () => {
+      createWallpaperSearchElement({
+        descriptorA: [],
+        descriptorB: [
+          {label: 'one', imagePath: 'one.png'},
+          {label: 'two', imagePath: 'two.png'},
+        ],
+        descriptorC: [],
+      });
+      await flushTasks();
+
+      const optionCheckmarks =
+          wallpaperSearchElement.$.descriptorComboboxB.querySelectorAll(
+              'customize-chrome-check-mark-wrapper');
+      assertEquals(2, optionCheckmarks.length);
+
+      const option1Checkmark = optionCheckmarks[0]!;
+      const option2Checkmark = optionCheckmarks[1]!;
+      assertFalse(option1Checkmark.checked);
+      assertFalse(option2Checkmark.checked);
+
+      wallpaperSearchElement.$.descriptorComboboxB.value = 'one';
+      await flushTasks();
+      assertTrue(option1Checkmark.checked);
+      assertFalse(option2Checkmark.checked);
+
+      wallpaperSearchElement.$.descriptorComboboxB.value = 'two';
+      await flushTasks();
+      assertFalse(option1Checkmark.checked);
+      assertTrue(option2Checkmark.checked);
+    });
+
     test('check marks one item in descriptorMenuD at a time', async () => {
       createWallpaperSearchElementWithDescriptors();
       await flushTasks();
diff --git a/chromeos/ash/components/drivefs/drivefs_pinning_manager.cc b/chromeos/ash/components/drivefs/drivefs_pinning_manager.cc
index dc087dc..0b1ec3d 100644
--- a/chromeos/ash/components/drivefs/drivefs_pinning_manager.cc
+++ b/chromeos/ash/components/drivefs/drivefs_pinning_manager.cc
@@ -1237,9 +1237,8 @@
             << "Failed to enable Docs offline: " << error << " with status "
             << Quote(status);
         VLOG(1) << "Docs offline enablement status: " << Quote(status);
-        base::UmaHistogramExactLinear(
-            "FileBrowser.GoogleDrive.BulkPinning.EnableDocsOfflineResult",
-            1 - error, 2 - drive::FILE_ERROR_MAX);
+        base::UmaHistogramEnumeration(
+            "FileBrowser.GoogleDrive.BulkPinning.EnableDocsOffline", status);
       }));
 }
 
diff --git a/chromeos/ash/components/growth/BUILD.gn b/chromeos/ash/components/growth/BUILD.gn
index e685716..a733e53 100644
--- a/chromeos/ash/components/growth/BUILD.gn
+++ b/chromeos/ash/components/growth/BUILD.gn
@@ -7,6 +7,7 @@
 
 component("growth") {
   sources = [
+    "action_performer.h",
     "campaigns_manager.cc",
     "campaigns_manager.h",
     "campaigns_manager_client.h",
diff --git a/chromeos/ash/components/growth/action_performer.h b/chromeos/ash/components/growth/action_performer.h
new file mode 100644
index 0000000..611da52
--- /dev/null
+++ b/chromeos/ash/components/growth/action_performer.h
@@ -0,0 +1,53 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_ASH_COMPONENTS_GROWTH_ACTION_PERFORMER_H_
+#define CHROMEOS_ASH_COMPONENTS_GROWTH_ACTION_PERFORMER_H_
+
+#include "base/functional/callback.h"
+#include "base/values.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace growth {
+
+// The different actions that the Growth framework can run.
+enum class ActionType {
+  kInstallWebApp = 0,
+  kPinWebApp = 1,
+};
+
+enum class ActionResult {
+  kSuccess = 0,
+  kFailure = 1,
+};
+
+enum class ActionResultReason {
+  kParsingActionFailed = 0,
+
+  // For kInstallWebApp action
+  kWebAppProviderNotAvailable = 1,
+  kWebAppInstallFailedOther = 2,
+};
+
+// Abstract interface for the different actions that Growth framework
+// can make.
+class ActionPerformer {
+ public:
+  using Callback = base::OnceCallback<void(ActionResult,
+                                           absl::optional<ActionResultReason>)>;
+  ActionPerformer() = default;
+  ActionPerformer(const ActionPerformer&) = delete;
+  ActionPerformer& operator=(const ActionPerformer&) = delete;
+  virtual ~ActionPerformer() = default;
+
+  virtual void Run(const base::Value::Dict* action_params,
+                   Callback callback) = 0;
+
+  // Returns what type of action the subclass can run.
+  virtual ActionType ActionType() const = 0;
+};
+
+}  // namespace growth
+
+#endif  // CHROMEOS_ASH_COMPONENTS_GROWTH_ACTION_PERFORMER_H_
diff --git a/chromeos/ash/components/growth/campaigns_manager.h b/chromeos/ash/components/growth/campaigns_manager.h
index 773d730..5672452 100644
--- a/chromeos/ash/components/growth/campaigns_manager.h
+++ b/chromeos/ash/components/growth/campaigns_manager.h
@@ -10,6 +10,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/observer_list.h"
 #include "base/observer_list_types.h"
+#include "chromeos/ash/components/growth/action_performer.h"
 #include "chromeos/ash/components/growth/campaigns_manager_client.h"
 #include "chromeos/ash/components/growth/campaigns_matcher.h"
 #include "chromeos/ash/components/growth/campaigns_model.h"
@@ -56,6 +57,8 @@
   // that targets the given `slot`.
   const Campaign* GetCampaignBySlot(Slot slot) const;
 
+  ActionMap& actions_map() { return actions_map_; }
+
  private:
   // Triggred when campaigns component loaded.
   void OnCampaignsComponentLoaded(
@@ -80,6 +83,9 @@
   // Campaigns matcher for selecting campaigns based on criterias.
   CampaignsMatcher matcher_;
 
+  // Maps action type to the action.
+  ActionMap actions_map_;
+
   base::ObserverList<Observer> observers_;
 
   base::WeakPtrFactory<CampaignsManager> weak_factory_{this};
diff --git a/chromeos/ash/components/growth/campaigns_manager_client.h b/chromeos/ash/components/growth/campaigns_manager_client.h
index 681e3d74..6a69589 100644
--- a/chromeos/ash/components/growth/campaigns_manager_client.h
+++ b/chromeos/ash/components/growth/campaigns_manager_client.h
@@ -5,8 +5,12 @@
 #ifndef CHROMEOS_ASH_COMPONENTS_GROWTH_CAMPAIGNS_MANAGER_CLIENT_H_
 #define CHROMEOS_ASH_COMPONENTS_GROWTH_CAMPAIGNS_MANAGER_CLIENT_H_
 
+#include <map>
+#include <memory>
+
 #include "base/files/file_path.h"
 #include "base/functional/callback.h"
+#include "chromeos/ash/components/growth/action_performer.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
@@ -18,6 +22,8 @@
 using CampaignComponentLoadedCallback = base::OnceCallback<void(
     const absl::optional<const base::FilePath>& file_path)>;
 
+using ActionMap = std::map<ActionType, std::unique_ptr<ActionPerformer>>;
+
 class CampaignsManagerClient {
  public:
   CampaignsManagerClient() = default;
@@ -44,6 +50,10 @@
 
   // Get demo mode app component version.
   virtual const base::Version& GetDemoModeAppVersion() const = 0;
+
+  // Get the implementations for the various Actions on the growth
+  // framework.
+  virtual ActionMap GetCampaignsActions() const = 0;
 };
 
 }  // namespace growth
diff --git a/chromeos/ash/components/growth/mock_campaigns_manager_client.h b/chromeos/ash/components/growth/mock_campaigns_manager_client.h
index 887485f9..cced2c02 100644
--- a/chromeos/ash/components/growth/mock_campaigns_manager_client.h
+++ b/chromeos/ash/components/growth/mock_campaigns_manager_client.h
@@ -20,13 +20,19 @@
   ~MockCampaignsManagerClient() override;
 
   // CampaignsManagerClient:
-  MOCK_METHOD1(LoadCampaignsComponent,
-               void(CampaignComponentLoadedCallback callback));
-  MOCK_CONST_METHOD0(IsDeviceInDemoMode, bool());
-  MOCK_CONST_METHOD0(IsCloudGamingDevice, bool());
-  MOCK_CONST_METHOD0(IsFeatureAwareDevice, bool());
-  MOCK_CONST_METHOD0(GetApplicationLocale, std::string&());
-  MOCK_CONST_METHOD0(GetDemoModeAppVersion, const base::Version&());
+  MOCK_METHOD(void,
+              LoadCampaignsComponent,
+              (CampaignComponentLoadedCallback callback),
+              (override));
+  MOCK_METHOD(bool, IsDeviceInDemoMode, (), (const, override));
+  MOCK_METHOD(bool, IsCloudGamingDevice, (), (const, override));
+  MOCK_METHOD(bool, IsFeatureAwareDevice, (), (const, override));
+  MOCK_METHOD(std::string&, GetApplicationLocale, (), (const, override));
+  MOCK_METHOD(const base::Version&,
+              GetDemoModeAppVersion,
+              (),
+              (const, override));
+  MOCK_METHOD(ActionMap, GetCampaignsActions, (), (const, override));
 };
 
 }  // namespace growth
diff --git a/chromeos/ash/components/network/cellular_policy_handler.cc b/chromeos/ash/components/network/cellular_policy_handler.cc
index 0bdd534..1c81fea4 100644
--- a/chromeos/ash/components/network/cellular_policy_handler.cc
+++ b/chromeos/ash/components/network/cellular_policy_handler.cc
@@ -294,6 +294,19 @@
     return;
   }
 
+  if (!HasNonCellularInternetConnectivity()) {
+    NET_LOG(ERROR)
+        << "Failed to install the policy eSIM profile due to missing a "
+        << "non-cellular internet connection: "
+        << GetCurrentActivationCode().ToErrorString();
+    auto current_request = std::move(remaining_install_requests_.front());
+    PopRequest();
+    ScheduleRetryAndProcessRequests(
+        std::move(current_request),
+        InstallRetryReason::kMissingNonCellularConnectivity);
+    return;
+  }
+
   if (need_refresh_profile_list_) {
     // Profile list for current EUICC may not have been refreshed, so explicitly
     // refresh profile list before processing installation requests.
@@ -324,19 +337,6 @@
     return;
   }
 
-  if (!HasNonCellularInternetConnectivity()) {
-    NET_LOG(ERROR)
-        << "Failed to install the policy eSIM profile due to missing a "
-        << "non-cellular internet connection: "
-        << GetCurrentActivationCode().ToErrorString();
-    auto current_request = std::move(remaining_install_requests_.front());
-    PopRequest();
-    ScheduleRetryAndProcessRequests(
-        std::move(current_request),
-        InstallRetryReason::kMissingNonCellularConnectivity);
-    return;
-  }
-
   NET_LOG(EVENT) << "Installing policy eSIM profile: "
                  << GetCurrentActivationCode().ToString();
 
diff --git a/chromeos/crosapi/mojom/app_service_types.mojom b/chromeos/crosapi/mojom/app_service_types.mojom
index 5cd33b37..d8628b2 100644
--- a/chromeos/crosapi/mojom/app_service_types.mojom
+++ b/chromeos/crosapi/mojom/app_service_types.mojom
@@ -473,6 +473,7 @@
   [MinVersion=10] kFromProtocolHandler,          // Protocol handler.
   [MinVersion=10] kFromUrlHandler,               // Url handler.
   [MinVersion=11] kFromSysTrayCalendar,          // System Tray Calendar.
+  [MinVersion=12] kFromInstaller,                // Installation UI.
 };
 
 [Stable, Extensible]
diff --git a/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc b/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
index 87250a7..d0b83ab 100644
--- a/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
+++ b/chromeos/crosapi/mojom/app_service_types_mojom_traits.cc
@@ -974,6 +974,8 @@
       return crosapi::mojom::LaunchSource::kFromUrlHandler;
     case apps::LaunchSource::kFromSysTrayCalendar:
       return crosapi::mojom::LaunchSource::kFromSysTrayCalendar;
+    case apps::LaunchSource::kFromInstaller:
+      return crosapi::mojom::LaunchSource::kFromInstaller;
     // TODO(crbug.com/1343692): Make lock screen apps use lacros browser.
     case apps::LaunchSource::kFromLockScreen:
     case apps::LaunchSource::kFromCommandLine:
@@ -1084,6 +1086,9 @@
     case crosapi::mojom::LaunchSource::kFromSysTrayCalendar:
       *output = apps::LaunchSource::kFromSysTrayCalendar;
       return true;
+    case crosapi::mojom::LaunchSource::kFromInstaller:
+      *output = apps::LaunchSource::kFromInstaller;
+      return true;
   }
 
   NOTREACHED();
diff --git a/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc b/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
index bd6d45c..acae285 100644
--- a/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
+++ b/chromeos/crosapi/mojom/app_service_types_mojom_traits_unittest.cc
@@ -1076,6 +1076,14 @@
             input, output));
     EXPECT_EQ(output, input);
   }
+  {
+    input = apps::LaunchSource::kFromInstaller;
+    apps::LaunchSource output;
+    ASSERT_TRUE(
+        mojo::test::SerializeAndDeserialize<crosapi::mojom::LaunchSource>(
+            input, output));
+    EXPECT_EQ(output, input);
+  }
 }
 
 TEST(AppServiceTypesMojomTraitsTest, RoundTripPermissions) {
diff --git a/chromeos/profiles/bigcore.afdo.newest.txt b/chromeos/profiles/bigcore.afdo.newest.txt
index f203aed..4a15d87d 100644
--- a/chromeos/profiles/bigcore.afdo.newest.txt
+++ b/chromeos/profiles/bigcore.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-bigcore-120-6085.0-1698658595-benchmark-121.0.6105.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-bigcore-121-6099.8-1699872611-benchmark-121.0.6126.0-r1-redacted.afdo.xz
diff --git a/clank b/clank
index 5649615..0b6331f 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit 5649615b9c2b9521f10acd5a4d48a729225b9474
+Subproject commit 0b6331f42591e5867461997a30f034db138ebae2
diff --git a/components/attribution_reporting/BUILD.gn b/components/attribution_reporting/BUILD.gn
index 1309227..ffd3f61 100644
--- a/components/attribution_reporting/BUILD.gn
+++ b/components/attribution_reporting/BUILD.gn
@@ -308,12 +308,6 @@
               "namespace attribution_reporting { class EventReportWindows; }"
         },
         {
-          mojom = "attribution_reporting.mojom.TriggerConfig"
-          cpp = "::attribution_reporting::TriggerConfig"
-          forward_declaration =
-              "namespace attribution_reporting { class TriggerConfig; }"
-        },
-        {
           mojom = "attribution_reporting.mojom.TriggerSpec"
           cpp = "::attribution_reporting::TriggerSpec"
           forward_declaration =
diff --git a/components/attribution_reporting/registration.mojom b/components/attribution_reporting/registration.mojom
index 1781943f..cf39cce 100644
--- a/components/attribution_reporting/registration.mojom
+++ b/components/attribution_reporting/registration.mojom
@@ -88,12 +88,6 @@
   map<uint32, uint8> trigger_data_indices;
 };
 
-// Configures a source's output space.
-// https://github.com/WICG/attribution-reporting-api/blob/main/flexible_event_config.md
-struct TriggerConfig {
-  TriggerDataMatching trigger_data_matching;
-};
-
 struct SourceRegistration {
   DestinationSet destinations;
 
@@ -128,7 +122,8 @@
   // Specifies whether to enable verbose debug reporting.
   bool debug_reporting = false;
 
-  TriggerConfig trigger_config;
+  // Controls how trigger data is matched against the source's trigger specs.
+  TriggerDataMatching trigger_data_matching;
 };
 
 // Mojo representation of the trigger configuration provided by a reporting
diff --git a/components/attribution_reporting/registration_mojom_traits.cc b/components/attribution_reporting/registration_mojom_traits.cc
index 6f6fde5..449bd82b 100644
--- a/components/attribution_reporting/registration_mojom_traits.cc
+++ b/components/attribution_reporting/registration_mojom_traits.cc
@@ -207,15 +207,6 @@
 }
 
 // static
-bool StructTraits<attribution_reporting::mojom::TriggerConfigDataView,
-                  attribution_reporting::TriggerConfig>::
-    Read(attribution_reporting::mojom::TriggerConfigDataView data,
-         attribution_reporting::TriggerConfig* out) {
-  *out = attribution_reporting::TriggerConfig(data.trigger_data_matching());
-  return true;
-}
-
-// static
 bool StructTraits<attribution_reporting::mojom::SourceRegistrationDataView,
                   attribution_reporting::SourceRegistration>::
     Read(attribution_reporting::mojom::SourceRegistrationDataView data,
@@ -244,10 +235,6 @@
     return false;
   }
 
-  if (!data.ReadTriggerConfig(&out->trigger_config)) {
-    return false;
-  }
-
   if (!out->max_event_level_reports.SetIfValid(
           data.max_event_level_reports())) {
     return false;
@@ -257,6 +244,7 @@
   out->priority = data.priority();
   out->debug_key = data.debug_key();
   out->debug_reporting = data.debug_reporting();
+  out->trigger_data_matching = data.trigger_data_matching();
   return out->IsValid();
 }
 
diff --git a/components/attribution_reporting/registration_mojom_traits.h b/components/attribution_reporting/registration_mojom_traits.h
index 1ea36686..57ea9353 100644
--- a/components/attribution_reporting/registration_mojom_traits.h
+++ b/components/attribution_reporting/registration_mojom_traits.h
@@ -162,19 +162,6 @@
 
 template <>
 struct COMPONENT_EXPORT(ATTRIBUTION_REPORTING_REGISTRATION_MOJOM_TRAITS)
-    StructTraits<attribution_reporting::mojom::TriggerConfigDataView,
-                 attribution_reporting::TriggerConfig> {
-  static attribution_reporting::mojom::TriggerDataMatching
-  trigger_data_matching(const attribution_reporting::TriggerConfig& config) {
-    return config.trigger_data_matching();
-  }
-
-  static bool Read(attribution_reporting::mojom::TriggerConfigDataView data,
-                   attribution_reporting::TriggerConfig* out);
-};
-
-template <>
-struct COMPONENT_EXPORT(ATTRIBUTION_REPORTING_REGISTRATION_MOJOM_TRAITS)
     StructTraits<attribution_reporting::mojom::SourceRegistrationDataView,
                  attribution_reporting::SourceRegistration> {
   static const attribution_reporting::DestinationSet& destinations(
@@ -232,9 +219,10 @@
     return source.debug_reporting;
   }
 
-  static const attribution_reporting::TriggerConfig& trigger_config(
+  static attribution_reporting::mojom::TriggerDataMatching
+  trigger_data_matching(
       const attribution_reporting::SourceRegistration& source) {
-    return source.trigger_config;
+    return source.trigger_data_matching;
   }
 
   static bool Read(
diff --git a/components/attribution_reporting/source_registration.cc b/components/attribution_reporting/source_registration.cc
index 2666787..1c96e89 100644
--- a/components/attribution_reporting/source_registration.cc
+++ b/components/attribution_reporting/source_registration.cc
@@ -142,7 +142,8 @@
   ASSIGN_OR_RETURN(result.max_event_level_reports,
                    MaxEventLevelReports::Parse(registration, source_type));
 
-  ASSIGN_OR_RETURN(result.trigger_config, TriggerConfig::Parse(registration));
+  ASSIGN_OR_RETURN(result.trigger_data_matching,
+                   ParseTriggerDataMatching(registration));
 
   result.debug_key = ParseDebugKey(registration);
 
@@ -205,7 +206,7 @@
 
   max_event_level_reports.Serialize(dict);
 
-  trigger_config.Serialize(dict);
+  Serialize(dict, trigger_data_matching);
 
   return dict;
 }
diff --git a/components/attribution_reporting/source_registration.h b/components/attribution_reporting/source_registration.h
index 6e9134b..fff4ece 100644
--- a/components/attribution_reporting/source_registration.h
+++ b/components/attribution_reporting/source_registration.h
@@ -20,7 +20,7 @@
 #include "components/attribution_reporting/max_event_level_reports.h"
 #include "components/attribution_reporting/source_registration_error.mojom-forward.h"
 #include "components/attribution_reporting/source_type.mojom-forward.h"
-#include "components/attribution_reporting/trigger_config.h"
+#include "components/attribution_reporting/trigger_data_matching.mojom.h"
 #include "mojo/public/cpp/bindings/default_construct_tag.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -73,7 +73,8 @@
   absl::optional<uint64_t> debug_key;
   AggregationKeys aggregation_keys;
   bool debug_reporting = false;
-  TriggerConfig trigger_config;
+  mojom::TriggerDataMatching trigger_data_matching =
+      mojom::TriggerDataMatching::kModulus;
 };
 
 }  // namespace attribution_reporting
diff --git a/components/attribution_reporting/source_registration_unittest.cc b/components/attribution_reporting/source_registration_unittest.cc
index 2e6f44e..bcee25d 100644
--- a/components/attribution_reporting/source_registration_unittest.cc
+++ b/components/attribution_reporting/source_registration_unittest.cc
@@ -21,7 +21,7 @@
 #include "components/attribution_reporting/source_registration_error.mojom.h"
 #include "components/attribution_reporting/source_type.mojom.h"
 #include "components/attribution_reporting/test_utils.h"
-#include "components/attribution_reporting/trigger_config.h"
+#include "components/attribution_reporting/trigger_data_matching.mojom.h"
 #include "net/base/schemeful_site.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -87,7 +87,8 @@
               Field(&SourceRegistration::debug_key, absl::nullopt),
               Field(&SourceRegistration::aggregation_keys, AggregationKeys()),
               Field(&SourceRegistration::debug_reporting, false),
-              Field(&SourceRegistration::trigger_config, TriggerConfig()))),
+              Field(&SourceRegistration::trigger_data_matching,
+                    mojom::TriggerDataMatching::kModulus))),
       },
       {
           "source_event_id_valid",
@@ -362,7 +363,8 @@
             "expiry": 2592000,
             "max_event_level_reports": 0,
             "priority": "0",
-            "source_event_id": "0"
+            "source_event_id": "0",
+            "trigger_data_matching": "modulus"
           })json",
       },
       {
@@ -378,6 +380,7 @@
                 r.priority = -6;
                 r.source_event_id = 7;
                 r.max_event_level_reports = MaxEventLevelReports(8);
+                r.trigger_data_matching = mojom::TriggerDataMatching::kExact;
               }),
           R"json({
             "aggregatable_report_window": 1,
@@ -394,6 +397,7 @@
             "priority": "-6",
             "source_event_id": "7",
             "max_event_level_reports": 8,
+            "trigger_data_matching": "exact"
           })json",
       },
   };
diff --git a/components/attribution_reporting/test_utils.cc b/components/attribution_reporting/test_utils.cc
index b76eee5..0079eaa5 100644
--- a/components/attribution_reporting/test_utils.cc
+++ b/components/attribution_reporting/test_utils.cc
@@ -105,12 +105,6 @@
              << ", debug_reporting=" << item.debug_reporting << "}";
 }
 
-std::ostream& operator<<(std::ostream& out, const TriggerConfig& config) {
-  base::Value::Dict dict;
-  config.SerializeForTesting(dict);
-  return out << dict;
-}
-
 std::ostream& operator<<(std::ostream& out, const TriggerSpec& spec) {
   return out << spec.ToJson();
 }
diff --git a/components/attribution_reporting/test_utils.h b/components/attribution_reporting/test_utils.h
index 8b1a97b..9dd9583 100644
--- a/components/attribution_reporting/test_utils.h
+++ b/components/attribution_reporting/test_utils.h
@@ -61,8 +61,6 @@
 
 std::ostream& operator<<(std::ostream&, const OsRegistrationItem&);
 
-std::ostream& operator<<(std::ostream&, const TriggerConfig&);
-
 std::ostream& operator<<(std::ostream&, const TriggerSpec&);
 
 std::ostream& operator<<(std::ostream&, const TriggerSpecs&);
diff --git a/components/attribution_reporting/trigger_config.cc b/components/attribution_reporting/trigger_config.cc
index 078dedf..80079b4 100644
--- a/components/attribution_reporting/trigger_config.cc
+++ b/components/attribution_reporting/trigger_config.cc
@@ -44,37 +44,6 @@
 // https://wicg.github.io/attribution-reporting-api/#max-distinct-trigger-data-per-source
 constexpr uint8_t kMaxTriggerDataPerSource = 32;
 
-base::expected<TriggerDataMatching, SourceRegistrationError>
-ParseTriggerDataMatching(const base::Value& value) {
-  const std::string* str = value.GetIfString();
-  if (!str) {
-    return base::unexpected(
-        SourceRegistrationError::kTriggerDataMatchingWrongType);
-  } else if (*str == kTriggerDataMatchingExact) {
-    return TriggerDataMatching::kExact;
-  } else if (*str == kTriggerDataMatchingModulus) {
-    return TriggerDataMatching::kModulus;
-  } else {
-    return base::unexpected(
-        SourceRegistrationError::kTriggerDataMatchingUnknownValue);
-  }
-}
-
-std::string SerializeTriggerDataMatching(TriggerDataMatching v) {
-  switch (v) {
-    case TriggerDataMatching::kExact:
-      return kTriggerDataMatchingExact;
-    case TriggerDataMatching::kModulus:
-      return kTriggerDataMatchingModulus;
-  }
-}
-
-void SerializeTriggerConfig(const TriggerConfig& config,
-                            base::Value::Dict& dict) {
-  dict.Set(kTriggerDataMatching,
-           SerializeTriggerDataMatching(config.trigger_data_matching()));
-}
-
 // If `dict` contains a valid "trigger_data" field, writes the resulting keys
 // into `trigger_data_indices` using `spec_index` as the value.
 // `trigger_data_indices` is also used to perform deduplication checks.
@@ -164,47 +133,42 @@
 
 }  // namespace
 
-TriggerConfig::TriggerConfig() = default;
-
-TriggerConfig::TriggerConfig(TriggerDataMatching trigger_data_matching)
-    : trigger_data_matching_(trigger_data_matching) {}
-
-TriggerConfig::~TriggerConfig() = default;
-
-TriggerConfig::TriggerConfig(const TriggerConfig&) = default;
-
-TriggerConfig& TriggerConfig::operator=(const TriggerConfig&) = default;
-
-TriggerConfig::TriggerConfig(TriggerConfig&&) = default;
-
-TriggerConfig& TriggerConfig::operator=(TriggerConfig&&) = default;
-
-// static
-base::expected<TriggerConfig, SourceRegistrationError> TriggerConfig::Parse(
-    const base::Value::Dict& dict) {
+base::expected<TriggerDataMatching, SourceRegistrationError>
+ParseTriggerDataMatching(const base::Value::Dict& dict) {
   if (!base::FeatureList::IsEnabled(
           features::kAttributionReportingTriggerConfig)) {
-    return TriggerConfig();
+    return TriggerDataMatching::kModulus;
   }
 
-  TriggerConfig config;
-  if (const base::Value* value = dict.Find(kTriggerDataMatching)) {
-    ASSIGN_OR_RETURN(config.trigger_data_matching_,
-                     ParseTriggerDataMatching(*value));
+  const base::Value* value = dict.Find(kTriggerDataMatching);
+  if (!value) {
+    return TriggerDataMatching::kModulus;
   }
 
-  return config;
-}
-
-void TriggerConfig::Serialize(base::Value::Dict& dict) const {
-  if (base::FeatureList::IsEnabled(
-          features::kAttributionReportingTriggerConfig)) {
-    SerializeTriggerConfig(*this, dict);
+  const std::string* str = value->GetIfString();
+  if (!str) {
+    return base::unexpected(
+        SourceRegistrationError::kTriggerDataMatchingWrongType);
+  } else if (*str == kTriggerDataMatchingExact) {
+    return TriggerDataMatching::kExact;
+  } else if (*str == kTriggerDataMatchingModulus) {
+    return TriggerDataMatching::kModulus;
+  } else {
+    return base::unexpected(
+        SourceRegistrationError::kTriggerDataMatchingUnknownValue);
   }
 }
 
-void TriggerConfig::SerializeForTesting(base::Value::Dict& dict) const {
-  SerializeTriggerConfig(*this, dict);
+void Serialize(base::Value::Dict& dict,
+               TriggerDataMatching trigger_data_matching) {
+  switch (trigger_data_matching) {
+    case TriggerDataMatching::kExact:
+      dict.Set(kTriggerDataMatching, kTriggerDataMatchingExact);
+      break;
+    case TriggerDataMatching::kModulus:
+      dict.Set(kTriggerDataMatching, kTriggerDataMatchingModulus);
+      break;
+  }
 }
 
 TriggerSpec::TriggerSpec() = default;
diff --git a/components/attribution_reporting/trigger_config.h b/components/attribution_reporting/trigger_config.h
index 903f444..78c77c5 100644
--- a/components/attribution_reporting/trigger_config.h
+++ b/components/attribution_reporting/trigger_config.h
@@ -20,7 +20,7 @@
 #include "components/attribution_reporting/event_report_windows.h"
 #include "components/attribution_reporting/source_registration_error.mojom-forward.h"
 #include "components/attribution_reporting/source_type.mojom-forward.h"
-#include "components/attribution_reporting/trigger_data_matching.mojom.h"
+#include "components/attribution_reporting/trigger_data_matching.mojom-forward.h"
 
 namespace base {
 class TimeDelta;
@@ -198,40 +198,12 @@
   std::vector<TriggerSpec> specs_;
 };
 
-class COMPONENT_EXPORT(ATTRIBUTION_REPORTING) TriggerConfig {
- public:
-  static base::expected<TriggerConfig, mojom::SourceRegistrationError> Parse(
-      const base::Value::Dict&);
+COMPONENT_EXPORT(ATTRIBUTION_REPORTING)
+base::expected<mojom::TriggerDataMatching, mojom::SourceRegistrationError>
+ParseTriggerDataMatching(const base::Value::Dict&);
 
-  TriggerConfig();
-
-  explicit TriggerConfig(mojom::TriggerDataMatching);
-
-  ~TriggerConfig();
-
-  TriggerConfig(const TriggerConfig&);
-  TriggerConfig& operator=(const TriggerConfig&);
-
-  TriggerConfig(TriggerConfig&&);
-  TriggerConfig& operator=(TriggerConfig&&);
-
-  mojom::TriggerDataMatching trigger_data_matching() const {
-    return trigger_data_matching_;
-  }
-
-  // Serializes into the given dictionary iff
-  // `features::kAttributionReportingTriggerConfig` is enabled.
-  void Serialize(base::Value::Dict&) const;
-
-  // Always serializes regardless of the above feature status.
-  void SerializeForTesting(base::Value::Dict&) const;
-
-  friend bool operator==(const TriggerConfig&, const TriggerConfig&) = default;
-
- private:
-  mojom::TriggerDataMatching trigger_data_matching_ =
-      mojom::TriggerDataMatching::kModulus;
-};
+COMPONENT_EXPORT(ATTRIBUTION_REPORTING)
+void Serialize(base::Value::Dict&, mojom::TriggerDataMatching);
 
 }  // namespace attribution_reporting
 
diff --git a/components/attribution_reporting/trigger_config_unittest.cc b/components/attribution_reporting/trigger_config_unittest.cc
index 9da9581..240d3334 100644
--- a/components/attribution_reporting/trigger_config_unittest.cc
+++ b/components/attribution_reporting/trigger_config_unittest.cc
@@ -40,62 +40,48 @@
 using ::testing::Property;
 using ::testing::SizeIs;
 
-TEST(TriggerConfigTest, Parse) {
+TEST(TriggerDataMatchingTest, Parse) {
   const struct {
     const char* desc;
     const char* json;
-    ::testing::Matcher<base::expected<TriggerConfig, SourceRegistrationError>>
+    ::testing::Matcher<
+        base::expected<TriggerDataMatching, SourceRegistrationError>>
         disabled_matches;
-    ::testing::Matcher<base::expected<TriggerConfig, SourceRegistrationError>>
+    ::testing::Matcher<
+        base::expected<TriggerDataMatching, SourceRegistrationError>>
         enabled_matches;
   } kTestCases[] = {
       {
           .desc = "missing",
           .json = R"json({})json",
-          .disabled_matches =
-              ValueIs(Property(&TriggerConfig::trigger_data_matching,
-                               TriggerDataMatching::kModulus)),
-          .enabled_matches =
-              ValueIs(Property(&TriggerConfig::trigger_data_matching,
-                               TriggerDataMatching::kModulus)),
+          .disabled_matches = ValueIs(TriggerDataMatching::kModulus),
+          .enabled_matches = ValueIs(TriggerDataMatching::kModulus),
       },
       {
           .desc = "wrong_type",
           .json = R"json({"trigger_data_matching":1})json",
-          .disabled_matches =
-              ValueIs(Property(&TriggerConfig::trigger_data_matching,
-                               TriggerDataMatching::kModulus)),
+          .disabled_matches = ValueIs(TriggerDataMatching::kModulus),
           .enabled_matches =
               ErrorIs(SourceRegistrationError::kTriggerDataMatchingWrongType),
       },
       {
           .desc = "invalid_value",
           .json = R"json({"trigger_data_matching":"MODULUS"})json",
-          .disabled_matches =
-              ValueIs(Property(&TriggerConfig::trigger_data_matching,
-                               TriggerDataMatching::kModulus)),
+          .disabled_matches = ValueIs(TriggerDataMatching::kModulus),
           .enabled_matches = ErrorIs(
               SourceRegistrationError::kTriggerDataMatchingUnknownValue),
       },
       {
           .desc = "valid_modulus",
           .json = R"json({"trigger_data_matching":"modulus"})json",
-          .disabled_matches =
-              ValueIs(Property(&TriggerConfig::trigger_data_matching,
-                               TriggerDataMatching::kModulus)),
-          .enabled_matches =
-              ValueIs(Property(&TriggerConfig::trigger_data_matching,
-                               TriggerDataMatching::kModulus)),
+          .disabled_matches = ValueIs(TriggerDataMatching::kModulus),
+          .enabled_matches = ValueIs(TriggerDataMatching::kModulus),
       },
       {
           .desc = "valid_exact",
           .json = R"json({"trigger_data_matching":"exact"})json",
-          .disabled_matches =
-              ValueIs(Property(&TriggerConfig::trigger_data_matching,
-                               TriggerDataMatching::kModulus)),
-          .enabled_matches =
-              ValueIs(Property(&TriggerConfig::trigger_data_matching,
-                               TriggerDataMatching::kExact)),
+          .disabled_matches = ValueIs(TriggerDataMatching::kModulus),
+          .enabled_matches = ValueIs(TriggerDataMatching::kExact),
       },
   };
 
@@ -106,7 +92,7 @@
 
     {
       SCOPED_TRACE("disabled");
-      EXPECT_THAT(TriggerConfig::Parse(dict), test_case.disabled_matches);
+      EXPECT_THAT(ParseTriggerDataMatching(dict), test_case.disabled_matches);
     }
 
     {
@@ -115,25 +101,22 @@
       base::test::ScopedFeatureList scoped_feature_list(
           features::kAttributionReportingTriggerConfig);
 
-      EXPECT_THAT(TriggerConfig::Parse(dict), test_case.enabled_matches);
+      EXPECT_THAT(ParseTriggerDataMatching(dict), test_case.enabled_matches);
     }
   }
 }
 
-TEST(TriggerConfigTest, Serialize) {
+TEST(TriggerDataMatchingTest, Serialize) {
   const struct {
     TriggerDataMatching trigger_data_matching;
-    base::Value::Dict disabled_expected;
-    base::Value::Dict enabled_expected;
+    base::Value::Dict expected;
   } kTestCases[] = {
       {
           TriggerDataMatching::kModulus,
-          base::Value::Dict(),
           base::Value::Dict().Set("trigger_data_matching", "modulus"),
       },
       {
           TriggerDataMatching::kExact,
-          base::Value::Dict(),
           base::Value::Dict().Set("trigger_data_matching", "exact"),
       },
   };
@@ -141,24 +124,9 @@
   for (const auto& test_case : kTestCases) {
     SCOPED_TRACE(test_case.trigger_data_matching);
 
-    {
-      SCOPED_TRACE("disabled");
-
-      base::Value::Dict dict;
-      TriggerConfig(test_case.trigger_data_matching).Serialize(dict);
-      EXPECT_EQ(dict, test_case.disabled_expected);
-    }
-
-    {
-      SCOPED_TRACE("enabled");
-
-      base::test::ScopedFeatureList scoped_feature_list(
-          features::kAttributionReportingTriggerConfig);
-
-      base::Value::Dict dict;
-      TriggerConfig(test_case.trigger_data_matching).Serialize(dict);
-      EXPECT_EQ(dict, test_case.enabled_expected);
-    }
+    base::Value::Dict dict;
+    Serialize(dict, test_case.trigger_data_matching);
+    EXPECT_EQ(dict, test_case.expected);
   }
 }
 
diff --git a/components/autofill/core/browser/data_model/autofill_profile_comparator_unittest.cc b/components/autofill/core/browser/data_model/autofill_profile_comparator_unittest.cc
index 945df5f..97e9b4b 100644
--- a/components/autofill/core/browser/data_model/autofill_profile_comparator_unittest.cc
+++ b/components/autofill/core/browser/data_model/autofill_profile_comparator_unittest.cc
@@ -451,6 +451,8 @@
   EXPECT_EQ(u"timothe noel etienne perier",
             AutofillProfileComparator::NormalizeForComparison(
                 u"Timothé-Noël Étienne Périer"));
+  EXPECT_EQ(u"strasse",
+            AutofillProfileComparator::NormalizeForComparison(u"Straße"));
   // NOP.
   EXPECT_EQ(std::u16string(), AutofillProfileComparator::NormalizeForComparison(
                                   std::u16string()));
@@ -1129,6 +1131,39 @@
   MergeAddressesAndExpect(p2, p1, expected);
 }
 
+// The intention of this test is to verify that "Straße" and "Str."" ar
+// considered equivalent, which requires a normalization of ß to ss followed by
+// a rewrite of "strasse" to "str".
+TEST_F(AutofillProfileComparatorTest, MergeAddressesWithRewriteDE) {
+  AutofillProfile p1 = CreateProfileWithAddress("Erika-Mann-Straße 33", "APP 3",
+                                                "München", "", "80636", "DE");
+
+  p1.SetRawInfo(autofill::ADDRESS_HOME_STREET_NAME, u"Erika-Mann-Straße");
+  p1.SetRawInfo(autofill::ADDRESS_HOME_HOUSE_NUMBER, u"33");
+  p1.SetRawInfo(autofill::ADDRESS_HOME_SUBPREMISE, u"APP 3");
+
+  AutofillProfile p2 = CreateProfileWithAddress("Erika-Mann-Str. 33", "",
+                                                "Munchen", "", "80636", "DE");
+  p2.SetRawInfo(autofill::ADDRESS_HOME_STREET_NAME, u"Erika-Mann-Str");
+  p2.SetRawInfo(autofill::ADDRESS_HOME_HOUSE_NUMBER, u"33");
+
+  p2.set_use_date(p1.use_date() + base::Minutes(1));
+
+  Address expected(kLegacyHierarchyCountryCode);
+  // The longer string wins.
+  expected.SetRawInfo(ADDRESS_HOME_LINE1, u"Erika-Mann-Straße 33");
+  // Extra information.
+  expected.SetRawInfo(ADDRESS_HOME_LINE2, u"APP 3");
+  // The most recent string wins.
+  expected.SetRawInfo(ADDRESS_HOME_CITY, u"Munchen");
+  expected.SetRawInfo(ADDRESS_HOME_STATE, u"");
+  expected.SetRawInfo(ADDRESS_HOME_ZIP, u"80636");
+  expected.SetRawInfo(ADDRESS_HOME_COUNTRY, u"DE");
+
+  MergeAddressesAndExpect(p1, p2, expected);
+  MergeAddressesAndExpect(p2, p1, expected);
+}
+
 TEST_F(AutofillProfileComparatorTest,
        MergeAddressesDependentLocalityAndSortingCode) {
   AutofillProfile p1 = CreateProfileWithAddress(
diff --git a/components/autofill/core/browser/data_model/borrowed_transliterator.cc b/components/autofill/core/browser/data_model/borrowed_transliterator.cc
index 7ab7e0b1..0c3df92 100644
--- a/components/autofill/core/browser/data_model/borrowed_transliterator.cc
+++ b/components/autofill/core/browser/data_model/borrowed_transliterator.cc
@@ -28,26 +28,37 @@
 }
 
 // static
-std::unique_ptr<icu::Transliterator>
-BorrowedTransliterator::CreateTransliterator() {
-  UErrorCode status = U_ZERO_ERROR;
-  std::unique_ptr<icu::Transliterator> transliterator(
-      icu::Transliterator::createInstance(
-          "NFD; [:Nonspacing Mark:] Remove; Lower; NFC", UTRANS_FORWARD,
-          status));
-  if (U_FAILURE(status) || transliterator == nullptr) {
-    // TODO(rogerm): Add a histogram to count how often this happens.
-    LOG(ERROR) << "Failed to create ICU Transliterator: "
-               << u_errorName(status);
-  }
-  return transliterator;
-}
-
-// static
 std::unique_ptr<icu::Transliterator>&
 BorrowedTransliterator::GetTransliterator() {
-  static base::NoDestructor<std::unique_ptr<icu::Transliterator>> instance(
-      CreateTransliterator());
+  static base::NoDestructor<std::unique_ptr<icu::Transliterator>> instance([] {
+    UErrorCode status = U_ZERO_ERROR;
+    UParseError parse_error;
+    // This is happening in the following rule:
+    // "::NFD;" performs a decomposition and normalization. (â becomes a and  ̂)
+    // "::[:Nonspacing Mark:] Remove;" removes the " ̂"
+    // "::Lower;" converts the result to lower case
+    // "::NFC;" re-composes the decomposed characters
+    // "::Latin-ASCII;" converts various other Latin characters to an ASCII
+    //   representation (e.g. "ł", which does not get decomposed, to "l"; "ß" to
+    //   "ss").
+    //
+    // It would be interesting to transliterate umlauts according to DIN 5007-2
+    // (::de-ASCII) for German addresses ("ö" to "oe"), but that does not match
+    // our assumptions from
+    // components/autofill/core/browser/geo/address_rewrite_rules/.
+    icu::UnicodeString transliteration_rules =
+        "::NFD; ::[:Nonspacing Mark:] Remove; ::Lower; ::NFC; ::Latin-ASCII;";
+    std::unique_ptr<icu::Transliterator> transliterator(
+        icu::Transliterator::createFromRules(
+            "NormalizeForAddresses", transliteration_rules, UTRANS_FORWARD,
+            parse_error, status));
+    if (U_FAILURE(status) || transliterator == nullptr) {
+      // TODO(rogerm): Add a histogram to count how often this happens.
+      LOG(ERROR) << "Failed to create ICU Transliterator: "
+                 << u_errorName(status);
+    }
+    return transliterator;
+  }());
   return *instance;
 }
 
diff --git a/components/autofill/core/browser/data_model/borrowed_transliterator.h b/components/autofill/core/browser/data_model/borrowed_transliterator.h
index 89c07627..f90d4b60 100644
--- a/components/autofill/core/browser/data_model/borrowed_transliterator.h
+++ b/components/autofill/core/browser/data_model/borrowed_transliterator.h
@@ -25,18 +25,18 @@
  private:
   static base::Lock& GetLock();
 
-  // Use ICU transliteration to remove diacritics and fold case.
+  // Use ICU transliteration to remove diacritics, fold case and transliterate
+  // Latin to ASCII.
   // See http://userguide.icu-project.org/transforms/general
-  static std::unique_ptr<icu::Transliterator> CreateTransliterator();
-
   static std::unique_ptr<icu::Transliterator>& GetTransliterator();
 
   base::AutoLock auto_lock_;
 };
 
 // Apply the transliteration to a full string to convert it to lower case and to
-// remove the diacritics.
-// and remove the diacritics.
+// remove the diacritics. This function also converts a other Latin characters
+// to ascii (ł -> l, ß -> ss). It does not perform German transliteration (ö
+// becomes o, not oe).
 std::u16string RemoveDiacriticsAndConvertToLowerCase(base::StringPiece16 value);
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/data_model/borrowed_transliterator_unittest.cc b/components/autofill/core/browser/data_model/borrowed_transliterator_unittest.cc
index 8835bc05..cdbb6be 100644
--- a/components/autofill/core/browser/data_model/borrowed_transliterator_unittest.cc
+++ b/components/autofill/core/browser/data_model/borrowed_transliterator_unittest.cc
@@ -14,8 +14,8 @@
 
 TEST(BorrowedTransliterator, RemoveDiacriticsAndConvertToLowerCase) {
   EXPECT_EQ(RemoveDiacriticsAndConvertToLowerCase(
-                u"āēaa11.īūčģķļņšžKāäǟḑēīļņōȯȱõȭŗšțūž"),
-            u"aeaa11.iucgklnszkaaadeilnooooorstuz");
+                u"āēaa11.īūčģķļņšžKāäǟḑēīļņōȯȱõȭŗšțūžßł"),
+            u"aeaa11.iucgklnszkaaadeilnooooorstuzssl");
 }
 
 }  // namespace autofill
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc
index 5cd514c6..b40c55b4f 100644
--- a/components/autofill/core/browser/form_data_importer_unittest.cc
+++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -782,6 +782,7 @@
             features::kAutofillEnableSupportForAddressOverflow,
             features::kAutofillEnableSupportForBetweenStreetsOrLandmark,
             features::kAutofillEnableSupportForAddressOverflowAndLandmark,
+            features::kAutofillEnableParsingOfStreetLocation,
         },
         {});
   }
diff --git a/components/autofill/core/browser/form_parsing/address_field.cc b/components/autofill/core/browser/form_parsing/address_field.cc
index 37f38de8..605912b1 100644
--- a/components/autofill/core/browser/form_parsing/address_field.cc
+++ b/components/autofill/core/browser/form_parsing/address_field.cc
@@ -405,11 +405,12 @@
     // a street location typically contains strings that match the regular
     // expressions for a street name as well.
     if (!street_location_ &&
-        // TODO(crbug.com/1474308) Gate this behind a feature flag.
         // TODO(crbug.com/1474308) Find a better way to gate street location
         // support. This is easy to confuse with with an address line 1 field.
         // This is currently allowlisted for MX which prefers pairs of
         // street location and address overflow fields.
+        base::FeatureList::IsEnabled(
+            features::kAutofillEnableParsingOfStreetLocation) &&
         client_country == GeoIpCountryCode("MX") &&
         ParseFieldSpecifics(scanner, kStreetLocationRe,
                             kStreetLocationMatchType, street_location_patterns,
diff --git a/components/autofill/core/browser/heuristic_classification_unittests.cc b/components/autofill/core/browser/heuristic_classification_unittests.cc
index bbde9bb..d8ce38c4 100644
--- a/components/autofill/core/browser/heuristic_classification_unittests.cc
+++ b/components/autofill/core/browser/heuristic_classification_unittests.cc
@@ -530,6 +530,7 @@
       features::kAutofillEnableDependentLocalityParsing,
       features::kAutofillEnableExpirationDateImprovements,
       features::kAutofillEnableSupportForBetweenStreetsOrLandmark,
+      features::kAutofillEnableParsingOfStreetLocation,
       // Allow local heuristics to take precedence.
       features::kAutofillStreetNameOrHouseNumberPrecedenceOverAutocomplete,
       features::kAutofillLocalHeuristicsOverrides,
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index 4e8320b..e7d556f4 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -233,6 +233,15 @@
              "AutofillEnableSupportForLandmark",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// Controls if Chrome parses fields at street locations. This field type is
+// generally supported in the legacy hierarchy but there is a risk of confusing
+// an address line 1 with a street location. We don't have a good strategy for
+// that yet. Therefore, this behavior is limited to MX at the moment.
+// TODO(crbug.com/1441904) Remove once launched.
+BASE_FEATURE(kAutofillEnableParsingOfStreetLocation,
+             "AutofillEnableParsingOfStreetLocation",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 // Controls if the heuristic field parsing utilizes shared labels.
 // TODO(crbug.com/1165780): Remove once shared labels are launched.
 BASE_FEATURE(kAutofillEnableSupportForParsingWithSharedLabels,
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h
index 7f90d73..5a89b2cc 100644
--- a/components/autofill/core/common/autofill_features.h
+++ b/components/autofill/core/common/autofill_features.h
@@ -58,6 +58,8 @@
 COMPONENT_EXPORT(AUTOFILL)
 BASE_DECLARE_FEATURE(kAutofillEnableSupportForLandmark);
 COMPONENT_EXPORT(AUTOFILL)
+BASE_DECLARE_FEATURE(kAutofillEnableParsingOfStreetLocation);
+COMPONENT_EXPORT(AUTOFILL)
 BASE_DECLARE_FEATURE(kAutofillPredictionsForAutocompleteUnrecognized);
 COMPONENT_EXPORT(AUTOFILL)
 extern const base::FeatureParam<bool>
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc
index 50a6933..83d49cb0c 100644
--- a/components/autofill/core/common/autofill_payments_features.cc
+++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -44,6 +44,12 @@
              "AutofillEnableCardArtServerSideStretching",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// When enabled, card benefits offered by issuers will be shown in Payments
+// Autofill UI.
+BASE_FEATURE(kAutofillEnableCardBenefits,
+             "AutofillEnableCardBenefits",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 // When enabled, card product name (instead of issuer network) will be shown in
 // Payments Autofill UI.
 BASE_FEATURE(kAutofillEnableCardProductName,
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h
index cd182e84..3414041 100644
--- a/components/autofill/core/common/autofill_payments_features.h
+++ b/components/autofill/core/common/autofill_payments_features.h
@@ -16,6 +16,7 @@
 BASE_DECLARE_FEATURE(kAutofillEnableAndroidNKeyForFidoAuthentication);
 BASE_DECLARE_FEATURE(kAutofillEnableCardArtImage);
 BASE_DECLARE_FEATURE(kAutofillEnableCardArtServerSideStretching);
+BASE_DECLARE_FEATURE(kAutofillEnableCardBenefits);
 BASE_DECLARE_FEATURE(kAutofillEnableCardProductName);
 BASE_DECLARE_FEATURE(kAutofillEnableCvcStorageAndFilling);
 BASE_DECLARE_FEATURE(kAutofillEnableEmailOtpForVcnYellowPath);
diff --git a/components/autofill/ios/browser/BUILD.gn b/components/autofill/ios/browser/BUILD.gn
index 23003d2..83361e21ab 100644
--- a/components/autofill/ios/browser/BUILD.gn
+++ b/components/autofill/ios/browser/BUILD.gn
@@ -20,8 +20,6 @@
     "autofill_java_script_feature.mm",
     "autofill_manager_observer_bridge.h",
     "autofill_manager_observer_bridge.mm",
-    "child_frame_registration_java_script_feature.h",
-    "child_frame_registration_java_script_feature.mm",
     "credit_card_util.h",
     "credit_card_util.mm",
     "form_suggestion.h",
@@ -37,7 +35,6 @@
 
   deps = [
     ":autofill_js",
-    ":child_frame_registration_ts",
     ":suggestion_controller_js",
     ":util",
     "//base",
@@ -94,17 +91,6 @@
   ]
 }
 
-optimize_ts("child_frame_registration_ts") {
-  visibility = [ ":browser" ]
-
-  sources = [ "resources/child_frame_registration.ts" ]
-  deps = [
-    "//ios/web/public/js_messaging:frame_id",
-    "//ios/web/public/js_messaging:gcrweb",
-    "//ios/web/public/js_messaging:util_scripts",
-  ]
-}
-
 optimize_ts("suggestion_controller_js") {
   sources = [ "resources/suggestion_controller.ts" ]
 
diff --git a/components/autofill/ios/browser/child_frame_registration_java_script_feature.h b/components/autofill/ios/browser/child_frame_registration_java_script_feature.h
deleted file mode 100644
index a436f76..0000000
--- a/components/autofill/ios/browser/child_frame_registration_java_script_feature.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_AUTOFILL_IOS_BROWSER_CHILD_FRAME_REGISTRATION_JAVA_SCRIPT_FEATURE_H_
-#define COMPONENTS_AUTOFILL_IOS_BROWSER_CHILD_FRAME_REGISTRATION_JAVA_SCRIPT_FEATURE_H_
-
-#import <map>
-
-#import "components/autofill/core/common/unique_ids.h"
-#import "ios/web/public/js_messaging/java_script_feature.h"
-#import "third_party/abseil-cpp/absl/types/optional.h"
-
-namespace web {
-class ScriptMessage;
-class WebState;
-}  // namespace web
-
-namespace autofill {
-
-// Child frame registration is the process whereby a frame can assign an ID (a
-// remote frame token) to a child frame, establishing a relationship between
-// that frame in the DOM (and JS) and the corresponding WebFrame object in C++.
-// This class maintains those mappings.
-class ChildFrameRegistrationJavaScriptFeature : public web::JavaScriptFeature {
- public:
-  static ChildFrameRegistrationJavaScriptFeature* GetInstance();
-  ChildFrameRegistrationJavaScriptFeature();
-  ~ChildFrameRegistrationJavaScriptFeature() override;
-
-  // Maps from remote to local tokens for all registered frames, to allow
-  // lookup of a frame based on its remote token.
-  //
-  // Frame Tokens are used by browser-layer Autofill code to identify and
-  // interact with a specific frame. Local Frame Tokens must not leak to frames
-  // other than the ones they identify, while Remote Frame Tokens are also known
-  // to the parent frame.
-  //
-  // In the context of iOS, the LocalFrameToken is equal to the frameId and can
-  // be used to fetch the appropriate WebFrame from the WebFramesManager.
-  //
-  // TODO(crbug.com/1440471): Encapsulate this with a public lookup method.
-  std::map<RemoteFrameToken, LocalFrameToken> lookup_map;
-
- protected:
-  // JavaScriptFeature:
-  void ScriptMessageReceived(web::WebState* web_state,
-                             const web::ScriptMessage& script_message) override;
-  absl::optional<std::string> GetScriptMessageHandlerName() const override;
-};
-
-}  // namespace autofill
-
-#endif  // COMPONENTS_AUTOFILL_IOS_BROWSER_CHILD_FRAME_REGISTRATION_JAVA_SCRIPT_FEATURE_H_
diff --git a/components/autofill/ios/browser/child_frame_registration_java_script_feature.mm b/components/autofill/ios/browser/child_frame_registration_java_script_feature.mm
deleted file mode 100644
index f0b6c850..0000000
--- a/components/autofill/ios/browser/child_frame_registration_java_script_feature.mm
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "components/autofill/ios/browser/child_frame_registration_java_script_feature.h"
-
-#import "base/no_destructor.h"
-#import "base/strings/string_number_conversions.h"
-#import "base/unguessable_token.h"
-#import "base/values.h"
-#import "ios/web/public/js_messaging/script_message.h"
-
-namespace {
-
-constexpr char kScriptName[] = "child_frame_registration";
-constexpr char kScriptMessageName[] = "RegisterChildFrame";
-
-// Local and remote frame IDs generated in JavaScript are equivalent to
-// base::UnguessableToken (128 bits, cryptographically random).
-absl::optional<base::UnguessableToken> DeserializeJavaScriptFrameId(
-    const std::string& id) {
-  // A valid ID is 128 bits, or 32 hex digits.
-  if (id.length() != 32) {
-    return {};
-  }
-
-  // Break string into first and last 16 hex digits.
-  std::string high_hex = id.substr(0, 16);
-  std::string low_hex = id.substr(16);
-
-  uint64_t high, low;
-  if (!base::HexStringToUInt64(high_hex, &high) ||
-      !base::HexStringToUInt64(low_hex, &low)) {
-    return {};
-  }
-
-  return base::UnguessableToken::Deserialize(high, low);
-}
-
-}  // namespace
-
-namespace autofill {
-
-// static
-ChildFrameRegistrationJavaScriptFeature*
-ChildFrameRegistrationJavaScriptFeature::GetInstance() {
-  static base::NoDestructor<ChildFrameRegistrationJavaScriptFeature> instance;
-  return instance.get();
-}
-
-ChildFrameRegistrationJavaScriptFeature::
-    ChildFrameRegistrationJavaScriptFeature()
-    : JavaScriptFeature(
-          web::ContentWorld::kIsolatedWorld,
-          {FeatureScript::CreateWithFilename(
-              kScriptName,
-              FeatureScript::InjectionTime::kDocumentEnd,
-              FeatureScript::TargetFrames::kAllFrames,
-              FeatureScript::ReinjectionBehavior::kInjectOncePerWindow)}) {}
-
-ChildFrameRegistrationJavaScriptFeature::
-    ~ChildFrameRegistrationJavaScriptFeature() = default;
-
-void ChildFrameRegistrationJavaScriptFeature::ScriptMessageReceived(
-    web::WebState* web_state,
-    const web::ScriptMessage& script_message) {
-  base::Value::Dict* response = script_message.body()->GetIfDict();
-  if (!response) {
-    return;
-  }
-
-  const std::string* local_frame_id = response->FindString("local_frame_id");
-  const std::string* remote_frame_id = response->FindString("remote_frame_id");
-  if (!local_frame_id || !remote_frame_id) {
-    return;
-  }
-
-  absl::optional<base::UnguessableToken> local =
-      DeserializeJavaScriptFrameId(*local_frame_id);
-  absl::optional<base::UnguessableToken> remote =
-      DeserializeJavaScriptFrameId(*remote_frame_id);
-
-  if (!local || !remote) {
-    return;
-  }
-
-  // TODO(crbug.com/1440471): Handle double registration
-  lookup_map.emplace(*remote, *local);
-}
-
-absl::optional<std::string>
-ChildFrameRegistrationJavaScriptFeature::GetScriptMessageHandlerName() const {
-  return kScriptMessageName;
-}
-
-}  // namespace autofill
diff --git a/components/autofill/ios/browser/resources/child_frame_registration.ts b/components/autofill/ios/browser/resources/child_frame_registration.ts
deleted file mode 100644
index bc4fedc..0000000
--- a/components/autofill/ios/browser/resources/child_frame_registration.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Identifies relationships between parent and child frames
- * by generating a unique ID and sending it to the browser from each frame.
- */
-
-import {generateRandomId, getFrameId} from '//ios/web/public/js_messaging/resources/frame_id.js';
-import {sendWebKitMessage} from '//ios/web/public/js_messaging/resources/utils.js';
-
-// TODO(crbug.com/1440471): This just posts a message with the frame ID and a
-// mock value for the remote token. This needs to message the child frames.
-
-sendWebKitMessage('RegisterChildFrame', {
-  'local_frame_id': getFrameId(),
-  'remote_frame_id': generateRandomId(),
-});
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
index b75e49ab..1b1f8b01 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
@@ -381,9 +381,8 @@
             @ContentSettingsType int contentSettingType, String primaryPattern,
             String secondaryPattern, @ContentSettingValues int setting) {
         if (contentSettingType == ContentSettingsType.STORAGE_ACCESS) {
-            // StorageAccess exceptions should always specify a primary pattern. The secondary
-            // pattern might or not be empty depending if the exception is normal or embargoed.
-            assert !primaryPattern.isEmpty() && !primaryPattern.equals(SITE_WILDCARD);
+            // StorageAccess exceptions should always specify a primary and a secondary pattern.
+            assert !primaryPattern.equals(SITE_WILDCARD) && !secondaryPattern.equals(SITE_WILDCARD);
         } else if (contentSettingType == ContentSettingsType.COOKIES
                 && !secondaryPattern.equals(SITE_WILDCARD)) {
             // Currently only Cookie Settings support a non-empty, non-wildcard secondaryPattern.
diff --git a/components/compose_strings.grdp b/components/compose_strings.grdp
index 2aee7d50..f5f5aaaf 100644
--- a/components/compose_strings.grdp
+++ b/components/compose_strings.grdp
@@ -44,7 +44,7 @@
   We can Autofill many things (e.g., adresses, passwords, user names, credit card.). You can autofill any fields you want.
   </message>
   <message name="IDS_COMPOSE_INPUT_FOOTER" desc="The footer text for the input dialog." translateable="false">
-  <ph name="BEGIN_BOLD">&lt;b&gt;</ph>Tip:<ph name="END_BOLD">&lt;/b&gt;</ph> You can activate Autofill in any text field when you right click.
+  Your bookmark is saved to <ph name="START">&lt;a href="chrome://bookmarks"&gt;</ph>Bookmark UI<ph name="END">&lt;/a&gt;</ph>.
   </message>
   <message name="IDS_COMPOSE_SUBMIT_BUTTON" desc="The button to submit the input." translateable="false">
   Submit
diff --git a/components/content_settings/core/browser/content_settings_policy_provider.cc b/components/content_settings/core/browser/content_settings_policy_provider.cc
index 39cb9dbd..9ffc3594 100644
--- a/components/content_settings/core/browser/content_settings_policy_provider.cc
+++ b/components/content_settings/core/browser/content_settings_policy_provider.cc
@@ -117,6 +117,8 @@
          CONTENT_SETTING_ALLOW},
         {prefs::kManagedMidiBlockedForUrls, ContentSettingsType::MIDI,
          CONTENT_SETTING_BLOCK},
+        {prefs::kManagedMidiBlockedForUrls, ContentSettingsType::MIDI_SYSEX,
+         CONTENT_SETTING_BLOCK},
 };
 
 constexpr const char* kManagedPrefs[] = {
@@ -302,6 +304,7 @@
         {ContentSettingsType::THIRD_PARTY_STORAGE_PARTITIONING,
          prefs::kManagedDefaultThirdPartyStoragePartitioningSetting},
         {ContentSettingsType::MIDI, prefs::kManagedDefaultMidi},
+        {ContentSettingsType::MIDI_SYSEX, prefs::kManagedDefaultMidi},
 };
 
 // static
diff --git a/components/crx_file/id_util.cc b/components/crx_file/id_util.cc
index 2f5c2eb..f4a9734 100644
--- a/components/crx_file/id_util.cc
+++ b/components/crx_file/id_util.cc
@@ -65,9 +65,8 @@
 }
 
 std::string HashedIdInHex(const std::string& id) {
-  const std::string id_hash = base::SHA1HashString(id);
-  DCHECK_EQ(base::kSHA1Length, id_hash.length());
-  return base::HexEncode(id_hash.c_str(), id_hash.length());
+  return base::HexEncode(
+      base::SHA1HashSpan(base::as_bytes(base::make_span(id))));
 }
 
 base::FilePath MaybeNormalizePath(const base::FilePath& path) {
diff --git a/components/embedder_support/user_agent_utils.cc b/components/embedder_support/user_agent_utils.cc
index c957a691..556dcce 100644
--- a/components/embedder_support/user_agent_utils.cc
+++ b/components/embedder_support/user_agent_utils.cc
@@ -487,8 +487,9 @@
   metadata.architecture = content::GetCpuArchitecture();
   metadata.model = content::BuildModelInfo();
 
-  // TODO(https://crbug.com/1442283): Support a broader range of form-factors.
-  metadata.form_factor = metadata.mobile ? kMobileFormFactor : "";
+  // By default, use "Mobile" or "Desktop" depending on the `mobile` bit.
+  metadata.form_factor = {metadata.mobile ? blink::kMobileFormFactor
+                                          : blink::kDesktopFormFactor};
 
 #if BUILDFLAG(IS_WIN)
   metadata.platform_version = GetWindowsPlatformVersion();
@@ -520,7 +521,7 @@
       std::string();  // match content::GetOSVersion(false) on Linux
   spoofed_ua.ua_metadata_override->model = std::string();
   spoofed_ua.ua_metadata_override->mobile = false;
-  spoofed_ua.ua_metadata_override->form_factor = "";
+  spoofed_ua.ua_metadata_override->form_factor = {blink::kDesktopFormFactor};
   // Match the above "CpuInfo" string, which is also the most common Linux
   // CPU architecture and bitness.`
   spoofed_ua.ua_metadata_override->architecture = "x86";
diff --git a/components/embedder_support/user_agent_utils.h b/components/embedder_support/user_agent_utils.h
index f93141d..f2e6fc7 100644
--- a/components/embedder_support/user_agent_utils.h
+++ b/components/embedder_support/user_agent_utils.h
@@ -22,9 +22,6 @@
 
 namespace embedder_support {
 
-// Value of the Sec-CH-UA-Form-Factor header for the mobile form-factor.
-constexpr char kMobileFormFactor[] = "Mobile";
-
 // TODO(crbug.com/1330890): Remove this enum along with policy.
 enum class UserAgentReductionEnterprisePolicyState {
   kDefault = 0,
diff --git a/components/embedder_support/user_agent_utils_unittest.cc b/components/embedder_support/user_agent_utils_unittest.cc
index a59b8fb..2f36322 100644
--- a/components/embedder_support/user_agent_utils_unittest.cc
+++ b/components/embedder_support/user_agent_utils_unittest.cc
@@ -767,7 +767,9 @@
   EXPECT_EQ(metadata.model, content::BuildModelInfo());
   EXPECT_EQ(metadata.bitness, content::GetCpuBitness());
   EXPECT_EQ(metadata.wow64, content::IsWoW64());
-  EXPECT_EQ(metadata.form_factor, metadata.mobile ? "Mobile" : "");
+  std::vector<std::string> expected_form_factor = {metadata.mobile ? "Mobile"
+                                                                   : "Desktop"};
+  EXPECT_EQ(metadata.form_factor, expected_form_factor);
 
   // Verify only populate low-entropy client hints.
   metadata = GetUserAgentMetadata(true);
diff --git a/components/exo/data_offer_unittest.cc b/components/exo/data_offer_unittest.cc
index f76b0e2..616a998a 100644
--- a/components/exo/data_offer_unittest.cc
+++ b/components/exo/data_offer_unittest.cc
@@ -105,15 +105,17 @@
     return true;
   }
 
-  void PasteIfAllowed(const ui::DataTransferEndpoint* const data_src,
-                      const ui::DataTransferEndpoint* const data_dst,
-                      const absl::optional<size_t> size,
-                      content::RenderFrameHost* web_contents,
-                      base::OnceCallback<void(bool)> callback) override {}
+  void PasteIfAllowed(
+      base::optional_ref<const ui::DataTransferEndpoint> data_src,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      const absl::optional<size_t> size,
+      content::RenderFrameHost* web_contents,
+      base::OnceCallback<void(bool)> callback) override {}
 
-  void DropIfAllowed(const ui::OSExchangeData* const drag_data,
-                     const ui::DataTransferEndpoint* const data_dst,
-                     base::OnceClosure drop_cb) override {
+  void DropIfAllowed(
+      const ui::OSExchangeData* const drag_data,
+      base::optional_ref<const ui::DataTransferEndpoint> data_dst,
+      base::OnceClosure drop_cb) override {
     std::move(drop_cb).Run();
   }
 
diff --git a/components/exo/drag_drop_operation_unittest.cc b/components/exo/drag_drop_operation_unittest.cc
index 48df6455..1ed66228 100644
--- a/components/exo/drag_drop_operation_unittest.cc
+++ b/components/exo/drag_drop_operation_unittest.cc
@@ -368,14 +368,14 @@
                     base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     const absl::optional<size_t> size));
   MOCK_METHOD5(PasteIfAllowed,
-               void(const ui::DataTransferEndpoint* const data_src,
-                    const ui::DataTransferEndpoint* const data_dst,
+               void(base::optional_ref<const ui::DataTransferEndpoint> data_src,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     const absl::optional<size_t> size,
                     content::RenderFrameHost* rfh,
                     base::OnceCallback<void(bool)> callback));
   MOCK_METHOD3(DropIfAllowed,
                void(const ui::OSExchangeData* drag_data,
-                    const ui::DataTransferEndpoint* data_dst,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::OnceClosure drop_cb));
 };
 
@@ -418,7 +418,7 @@
   // Expect the encoded endpoint from Lacros to be correctly parsed.
   EXPECT_CALL(*dlp_controller, DropIfAllowed)
       .WillOnce([&](const ui::OSExchangeData* drag_data,
-                    const ui::DataTransferEndpoint* data_dst,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::OnceClosure drop_cb) {
         ASSERT_TRUE(drag_data);
         auto* data_src = drag_data->GetSource();
@@ -484,7 +484,7 @@
   // Expect the encoded endpoint from non-Lacros to be ignored.
   EXPECT_CALL(*dlp_controller, DropIfAllowed)
       .WillOnce([&](const ui::OSExchangeData* drag_data,
-                    const ui::DataTransferEndpoint* data_dst,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::OnceClosure drop_cb) {
         ASSERT_TRUE(drag_data);
         auto* data_src = drag_data->GetSource();
diff --git a/components/exo/wayland/zcr_remote_shell_impl.cc b/components/exo/wayland/zcr_remote_shell_impl.cc
index ec54f11..9b601cf 100644
--- a/components/exo/wayland/zcr_remote_shell_impl.cc
+++ b/components/exo/wayland/zcr_remote_shell_impl.cc
@@ -573,8 +573,7 @@
   in_display_update_ = true;
 }
 
-void WaylandRemoteShell::OnDidProcessDisplayChanges(
-    const DisplayConfigurationChange& configuration_change) {
+void WaylandRemoteShell::OnDidProcessDisplayChanges() {
   in_display_update_ = false;
 }
 
diff --git a/components/exo/wayland/zcr_remote_shell_impl.h b/components/exo/wayland/zcr_remote_shell_impl.h
index ff426a1b..3a1f0e1 100644
--- a/components/exo/wayland/zcr_remote_shell_impl.h
+++ b/components/exo/wayland/zcr_remote_shell_impl.h
@@ -101,8 +101,7 @@
 
   // display::DisplayManagerObserver:
   void OnWillProcessDisplayChanges() override;
-  void OnDidProcessDisplayChanges(
-      const DisplayConfigurationChange& configuration_change) override;
+  void OnDidProcessDisplayChanges() override;
 
   // Overridden from ash::TabletModeObserver:
   void OnTabletModeStarted() override;
diff --git a/components/image_fetcher/core/cache/image_cache.cc b/components/image_fetcher/core/cache/image_cache.cc
index 11103e63..a067460 100644
--- a/components/image_fetcher/core/cache/image_cache.cc
+++ b/components/image_fetcher/core/cache/image_cache.cc
@@ -47,7 +47,7 @@
 // static
 std::string ImageCache::HashUrlToKey(const std::string& input) {
   return base32::Base32Encode(
-      base::as_bytes(base::make_span(base::SHA1HashString(input))));
+      base::SHA1HashSpan(base::as_bytes(base::make_span(input))));
 }
 
 // static
diff --git a/components/metrics/environment_recorder.cc b/components/metrics/environment_recorder.cc
index 67eea0a4..7f7f5ae 100644
--- a/components/metrics/environment_recorder.cc
+++ b/components/metrics/environment_recorder.cc
@@ -18,8 +18,8 @@
 
 // Computes a SHA-1 hash of |data| and returns it as a hex string.
 std::string ComputeSHA1(const std::string& data) {
-  const std::string sha1 = base::SHA1HashString(data);
-  return base::HexEncode(sha1.data(), sha1.size());
+  return base::HexEncode(
+      base::SHA1HashSpan(base::as_bytes(base::make_span(data))));
 }
 
 }  // namespace
diff --git a/components/metrics/ui/form_factor_metrics_provider.cc b/components/metrics/ui/form_factor_metrics_provider.cc
index 8e8a30f2..d497b71 100644
--- a/components/metrics/ui/form_factor_metrics_provider.cc
+++ b/components/metrics/ui/form_factor_metrics_provider.cc
@@ -8,6 +8,10 @@
 #include "build/build_config.h"
 #include "ui/base/device_form_factor.h"
 
+#if BUILDFLAG(IS_ANDROID)
+#include "base/android/build_info.h"
+#endif
+
 namespace metrics {
 
 void FormFactorMetricsProvider::ProvideSystemProfileMetrics(
@@ -17,6 +21,17 @@
 
 SystemProfileProto::Hardware::FormFactor
 FormFactorMetricsProvider::GetFormFactor() const {
+// Temporary workaround to report foldable for UMA without affecting
+// other form factors. This will be removed and replaced with a long-term
+// solution in DeviceFormFactor::GetDeviceFormFactor() after conducting an
+// audit of form factor usage or exposing ui_mode.
+// VariationsServiceClient::GetCurrentFormFactor() also needs to be updated.
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_foldable()) {
+    return SystemProfileProto::Hardware::FORM_FACTOR_FOLDABLE;
+  }
+#endif
+
 #if BUILDFLAG(PLATFORM_CFM)
   return SystemProfileProto::Hardware::FORM_FACTOR_MEET_DEVICE;
 #else
diff --git a/components/omnibox/browser/actions/omnibox_pedal_provider.cc b/components/omnibox/browser/actions/omnibox_pedal_provider.cc
index ae39bc5..796bd27 100644
--- a/components/omnibox/browser/actions/omnibox_pedal_provider.cc
+++ b/components/omnibox/browser/actions/omnibox_pedal_provider.cc
@@ -5,8 +5,8 @@
 #include "components/omnibox/browser/actions/omnibox_pedal_provider.h"
 
 #include <numeric>
+#include <unordered_map>
 
-#include "base/containers/cxx20_erase.h"
 #include "base/i18n/case_conversion.h"
 #include "base/i18n/char_iterator.h"
 #include "base/i18n/rtl.h"
@@ -55,7 +55,7 @@
 
   // Cull Pedals with incomplete data; they won't trigger if not enabled,
   // but there's no need to keep them in the collection (iterated frequently).
-  base::EraseIf(pedals_, [](const auto& it) {
+  std::erase_if(pedals_, [](const auto& it) {
     const OmniboxPedal::LabelStrings& labels = it.second->GetLabelStrings();
     return labels.hint.empty() || labels.suggestion_contents.empty() ||
            labels.accessibility_hint.empty() ||
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc
index f21a0897..7a56ed6 100644
--- a/components/omnibox/browser/autocomplete_controller.cc
+++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -1975,6 +1975,14 @@
       // occupied the top spot while '@' was demoted below others.
       std::sort(result->begin(), result->end(),
                 AutocompleteMatch::MoreRelevant);
+      // Put first defaultable match in top position since relevance
+      // ranking alone doesn't guarantee it.
+      auto default_match = std::find_if(
+          result->begin(), result->end(),
+          [](const auto& m) { return m.allowed_to_be_default_match; });
+      if (default_match != result->begin() && default_match != result->end()) {
+        std::rotate(result->begin(), default_match, default_match + 1);
+      }
     }
 
     // Intentionally avoid actions and remove button on first suggestion
diff --git a/components/password_manager/core/browser/affiliation/BUILD.gn b/components/password_manager/core/browser/affiliation/BUILD.gn
index 4a0e8b6..921eadf 100644
--- a/components/password_manager/core/browser/affiliation/BUILD.gn
+++ b/components/password_manager/core/browser/affiliation/BUILD.gn
@@ -73,6 +73,9 @@
     "//net",
     "//url",
   ]
+  if (!is_ios && !is_android) {
+    deps += [ "//components/webauthn/core/browser" ]
+  }
   configs += [ "//build/config/compiler:wexit_time_destructors" ]
 }
 
@@ -160,6 +163,10 @@
     "//testing/gmock",
     "//testing/gtest",
   ]
+
+  if (!is_android && !is_ios) {
+    deps += [ "//components/webauthn/core/browser:test_support" ]
+  }
 }
 
 if (use_fuzzing_engine_with_lpm) {
diff --git a/components/password_manager/core/browser/affiliation/affiliations_prefetcher.cc b/components/password_manager/core/browser/affiliation/affiliations_prefetcher.cc
index 5b8a802..1ddc6ea4 100644
--- a/components/password_manager/core/browser/affiliation/affiliations_prefetcher.cc
+++ b/components/password_manager/core/browser/affiliation/affiliations_prefetcher.cc
@@ -11,6 +11,7 @@
 #include "base/check_op.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
+#include "base/strings/strcat.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
 #include "components/password_manager/core/browser/affiliation/affiliation_service.h"
@@ -18,6 +19,8 @@
 #include "components/password_manager/core/browser/features/password_features.h"
 #include "components/password_manager/core/browser/password_form.h"
 #include "components/password_manager/core/common/password_manager_features.h"
+#include "components/webauthn/core/browser/passkey_model.h"
+#include "components/webauthn/core/browser/passkey_model_change.h"
 
 namespace password_manager {
 
@@ -34,6 +37,20 @@
 #endif
 }
 
+absl::optional<FacetURI> FacetURIFromPasskey(
+    const sync_pb::WebauthnCredentialSpecifics& passkey) {
+  std::string as_url = base::StrCat(
+      {url::kHttpsScheme, url::kStandardSchemeSeparator, passkey.rp_id()});
+  FacetURI facet_uri = FacetURI::FromPotentiallyInvalidSpec(as_url);
+  if (!facet_uri.is_valid()) {
+    return absl::nullopt;
+  }
+  if (!IsFacetValidForAffiliation(facet_uri)) {
+    return absl::nullopt;
+  }
+  return facet_uri;
+}
+
 }  // namespace
 
 AffiliationsPrefetcher::AffiliationsPrefetcher(
@@ -65,12 +82,29 @@
   }
 }
 
+void AffiliationsPrefetcher::RegisterPasskeyModel(
+    webauthn::PasskeyModel* passkey_model) {
+  passkey_model_observation_.Observe(passkey_model);
+
+  // If initialization had already happened, immediately prefetch affiliation
+  // info for all passkeys.
+  if (is_ready_) {
+    for (const auto& passkey : passkey_model->GetAllPasskeys()) {
+      absl::optional<FacetURI> facet = FacetURIFromPasskey(passkey);
+      if (facet) {
+        affiliation_service_->Prefetch(std::move(*facet), base::Time::Max());
+      }
+    }
+  }
+}
+
 void AffiliationsPrefetcher::Shutdown() {
   for (const auto& store : password_stores_) {
     store->RemoveObserver(this);
   }
   password_stores_.clear();
   pending_initializations_.clear();
+  passkey_model_observation_.Reset();
 }
 
 void AffiliationsPrefetcher::DisablePrefetching() {
@@ -133,6 +167,29 @@
   affiliation_service_->KeepPrefetchForFacets(std::move(facets));
 }
 
+void AffiliationsPrefetcher::OnPasskeysChanged(
+    const std::vector<webauthn::PasskeyModelChange>& changes) {
+  std::vector<FacetURI> facet_uris_to_trim;
+  for (const webauthn::PasskeyModelChange& change : changes) {
+    absl::optional<FacetURI> facet = FacetURIFromPasskey(change.passkey());
+    if (!facet) {
+      continue;
+    }
+
+    if (change.type() == webauthn::PasskeyModelChange::ChangeType::ADD) {
+      affiliation_service_->Prefetch(std::move(*facet), base::Time::Max());
+    } else if (change.type() ==
+               webauthn::PasskeyModelChange::ChangeType::REMOVE) {
+      affiliation_service_->CancelPrefetch(std::move(*facet),
+                                           base::Time::Max());
+    }
+  }
+}
+
+void AffiliationsPrefetcher::OnPasskeyModelShuttingDown() {
+  passkey_model_observation_.Reset();
+}
+
 void AffiliationsPrefetcher::OnGetPasswordStoreResults(
     std::vector<std::unique_ptr<PasswordForm>> results) {
   DCHECK(on_password_forms_received_barrier_callback_);
@@ -149,6 +206,13 @@
     return;
   }
 
+  // If no calls to Register* happened before |kInitializationDelayOnStartup|,
+  // don't do anything.
+  if (results.empty() && !passkey_model_observation_.IsObserving()) {
+    is_ready_ = true;
+    return;
+  }
+
   std::vector<FacetURI> facets;
   for (const auto& result_per_store : results) {
     for (const auto& form : result_per_store) {
@@ -159,9 +223,17 @@
       }
     }
   }
+  if (passkey_model_observation_.IsObserving()) {
+    for (const auto& passkey :
+         passkey_model_observation_.GetSource()->GetAllPasskeys()) {
+      absl::optional<FacetURI> facet = FacetURIFromPasskey(passkey);
+      if (facet) {
+        facets.push_back(std::move(*facet));
+      }
+    }
+  }
   affiliation_service_->KeepPrefetchForFacets(facets);
   affiliation_service_->TrimUnusedCache(std::move(facets));
-
   is_ready_ = true;
 }
 
@@ -171,9 +243,10 @@
     return;
   }
 
-  // If no calls to RegisterPasswordStore happened before
-  // |kInitializationDelayOnStartup| return early.
-  if (pending_initializations_.empty()) {
+  // If no calls to Register* happened before |kInitializationDelayOnStartup|
+  // return early.
+  if (pending_initializations_.empty() &&
+      !passkey_model_observation_.IsObserving()) {
     is_ready_ = true;
     return;
   }
diff --git a/components/password_manager/core/browser/affiliation/affiliations_prefetcher.h b/components/password_manager/core/browser/affiliation/affiliations_prefetcher.h
index 999ca393..d5a8952 100644
--- a/components/password_manager/core/browser/affiliation/affiliations_prefetcher.h
+++ b/components/password_manager/core/browser/affiliation/affiliations_prefetcher.h
@@ -11,9 +11,11 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/scoped_observation.h"
 #include "components/keyed_service/core/keyed_service.h"
 #include "components/password_manager/core/browser/password_store/password_store_consumer.h"
 #include "components/password_manager/core/browser/password_store/password_store_interface.h"
+#include "components/webauthn/core/browser/passkey_model.h"
 
 namespace password_manager {
 
@@ -25,11 +27,16 @@
 // stored in a PasswordStore.
 class AffiliationsPrefetcher : public KeyedService,
                                public PasswordStoreInterface::Observer,
+                               public webauthn::PasskeyModel::Observer,
                                public PasswordStoreConsumer {
  public:
   explicit AffiliationsPrefetcher(AffiliationService* affiliation_service);
   ~AffiliationsPrefetcher() override;
 
+  // Registers a passkey model and starts listening for passkey changes. Only
+  // one passkey model may be registered.
+  void RegisterPasskeyModel(webauthn::PasskeyModel* passkey_model);
+
   void RegisterPasswordStore(PasswordStoreInterface* store);
 
   // KeyedService:
@@ -46,6 +53,11 @@
       PasswordStoreInterface* store,
       const std::vector<PasswordForm>& retained_passwords) override;
 
+  // webauthn::PasskeyModel::Observer:
+  void OnPasskeysChanged(
+      const std::vector<webauthn::PasskeyModelChange>& changes) override;
+  void OnPasskeyModelShuttingDown() override;
+
   // PasswordStoreConsumer:
   void OnGetPasswordStoreResults(
       std::vector<std::unique_ptr<PasswordForm>> results) override;
@@ -64,6 +76,11 @@
   // Password store which are currently being observed.
   std::vector<raw_ptr<PasswordStoreInterface>> password_stores_;
 
+  // Passkey model being observed. May be null.
+  base::ScopedObservation<webauthn::PasskeyModel,
+                          webauthn::PasskeyModel::Observer>
+      passkey_model_observation_{this};
+
   // Allows to aggregate GetAllLogins results from multiple stores.
   base::RepeatingCallback<void(std::vector<std::unique_ptr<PasswordForm>>)>
       on_password_forms_received_barrier_callback_;
diff --git a/components/password_manager/core/browser/affiliation/affiliations_prefetcher_unittest.cc b/components/password_manager/core/browser/affiliation/affiliations_prefetcher_unittest.cc
index e57bca5c..708655a 100644
--- a/components/password_manager/core/browser/affiliation/affiliations_prefetcher_unittest.cc
+++ b/components/password_manager/core/browser/affiliation/affiliations_prefetcher_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/rand_util.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/scoped_mock_time_message_loop_task_runner.h"
@@ -28,6 +29,10 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
+#include "components/webauthn/core/browser/test_passkey_model.h"  // nogncheck
+#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
+
 namespace password_manager {
 
 namespace {
@@ -79,6 +84,22 @@
   return form;
 }
 
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
+
+const char kTestRpIdFacetURIAlpha1[] = "one.alpha.example.com";
+const char kTestRpIdFacetURIAlpha2[] = "two.alpha.example.com";
+const char kTestExtensionRpId[] = "chrome-extension://test-extension-id";
+
+sync_pb::WebauthnCredentialSpecifics GetTestPasskey(const char* rp_id) {
+  sync_pb::WebauthnCredentialSpecifics passkey;
+  passkey.set_rp_id(rp_id);
+  passkey.set_credential_id(base::RandBytesAsString(16));
+  passkey.set_sync_id(base::RandBytesAsString(16));
+  return passkey;
+}
+
+#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
+
 }  // namespace
 
 // Boolean parameters indicates whether affiliation service should support
@@ -615,4 +636,111 @@
   RunUntilIdle();
 }
 
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
+
+class AffiliationsPrefetcherWithPasskeysTest
+    : public AffiliationsPrefetcherTest {
+ protected:
+  webauthn::TestPasskeyModel* test_passkey_model() {
+    return test_passkey_model_.get();
+  }
+
+  void RunDeferredInitialization() {
+    RunUntilIdle();
+    ExpectCallToTrimUnusedCache();
+    prefetcher()->RegisterPasswordStore(password_store());
+    prefetcher()->RegisterPasskeyModel(test_passkey_model_.get());
+    FastForwardBy(kInitializationDelayOnStartup);
+  }
+
+ private:
+  std::unique_ptr<webauthn::TestPasskeyModel> test_passkey_model_ =
+      std::make_unique<webauthn::TestPasskeyModel>();
+};
+
+TEST_F(AffiliationsPrefetcherWithPasskeysTest, TestInitialPrefetch) {
+  AddLoginAndWait(password_store(),
+                  GetTestAndroidCredentials(kTestWebFacetURIAlpha1));
+  test_passkey_model()->AddNewPasskeyForTesting(
+      GetTestPasskey(kTestRpIdFacetURIAlpha2));
+
+  std::vector<FacetURI> expected_facets;
+  expected_facets.push_back(
+      FacetURI::FromCanonicalSpec(kTestWebFacetURIAlpha1));
+  expected_facets.push_back(
+      FacetURI::FromCanonicalSpec(kTestWebFacetURIAlpha2));
+
+  // Expect prefetch for passwords and passkeys.
+  ExpectKeepPrefetchForFacets(expected_facets);
+
+  ASSERT_NO_FATAL_FAILURE(RunDeferredInitialization());
+}
+
+TEST_F(AffiliationsPrefetcherWithPasskeysTest,
+       TestPasskeyModelRegisteredLater) {
+  AddLoginAndWait(password_store(),
+                  GetTestAndroidCredentials(kTestWebFacetURIAlpha1));
+  test_passkey_model()->AddNewPasskeyForTesting(
+      GetTestPasskey(kTestRpIdFacetURIAlpha2));
+
+  std::vector<FacetURI> expected_facets;
+  expected_facets.push_back(
+      FacetURI::FromCanonicalSpec(kTestWebFacetURIAlpha1));
+
+  ExpectKeepPrefetchForFacets(expected_facets);
+  ExpectCallToTrimUnusedCache();
+
+  prefetcher()->RegisterPasswordStore(password_store());
+  FastForwardBy(kInitializationDelayOnStartup);
+
+  expected_facets.push_back(
+      FacetURI::FromCanonicalSpec(kTestWebFacetURIAlpha2));
+  ExpectCallToPrefetch(kTestWebFacetURIAlpha2);
+
+  prefetcher()->RegisterPasskeyModel(test_passkey_model());
+  RunUntilIdle();
+}
+
+TEST_F(AffiliationsPrefetcherWithPasskeysTest, TestNewPasskeyDownloaded) {
+  prefetcher()->RegisterPasskeyModel(test_passkey_model());
+  ExpectKeepPrefetchForFacets({});
+  ExpectCallToTrimUnusedCache();
+  FastForwardBy(kInitializationDelayOnStartup);
+
+  std::vector<FacetURI> expected_facets{
+      FacetURI::FromCanonicalSpec(kTestWebFacetURIAlpha1)};
+  ExpectCallToPrefetch(kTestWebFacetURIAlpha1);
+  test_passkey_model()->AddNewPasskeyForTesting(
+      GetTestPasskey(kTestRpIdFacetURIAlpha1));
+}
+
+TEST_F(AffiliationsPrefetcherWithPasskeysTest, TestPasskeyDeleted) {
+  sync_pb::WebauthnCredentialSpecifics passkey =
+      GetTestPasskey(kTestRpIdFacetURIAlpha1);
+  test_passkey_model()->AddNewPasskeyForTesting(passkey);
+
+  std::vector<FacetURI> expected_facets{
+      FacetURI::FromCanonicalSpec(kTestWebFacetURIAlpha1)};
+  ExpectKeepPrefetchForFacets(expected_facets);
+  ASSERT_NO_FATAL_FAILURE(RunDeferredInitialization());
+
+  ExpectCallToCancelPrefetch(kTestWebFacetURIAlpha1);
+  test_passkey_model()->DeletePasskey(passkey.credential_id());
+  RunUntilIdle();
+}
+
+TEST_F(AffiliationsPrefetcherWithPasskeysTest, TestInvalidFacetsIgnored) {
+  test_passkey_model()->AddNewPasskeyForTesting(
+      GetTestPasskey(kTestRpIdFacetURIAlpha1));
+  test_passkey_model()->AddNewPasskeyForTesting(
+      GetTestPasskey(kTestExtensionRpId));
+
+  std::vector<FacetURI> expected_facets{
+      FacetURI::FromCanonicalSpec(kTestWebFacetURIAlpha1)};
+  ExpectKeepPrefetchForFacets(expected_facets);
+  ASSERT_NO_FATAL_FAILURE(RunDeferredInitialization());
+}
+
+#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/features/password_features.cc b/components/password_manager/core/browser/features/password_features.cc
index 8e22911..05399afe 100644
--- a/components/password_manager/core/browser/features/password_features.cc
+++ b/components/password_manager/core/browser/features/password_features.cc
@@ -89,6 +89,13 @@
              base::FEATURE_DISABLED_BY_DEFAULT);
 #endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
 
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)  // Desktop
+// Enabled in M121. Remove at or after M123.
+BASE_FEATURE(kPasskeysPrefetchAffiliations,
+             "PasskeysPrefetchAffiliations",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
+
 // Enables different experiments that modify content and behavior of the
 // existing generated password suggestion dropdown.
 #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)  // Desktop
diff --git a/components/password_manager/core/browser/features/password_features.h b/components/password_manager/core/browser/features/password_features.h
index f1e6ac4..9ce896e 100644
--- a/components/password_manager/core/browser/features/password_features.h
+++ b/components/password_manager/core/browser/features/password_features.h
@@ -41,6 +41,11 @@
 #endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
 
 #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)  // Desktop
+// Have GPM passkeys trigger prefetching affiliation like passwords do.
+BASE_DECLARE_FEATURE(kPasskeysPrefetchAffiliations);
+#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
+
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)  // Desktop
 BASE_DECLARE_FEATURE(kPasswordGenerationExperiment);
 #endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
 
diff --git a/components/safe_browsing/content/resources/real_time_url_checks_allowlist/real_time_url_allowlist.asciipb b/components/safe_browsing/content/resources/real_time_url_checks_allowlist/real_time_url_allowlist.asciipb
index 2635870..87f0cd9 100644
--- a/components/safe_browsing/content/resources/real_time_url_checks_allowlist/real_time_url_allowlist.asciipb
+++ b/components/safe_browsing/content/resources/real_time_url_checks_allowlist/real_time_url_allowlist.asciipb
@@ -1,3 +1,3 @@
-version_id: 5
+version_id: 6
 scheme_id: 0
-url_hashes: '\x00\x05\xc3t"\xde\xfcV\x9b\xbf\x839\x81\xb7G\xc8\x00\x0c\xa4\x11Nt\xed\x84\x99*HO5\x88\xcf*\x00G|j\xd5\xb1\x9e\n\xd1_\x01\\\xe4\xbb\xd8\xf8\x00]EF\xb2>{\x04f\x05\x1b+\xaa\x91\xac\x14\x00g\xc7x\x17\xde\xc1LQ\x87\xa3\xb6\xb0@@\xde\x00\x88\xc6\xecq\x88\xf3*\xb0\xac\xf6`@\xc4\x81\x19\x011u\xd0q\x97\xb3)\xcas\\`\xad\x80\xaf\xc4\x01;\xbdI\xeb\xf6S4\xfc%5\xaf\x0b^u\xb7\x01rr\x0e@\x8e\x9aw\x06\xc9\x81F\xf7\x06\x82\xe5\x01v\x11\x0f\xd0\xfc\x93\xb6\xe3\xba\x08a\xf8\x0f\x08X\x01~}\'\xe5\xe2\\\xd8\xa6\x9f\x96\xc9Z\xc8P[\x01\xc8\xfd\x12\xce\xdc\x17/\xfe\xa0\xa7\xfdC\xfa\x93\x8f\x01\xf6=\x9e\xa0\x85zio\x0bC\xb9-1\xaf\xc1\x02\x13\xfc\x17o\xaa9 \x9b\xda\\\'\x0c\xb3\x94\xfb\x02J\xd6\x00@!t=\xf8\xdab\xc6\x8f\xf0Q\xf4\x02Sx\x1a\xb6W\x07\xf8\x8a\x87\xfe\xacv\xe4>7\x02\xa1\x16@\xb4\xa0)\x81eC\xae(\xd5\xda\xe1q\x02\xa1*\xe3\x84\xd4\x03\xa8Z\xe3K\x950\x0b\xfe\xfc\x02\xcb\x93\xbf\xa5\x83l\xa1\xe7\xe4\xdbLc\xec\xed\x1d\x02\xee\xf2\xa5\xd4\x88\x16%,\xa6\x10\x9b\x1dYw\xec\x02\xfa\xc0C!\xfe\x93B`\x97\xec\xc9P\xa1\xf30\x039\x91\x9bC\xa6\x8b\xa1\xb3\xf7\xf3r\xb3\'\x9c \x03I)\x11\xc0\x01v\xfe\x95Ox>\x12\xd3\x85\xdf\x03\xb75\xbf~\xce\x8e\xf7\xef\x17\x82\x17t\xea\xec9\x03\xbf\xc6\x9cr\xed\xa5\x01\'(\x955\xa0\xd00$\x03\xc20\xa1\x9c\'\x90\xa0Pi)W\xaaa\x84e\x03\xc9\xf7\xde\x97\x87\xdaR\x17\x89\xc3\xd2\x86\x8du\x99\x04\x0b\xd8-\xd7|\x1e\x06\xff\xd5\xa9\x06I\x13\x935\x04\x1f\xd7`\xb9I\x17\x99\x8ff\xf6\x01\x86\xd9\xd6\xcb\x04*F\x0b\xdcS\xc0\xc1\x05\xc0\xd1]\xb2m1a\x04BuI\x9d\xe5\x80\x83\xdeF@\x10J@\xff]\x04F\xc9\xb4Y\xe0G\xdc_\xce^VF\xf6\x95\xe5\x04e\x95\x8d4\xb4\x16\xc9fs\xec\xdahD\x8b.\x04\xdcb\x8acQ\xeaiJ]\x01\x12\x14\xc0\xe4\xbe\x04\xff\xa7g\xe8\x02\x0f\xc0\xa5\x0bO\xb7\xdb\x02W\xd1\x05!\x1c\x13\x17\xa97O{\x11\x12\x10\x98\xa4^\n\x050\x93\xde\x97r\x7f\x19d6Q\xcf\r\xd7E\xe5\x057l{\xb0$\xca3\xa4\xf2\xfb=\x99\xcew\xf3\x05_{\\\x81\xc1w\x14\xc5\xce\xa0\x87\x90\xa7\x1b\xb1\x05\x8b\xc0<]Yu\xef\x14\xee\xd1P\x07j\xed^\x05\xcd\xe0\xc3P\xf4\x9f*\x97\x92\xfc\xb2g\x1f}\x8f\x061\x1d\xabG#\xac\xbd\xf9\xb7\n\x84\x94b\x11\xaa\x06n\x83\xa3tpKq\xec\xa4\xf6N\xb1\xd8\xb4\x9d\x06\xc1\x88\xf0\'\xca\xac\xc8\x04\x81\x90\xe5`\x9b\xc0\xd9\x06\xd0y\xada\x9f\xb1\xae1\xdd1\xc7\x91\x1d\x88u\x06\xd5P$\x85\xd6\xcf\xec\xc5Y\xc7\x99jShV\x06\xe2\x00o,\xb4\xfc\xc6\njb\xa4"\x1c#\xd9\x07\x00\xc0\x15&.\x89(\x02\x9c\x884\xebp\xd1q\x076\xb9\xa5w@\x1fV\xfc\xffp>\xc4\xdd\x1fS\x07RU\xf9\x13\x17J#r\x10\xec\xfeU4Z,\x07g;\x8a\x99\xd1\x8a`\xc7`,\xddf\xdb\xde\xc4\x07q_=\x9e4\xafTDI2\x17i\x11Mx\x07}\xa0z\x1f\x9d\xbc\xf1\xceB\xdc\xec\xcd)\xc3\x80\x07\x89\xcb\xc6\x92\x8f\xeeK}O2\xae\xafF\xf1$\x07\xa2|\xdb\x8f$9\xb6\xca\xef\xa1^vl5\x87\x07\xe1t\xe2X\xc4\xc4\xe9\xd7\xc1?.\xc8\xa3\x8ad\x07\xea(\x8d\x08\x0b\xaf\xb6\t\xce\xedM\x18_\x83\x91\x08\n\xd8\x11e$\x8ba\xd9j\x984\xa9\x0ey"\x084.\xa2\x18r\xf2\x04\xeb\xd1\x83\x99Q\xb6\xc1j\x08\x9f\x05\xb9\xe9\x92\x9bSV\xc1\xf8\x13\xc4\x88\xa2K\x08\xa6ny\x04\xab\x1f\xb1\xca\x15\x8et _\x17\x9f\x08\xc2\xb6\x1f\xc4\xeeCN7\xcd2\x17\xa6\xc0f\xad\t\x13\xf6l\t\x16+K6\xa0p\x04>\xa7&t\t-7\xda\xfb\x8b?\xc2\xf2S1\xd1\x11\\KD\teC~a\x94$\xd3\xdfJ=C\xb2\xed\xa1}\ti\xa4\xf3{Nq\xba\x88\xd3\xc8\x8dg\x98{\xde\t\xa0\xa9)\xaf}\xcf!0\xd6AO\x033)\x8d\n!0\x10\xd8)\xa3\xf4B\x16\xa3\xd7>2\x91,\n8\xb6\xad\xc3\xd5\xbf?\xdc\x16>\xfe9F\xd8^\n:\xf6M\x07|*l%&\xe5I\x11\x8c;%\nb\xf4g=\x92\xa1p\xe1n\xc7\x8cz\x91\x86q\ng\x9ej\x04\xd7:4\xc3!P\xb4\xb1\\\x8eq\n\x89\\\xfe\x0f\xf6\\\xec\xbd\xc5O\xbb$b!\xd8\n\xb4G`\x8e\xe2k\x87\xeb+z\xb6\xb2.\x0fw\n\xde\xf0\xfe\xe7\x0b\xd7\x90*\xeb$\x98\x83\x1d$N\n\xe1\xb4Zx\xf4\x0e\x8b~\x89(D\xe5\x81\xc8\x80\n\xf3\xba\x94<\xc1\xbe[\xa9\x9d\x98\x05Q\xd4\x1e\xec\x0b.\x92\xc6\xf6\xe8\x84\x83\x175nw}\x0b\x97"\x0bR\xad\xbf\xd3\x9f\xd6\x12}\x92M\xce\x84\x9f\x94T\x0b_`\xd4\x98\xf9\xcd\xf6.\xfd\xc2\x9a\xc0\xc8\xc9s\x0b\x91\x9em\xe3\x1c$]\xb8\xadx|t\xd2\xc8\x02\x0b\xd3\xa1zE!U\x83B]u\x99\x94V\x13\xda\x0c\x07\xe5n\xd2I/!/I\xc5\t\x0f\x13E-\x0c\\\xbe\x17\x07\x8f\xe36(\x87\xca`vg\x03\xcd\x0c{a\xd54?+\x07nh_g\x07ys\x94\x0c\x81\x87\x8fOP\xe6\xd5,MKsBM_\xba\x0c\x88\x86\x80\x01\n2 Q\xce\xa0\x996\xddm\x9c\x0c\x96f\xfeB\xbb\x03\xe8\x90f\xa2N\xfa\xa3\x1a\x80\x0c\xbf\xea\xa5\xabN-\x96&\xd37:\xecp\xac\xd6\x0c\xc40`g\xee\xbe\x84\x81\xdaZJ\xde5P\xa6\x0c\xd2\xc1\x9d&A\x81\x17\tL!\xee\xfb\x02,0\x0c\xd8v\x93{^\xde\n\x1b\xb72\xf9Q\x9f\xfbF\r\x18\xf4\xebb\xb0\x1e\xc7\xcf\xe3\x90x\xfb\x19\x973\r&\xb0y\x18\xbc\xca\xee\xba\xfeK\xc6?\x12\xc8\xa8\r:T\x8b\xa0O\xd9\xc7\xf3\xd1\xf3\xda4T\x84Q\r_;aB\xecP2\xc7d!\xe1\xb2@\x1c\xb0\rt#\x92\x12R\x1eHD\xa5\x87\xbf\x90\xb6\xa9\x1e\r\x82\xe3\xe7s<\xc1\x9d\x0c\xa2\xea\xd7\\\x0b%\xa4\r\x97\x17\x0fd\x95(\x18\x8e\xe2\xdf\r\x9f\xd0:\xd1\r\xe3|\xfc\x95\xa8\x10\x93A\x92,a\xa3\x95\x0cp\x0e\x15\xc5\x97\x99\x01e\xf4K\x13\x8f\x08\t\x0f\xe4\xa7\x0e/-qVM\xe0\xeeRmC@Ys]7\x0e\x969\xec\xf4\xab\x8f\x04\xcf`;\x14\xd0\xe9Q\x03\x0e\xc8\xba\x89\x91o\x0e\xf60A(\xd3\x1a\x83\x0fJ\x0e\xf1\x1fK\xd2;\xc3&\x9b\x02\xc4] \xad\xafk\x0f\x01\x83=\x0f\x01\xb1\xf4\xcf\xc5\x80\x00\xba\xe2\x0bw\x0f\x03X\x91\x1b\x1e\x8d2}\x96\x7f\x8d\xe2N\xd4\xfd\x0f\x11#v~\xff\xd2\xffq\x18\xb5\xd6\xa0\x95\xfe(\x0f\'\xc1\xef4j\x0c\x1a\xe2]\xd3\xe4L\xd1#9\x0f?~\xd5\x08\xf7s\xbc\xefQQCq\x1a\x92\xb6\x0fGlb\x019\x03rv\xec6\x08\x88\xd8\xcd[\x0fU\x81\x18 \x0c\xc2\x02#\xcaY\x8e\xc9\xbf\xd4|\x0f\x93\xbc\x8e\xe2\x12\x9fV\xef.Z\xe4N\x00k?\x0f\xd7\xbc\x13Td\xd3\x18\xfahF(D5\xc0\x88\x0f\xdf\r\xc0\xeb\xf3\xe6\xe5.|\xf7\x1calB\xe1\x10\x00:\x8f\x9f~w\x0b\xc7}\x13\xb1\x1f\xb0\xa2>\x10\x80]W\xeb\x0eP9_\xfe\tKV\xe5v\xf6\x10\xa2\x1b\xac\n\xe0\xf6\xc6$\x94\xff&^*\x11\xa0\x10\xef\xa1C\x13z\xe8\r\x04\xcd50\rE&l\x11\x16\xccb\xcc\xe3\xe6i\xe4"\x17\x89\xfbVD\t\x11\x17\xd6-\xc5\xb6\x85\'\xec\x06[nI\xa5c6\x11B)R\xa8\x06\xacU[{\xbc\xd5I\xe2H\xec\x11D\xab\xa9T\xec\x13i\xd3T\xa1s\xd7\x97\xe1\xe6\x11PP\xec3l>J\xca\xf62\t\xbf\xc2^s\x11Z\x8d\xc2\x0b\xd4\x94\xfav\xd4(5\x81;\xbd\xa3\x11\xad\x11M.\x01\xa7\x0f\xdfb\xf5\xfbW5\xa8\xb2\x12\x0f\xdf\xd3z\xc3\x8a\x0e,\xad\xac \x9b[di\x12\x10\xdd\xd4C}\x03\x15\xd2\xaf:%Q:\xea\xea\x12B&\x1c\xd1\x9a\xa9Tc0\xa6\x964\xe7\xe7\xdd\x12[\xca\xe9\x9d\x0f\x03\xc6#"r\x05=\x1c\x85I\x12\\l\xd1\x1e3\xc1\x19&/GP/d\xb9\xf7\x12\x8e\xa6\x01\x0c\x82\x93\x8eFB\xb4\xae\x1b\x02v\xf6\x12\x9e\xc6,r\x96m\xcay~\xc8\xd9\xad)n\x9a\x12\xa0\xf0&\x83\xfb\xc0\xdf\xaa\x15\xec=\xc6\xd4\x9b\x13\x12\xaf\x1c\xcf\xf8E\xc0\xe7\xf0v\xc0Qj\xa6\x19\xdf\x12\xb9~\x98\xa0g)g\x152c\x1cb\x8b\xf5r\x12\xbf\xef\xb6\xfb5\xe5\xce\x8b\xafA\xcf\xb9\x82~\x1a\x12\xedS\xa9o\x0e\xaa+\xb1\x9a\xca\x9aIfz\xf3\x13\n\xb1+\xf7\x7f$\xe5\xdf\x08\\`\x96\x18\xea\x02\x13\x1cg\xee\xa5\xaf\x94\x1f\x86\x1a\x16>\x0c\xb7\xeaq\x13L\xddd\x1f\xa2\xac\xde\xf9&\xce\xf3\xed\xe0K\x1a\x13M\xf5~4\xfb\x05\xe5oytB\xf6\xf2\xd1\xcd\x13\x80\x06\x8dk&\xf9\xdf\x963\xd7fw@k\xf3\x13\xa4\xbd\x1a)\x81\x9d\x19\xe9\xf3\\0\x8d\xa3\x8d\xf1\x13\xa9\xf7*\'\xa9\xce\xa1(\xdd*\x83>E?\xbe\x13\xd9\xd0A\xbd&\xbf\x1a>&d\x9f_\xc2\x87\xea\x13\xea\x12~\xe5\xba\x8bKJ\x84\x8c3)2}\xe7\x13\xf9&dB\xcc\x97\xc7\x18\xbc\xb8\x1a*\xbf5\x1c\x13\xff*\xc9nX\xdd9\x90-+\x95\x84\xa8p\xaa\x14\x1d\xd8\xfd\xbce\xc0\x12\x9cX,!\nH\xd26\x14\x1f\xac\xec\xba#\xdb\xcd\xca\xa4\xdc\xf6\xcfd\xd89\x14K\x8c*\xed\xaf\x9ae\x97\xe6W\xf2\rv+<\x14V\xbb+\x99\xa6\x0f\xe8\xd0@\x8a\x1d\xe4V\x07\xec\x14d}\xad:\xaa\x19\xa8\x1e@\xb7*\xc6lW\x94\x14i\xd8\xeb\xba\x93\x89y\x9b\xb4&\xb9\x9f\xa6\xd0\xcf\x14\x8b\xaa\xf5\xa7\xe6\xadj Z\xf6\xcc\xf0]\x00&\x14\x99I\xb8Q\xeb\xa0D\x1c\xea\xa7\x0fz\x12u]\x14\xaf\x14\xf0w\xc26t\xa8T\xc9z$\xdb\xde\xc5\x14\xbb\x7f}\xbe\xef\xb3j\xd9\xcfi\\\'\xb2\\\xd2\x14\xd7\x1a\xcf~\xb1oW\x10\xf1!\xb1=\xdd\xc4\xbd\x14\xe7\xa0f\xfc\xd24\x1a\rn\xd9T|\x05k\x1c\x15\x14\xe2\xc7\xa2z\xbeGmh\xe3\x97/\xe4\xcd\x1f\x15&\xd7\x07\xb4\t\x841\xe3j\x13\x04H\xb1} \x15` \x99\xa9}\xde\x13\xb8\x95\x8bc\x18\xe7OU\x15s\xb9\xeeh0\x97\x90!GI#\x90\x13M\xa8\x15\x8c9\xea\x03}\xad\xdb@\xa1\xc5\xc9\x1f\x14Z\xa3\x15\xb7\xeaF\x8d\xea\xb1\xf9\x99\xde"B\xd9\xed\x11\x9b\x15\xfe\xd28\xa8t\xc8-K!m\x05\xe2g\xb6\x08\x16m\xaf\x9f\x95&\xd2P\xa0\xdb!\xcdl_u\xb4\x16\x7f\xf0[\x10\xd2;\xb5>D\x92Mw\x82O\xc1\x16\xe0\xf9\x17-\t\xf5\xfb\xe9\x92\xc5\xad\xbeb\x05S\x17\x05\xc1}\xeb\xe9:\x15kd\xebtl\xa9z\xd7\x17\x17}\x12\x93\x10\x1f\xf2\xf7z\xb3\x13\xe2\xcdt\xe2\x17!U8\x062\x85;\x0bq\x7f&=.\ra\x17N\x0b\xd9\xf7\xc0+?\xa8\x9e*\x1c\x9c|\x80d\x17\x81[X\x01U1\x83\xf7S\x8c\xbb\xa1\x16m\x0e\x17\x98\x9bk\xcb\x0e\x1f\xf7N\xc6\xe8\x0f\xc8\x06\r\x17\x17\xb8#(3\x9b\x19\xe7\xa7\xebT\xe1\xf2\xda\xe2\xeb\x17\xc8iU\x1d\xa8\x8c\x95\xf8\xa9\x11\n\x02\x92\x17S\x17\xf5T#6\xfd\xb5\x96q.1\xbf\xb2\xa8\xffg\x18lp\x88\xf9W.\x03k\xec\xdaH7\x15E>\x18\x92g`\x90p\xf0\x9b\r\xe0\xa8_%Q\xc7-\x18\x9f\x94|\xc9\xb7\xd6\'\xff\xd6\xf0\x7fngw\xa4\x18\xa55\n\xde\x95\nv\x9c\x1d?S\xba\x11\xf1D\x18\xc3$\xe6\x84\x0fA\xec\xc9\x94\xa2\xe1\xff\xc7\xc5\x8a\x18\xd7G\xab\xf2\x87\x1c\xe6\xdf\xdd\xb9>g\x02\xf0\xb9\x18\xe5\xbd\t\x0e\x04hj_\x03\x01\xcb\x82\x19\xff\xd9\x19\x14\xee\xbf(\x98\xf1W\xb1\xd0\x93\x86\xc1\xac\x8b\xd1\x19\x1dM&\xeaC\xda\x84[Q\xd1;Q\xecce\x19"\xce\xcf\x07tX@\x19C\xc7\x9d\xf2N\xc8B\x19g\xbc\xfaK\xea\xf3\x0e\x8d\xb4\x86\xc5O\x1c\x10\x06\x19ze\x1b\xbbq_3\\\xfa\x1a\xf04\xbe\xdc\xb7\x19\x81\xde\x0f\'_\xa9\xe0jI\x16\xcf\x86\xc6\xdf{\x19\xd3.\x82\xf9\xafu\xee~4h:\xd2\xa6T\xaa\x19\xdeb\xfa\x8d\xd7\\\xdc\xb5x\x07q\xa6\x81\x86\x1f\x1aS-\x11y*\xe3\xd8\xfe\xf4\x16x\xbb\x87\xdb\x94\x1af\x92\x18\xba\xbaZ\x1b\xb7\xac15~p\x8a"\x1a\xce\x05\x19j\xdb\x9eg\xf30\x00[\xe9\xaa\xa1\x00\x1a\xcee\xf0Y\x00.[\xf9s\x96\xb5e\x82\xb0\xfd\x1a\xe0\xa1\xe5\xb19\x1f\x85\x9a\xf6\xf3#\x1e\xfaSR\x1a\xe9\xe9\x8b\xbe\xf5G\xa6\xd1\x83\x1enT\x0f\xb6\xca\x1a\xf0\x91\x06\x06\xdb\xce\xdf\xf0J\xd2.\xba\x87\xda\xd6\x1a\xff\xf3\x00\x12\xf2\x0fEUt2M3}vc\x1b\x07\x12\x90=\xb8\xfdq\x06\x14\xb0h\xa4#\xbe\xa3\x1b\x18\xb4B\x15\xc7\xf2\x9e\xe8Pg\xacK\x8eGz\x1b$b\x13\xa5\t\x90fh\xb2f\xc7,\x14\xd9\xef\x1b(\x94\xbc|h\x88\xce\x0fnr\x8f\xc7tE\xd8\x1bY_\xfd\xc9!1^\xe5H\x8e<\xbd\x0e\x80\xef\x1bZy\xe9T\xf2\x04\xb9q\xd9\xfbu\x05\xdb\xf5\xb3\x1bf\xdf`\n\x1c\x1d\xd5\x85\rc\xcd\x93\x87\xdf@\x1b\xd8r\xa2]\xb8{\xfd\xf7\xf1-\x94\x96\xa2/\xc4\x1b\xda\x15+3\xeaI\xc8w\xe0\xc8\xc2jN\xbb\x17\x1b\xdf\x0bX\xf6r\x80K\xa0B\x9b8\x91\x88O\xf0\x1c\x13\x14\x97/%dD\x10Kql\x0f\xc1d\x9a\x1c,\x12\x15_Jg\x9b\xea@\x06\x03e\x16\xa3-\x1c:p{}\x9d9\x85\xd9\xd2\xbf\x87!\xdb33\x1cV~YMU\xa6`/\xcao-\xf0\xb7\'\x9c\x1c\\\xcb\xc5\xf5w\x94\xc8\x1fN\xf0N\xaf\xc8\xd4\x9b\x1c\x8d\xe6\xcc\xb9\xf1\xf7\xb9\x1d\xd2\x92v\x14n\x07]\x1c\x9e#G\xca\xbcj\x9d\xcc\xf6m\xd8\xb4\xc0r\x8f\x1c\xb6h\x8e\t\xb6\xcf\xbe(\x01\x9b\x8d\x90\xa4\r`\x1c\xb8\x1c\xad~\xcb\xeb\xa6\x81\xed#\'\x94\xaab\xc1\x1c\xc4x>\xe3>J5N\xda\xb07h\x0e\x0fj\x1c\xe9\xa8\xb7\x0e\xf1d\xddgz\x81/\x9a\x08\x83\xa6\x1dX\xa7N\xf1A\x7f\n\xdb#y\\\x10\xb6\x16K\x1dY^t\xca\x81q\xf2\xf0\xe3@G\xa7\xce\xf9\x10\x1d\x98\x88.\xe1\x1f\x81\xc2\xb6/\xa7\xc5I%\xf6\xaf\x1d\xb8\xe7\xa8Ed#\xcc#kv\x15\x13\xf2\xf7\x9c\x1e?C\xfc\xcd\xd4\xcf\x9cG\xc1\xfe\x19\x1f\x07\x18\xf3\x1ey*8\x99\xcez\xb4\xbb,\xbe\x1c\xb92w\xb9\x1e\x89\x19-\xe2\xef\xa0L3+SP_\x1ape\x1e\x95\x8d\xc6uQ\xcd\x9bf\xfcbv5R]:\x1e\xd7\x0c\x81\x86\xdd.\x1c\xd3\x96\x0f\xe2\xea|.\xe2\x1e\xdf\xee\x7f\xc4\x12\xf0\x18h\x07\x8d!>tD\x1b\x1f\x0c\xa6\x01\x98\xeb\xa0\xa4\xebSk\xf8\xa1\x0f\xe4\x8c\x1fA\xacr\xa7\xb4\xe1\xbb-\x8c\x8dynKy1\x1fG\x16\xec Yu\x0b~\xb4\xa16\x1f-\xed.\x1fp\x82\x08\xad\xadYF\xd8(\xbcB\x9d\x03\x0c\x8d\x1f{\xc4\xc7]\xa4\xcd\xe8\xd7H\xfc\\T\xefp\xf4\x1f\xb0W\xff\xc0\x03\xc5/U\xecV\x8bxz\xf0\xbf\x1f\xcbj9X\x94F\xfc\xc3\x01Y\xdc4C\xff\xb1 \x0b?Y\xdbO\x9f%\x83\xc2\x88\xc6\xaa\xf7\xa9\x00 \r\xacX\xc9\xcbN@A44\x0e\xf0\x9cah \x1b\xd6,B\x07\xbd8\xd0_\x803\xed\x18\xe4\x98 !\xbc\xfeN)v-\x12+\x97MwYe( 66\xcb\xf9w\xe1W\x9e\xcf\x1fN\xd9X/\x82 ec\xd6\x9a\x07\x0e\xb5w0\xaa\x05\xcb\xdc\xae3 s-\xfdq+R\xf3z\x12Z1\xd23H\x10 \xaeT\x84T\x92]\x12\xaek\x1d\xefe8\xc6L \xae\xc9\x88\xdf\n,\x0c\xc1\xeap\x88|\x8b<\xbe \xbc\xff\x98\xbd\xd0\x0c\xa7%\xa8\x87\xb0\x13#\xd4R \xbf\xe7\x8cv\xb65+|\xe4\xe6\x84\xd3@\xe7\xc6 \xe4\x00\xcbq\x85\xc9\x18\x88%\x1c=Q\x00\xac\xde \xf7\xf1Z(\xb4\xc7\xd3\xa6|C\t\xb7\x8f(\xb6 \xff\x85\x97V.s\xde\xebbq\xbeFi\x03\x87!\x0c?\xc8\xc1B@S\xd7\x18#g\x915\xaf.!\x16D[\xef\x08\x19\x82\x0c<\x08\xdbP\x96\xeb\x90!\x19\x86vn\xb0,\xf0\x02\x0fM\xbb(\xb1\x1e\x00!`\x87\x0f]\xe8\tms\x81\xc1\xedu\xb6\x8b~!`\xd7\x92\xb3\x10\xf3\x17\xd6\xc2[\x12y\x9d7$!mz\xf5sFq\x05\\\xd0\xd0r\xd3\xb7\xa7\x86!\x84g\xaf|2\x9e\xa3Go\x1d`\x85\xdc+\xff!\x8e`)\xfa\x93z>\xe7\xc3\xaf\x0fj\xc8\xe4<!\xd7Z\xf0\x84\xe6\x9e\x17\xae\xc6 N\x106\xda\xc9!\xf0\x99\xe2\xb47\x96J\x7fn\x87\x9ac\x85\x07\xc6"\x05\xda\xee\xe6d\x16\x1ba\xcdk\x8e?\xa5\x9a\x86"*|\xe7\xfa\x19\xf7r^\xe1x;\\\xcd\x0eh"4eo\x13c\n\x0f \x13\x84\xf8\'>He"\x86\xc2\xe9xH\x91\x86\x13\x1e\r\x151\x80\xd1\xf2"\x94q\xacx[\xea\xef\xc9\x0e`BT\xc2|\xe9"\xa5\xae\xfa]2\xdaC\x87os\xf5\x03\xbd\xfd\x07#\x1b\xfc\xf7\xf1=:!LG\n\xb0\x10\x01c\x8f#m\xa19\x13\xa0M\xcaB\'-\x84_\xa6\x93W#\xdeW\xbe\xbe>\xe5\xd5?\x1e\x88\xe1\x13\xe6\xc6s#\xeb\xfd{\xd4\x99cL\xad02\x1fwT4\xf7#\xf5\x11 \xaf\xdcz\x91VZ\xf88\x99Za/$! 9\xec^\xe8\xad\xd2\x8a>\x00\xc1~J\xb8$Z~F&Z\xff\x05\xee\x9eW\x91\n?G:$\x80\xb5\x1a\x95\xbcj\xdfv\xcd#\x9eO\xf4\xf2q%B\xf2}\xaf\xc1C\x04\x95(\xc3\xa6.\x14\xa5\x96%gf\x98\xe1\xee\xff\x1cuv\xa3\xf3+Y\x0f\x0b%\x7f\x90\x07\x95I]\xc7\xdc\xb4#\xacx\x03\x06\x1b%\x8d\xb5\xc6\xb5X*\\\x0b\xf6E\xdb\x12\xc4|j%\xb98\xc8jI\xae<\x04N-\xc5\x01\xf8n\x8e%\xf4\xcax\xfc\x06;\xe2\xe8\x816\x8a\xf78*\xe9&\r\x94\x9a9\x14 sA\x12\xd8\xba\xfb\x10\x16\xad&Un\xc1\xdf9\x0e\x16\x99q+\xfc\xce\x03a\x9c&\x80,U;\x0e\xcb\x1fV\xe7\x97h\x81K\xc9A&\xc1\xe7\x9e(e\xc1\xf2\xc7\xabz\xec\xbd\xb2\x8a\xcd&\xcc\xe4\xf9\xf2\xefa\xdf~\xe1OM\xd1\x9a\x9a\x06\'\x02\x9c\xf1\x14F\xb4\xc1H\x8f}\xd2\xb7\xcd\x01A\'S\x1f\x81\xbf\xbb\xcb\x9b\x19j"D"\xa3]\xd9\'V~\xc3{\xce\x82R\xae\xba\xc7O\x0f\xb8\x9f\x97\'mpA\xdd\x1a\xbc{\xa2\x12u\x0f\x87\x1a\xfb\x9c\'m\xe8\xb9\xd8\x0f`49\xe0\xad\xe4\xa8\xdc\xa3\xcc\'\xae\x83\xc4\xeb\xa1\xc0\xc4\x14\xe2/D\n\x01\x05\xb0\'\xbe\xb40\x8c\x00\x07?\x9a\xdbnO4\xca\xe3\x95\'\xef\xa5L\xc0M\x9f\x85\xba\xaa\xf6h\x8e\x83\x08{\'\xf4\x1bv\x05p\xd1\xb9y1.\xabt\xb0\x9a\x08(\x00GJ\xf2\x83\xcf\x8c\x02~xV\x16\x9c\t\xd4(,\xb8\xfe\x04\xbf\xe28\x1d\xad\xc0\x88\xa9w\x14\xf0(\xad\xa9\x16\xecA\xdd\xcfw\x95\t\x05aS\x8bp(\xb1m"\x9e\x1d3\xe4\x90\x18Au\x11\xe5m\xb3(\xc5\xbc\x95Z\xa0\x05o\xe7\x0e\xe5\xb4\xf9\xb5\x80@(\xc7\x84\xb6\xb0\xe5\xc6uH\x95\xe5\xa15J\x18\xeb(\xca\xdal\xdd\xb236\x96\x8a*\xf9\x1d\xbc\xdb\xf2(\xf8\xcc.\x1f\xea\x8b\x93\xe2V\x1e6U\xb1\xb7Q)\x07Vv*\x13\x82i\xc7(p\xa9\xae3u\x86)\x12\xec\x0b\x17\x91B\xf0\x94\xcc\xa0$0\x039\xb2)\x14\xff;a\xe3G\xf0\xe6(1\xbd\xf4\x90\x1fK)\x15\x88\xb3\x97o\x97d\x01@C\n\xac\xe5\xb7\xbf).\xa7\x93\x0c\x16\x8c\x80\xa9XB\xc2\x1c\x19\xb8\xa6)vV\xe9\xa5\xbf\xcc\xd7\x8a&<\x1fFu\x88\xb5)\xd0B\xf9\xf6[\xbd\x9a9Z\x0e\xef \x98\xf3\xea)\xd0r\xaf\x83|\xfc\xc7Mp\xf2s;\x02\xcd\xe6)\xfcE~n94\xedd/\xa6t\x9d3\xd3`*\x00\x8d\x85\xe7\xdb\xc6\xdd$\xc9\x1d\xd9%\xd0\x9c\x92*(UvR\xa6k\xf4\xdeE/e\x1e\x14\xe0\xfe*L\xf1\xac\x01)\xd9R\x966\xc6@G\x9cm\xf1*l\xc03\x12u`n\x9atH\xcf\x1c\x85$\x8c*\x9b\xe1\xe3qK.\x84U\xadVkj\x0c\xe6)*\xc0\xaf\x1d\x07\x168\xcb\xcd\x0c\xab\xf7\xda\x1f.\xca*\xca;\xa8\x17S\x9ed\xd2N\xe8}\xc7\x9f\x94\xbb*\xe6*1Z_\xbf\x9d9\x7f\xb2\x13\xad\xdd\xe9\x96*\xf2R\x0c\xff\xf4!\xafB(a\x8c\x07(b +!U\xb3:\n\xc2\x80\x0baP\x9eR\x10\xf3\x13++\xa0\xd6\xc6\xc5\x87\xea\xbf\xd0v]\xc7\xbd\x18\x8e+1\x18\xfbK\xd1\xd6\xfa\x15\x84\xd7\xbdJ\xfdB\xaf+W.\xa1\xb3\xba\x9c[\x87`\x18\xe9\xc2\x98M\xc5+]\x90:\xea>Jo\x8fm\xe5yu\xa8Y\xab+f\x98\x8c\x04\x03\xbe\xbb\xaa\xa3\x8a\xc5\xb4\x96\x07\xa1+qS\xee\x81\xc7\x86\x99SA\x99\xe1%\x92*\xca+u\xd4 ]\xa9\xe4\x9bwd\xdb\x08\x0bJ\xaa\x11+\xb1\xfc\xb5s\xda\xad\xd4\xf1;h\x89\xeeY\x86\xc4+\xcbw\xce\r\x95\x03\x89\xeef\x1d\xf9\x91\xec\xfef+\xcd\xf2\x1b\x11,sx]-y\xa8u\t\xfe\xbb+\xd8+y\x99\x02V\xfc\xc1\x86ry\x10\x96\xdf\xdd+\xf2\xcb\xd2?\xbf\x8c\xdd\x19\xc27\xee\xdc\x93\x13d,@X\x89=\xe5\xf4\x13\x12_\xa3\xc5\x94p\x98W,K\xcc\x8c\xcf4\x8c2\x88\xb0\xb7\xcf\xe6\xd0\xeb\x97,y\x16\xfa\xdd_0\x04\x1ea\x86P\x99B\xb6\xe8,\xc7 \xf10\xbb\xe4\xb4J\x88\x83>\x00\xf3\xca\x1b,\xcb\x94\xc6\xd3\xd2%\xdbq\x81\xe2\x0b\xf7&!\xc5,\xee\n\xfe\xe2]\n\xbb\xc0ywbK=g&,\xff\x8a\xef\xa9nl2\x9dt\x00\xdf\x08\xc4\xc7\xe0--\x9f\xcb\x85\xef\xcb\xe1v{\xad/,\t\x15\xbf-NH\x12{\x1e\x9b\xe2bc.\xfb\x97U\xeb\x9c-S\xf9\x19\xc8k}\x87\xeeQ\xbd<\xf4\xac\x04o-\x93m\x16@\xd3\xb14\x9fV-|\xc5ky#-\xad\x10]\x02\xcak\x93f\xf2\xfe\xf5\x11\x03\x0c\xa3-\xc0+\xf0\xf8\xb8i\xb9\xd5\x8f\xa3E\xb9\x07.\x94-\xfa\x9f\xf0\xd9\xd5\xc9%}G0;\x89q\xfcw.AB\xaaDx\xc8\xd0\xad\x87\xfd\x08\x98\xf8\xb9\xd5.\x91\xaeq2\x13\x8c\x08\xc2\xc6\\\xcc\xdf\xa2\xd3l.\x96M\xa1\xdb\xef\n\xcc\xc7\xeb\x8b\xa0Lg8\xd9.\xb9\x8b\xca9v\nC|\xb9\xf9\x99|\x0f.\xf9.\xbb4=\xe0\xfa\xa5\xa6kX_\xc6\xda\xe9{1.\xc8\xbc\x00\xd5=\x1a\x04X\xf6@\t\xa7Z\xf0\xef.\xf3\x99\xa8\xcfT\xdd\xc2\xbdWZ\xf4\xe7\xfe%\xaf.\xf5\x81[+K7\x18\x91\xe8\xb1\xe7l\xd8\xe1\\/\x05%l$\xa1\xfa\xa9r\x94\x80:2\xa1:]/\t#\xbc&\xa8\x05k\xdf\xa2\x83{\xa5/\xeb_/J\xb5)\xbcYY`\x86\x19\xf4y\xe1i\xfc]/\x8a\xee\x98\x8e\xbcI\xc3\xf7\xeb\xbe\xfd\x93\xd5\x8d\xf3/\x95\x96&\x07\x08\xdc\xec\xc2*\xa3\x08\x85x\xa6\xae0\x06p\xc0u\xf6\xb0\x98\x9f\xa3(\xf0\xea%\xa5\xb30"\x19\xf2\x0c\xa8\xff\xfc\xa4\xf8\xe9\xab\xc1A\xd0\xce0QT\x8dfw\x1b\xc0!_<\xdfo\x9a\x1b\xcc0t\xe0!\x03\xad%9\x8bj\x80m:\xa7\xaa>0\x9b\xed\xe0\x95u\x1au\xa4Z\x12\xf0\xdeb\xe0v0\xb8g\xa2\xc1r\xb7\n\x8c\xf5\xbek\xd9Y\xfb11\x1b\x95\xa2\xe7\xc5\xb2\xdf5\x88tnII\x10\x8e12\xf4x\x99R\x8d\x80t@E\xca\xa3\x08\xd8j1b\xff\xe6\x87\xf2\xd8g\x8f\x93#\xe8\xa0\x86\x83\xc01j\x94^\xc0qvh\xe8\xb37\x95\xdb\x94\x1f\xda1w\xd7:\xaf\x99\x9am\xb5mi\xf5\xde\x0b\xee-1\x85\x13\xac\x1d\x9f\xdd\x12\x81\xf9Y\xe5\xffZBE1\x94Qi\x86J\x02\x10\xee#\x12f0c\xf6(1\x98\x01\xb2;^"#\xd8@\xc9\xdb:\x15\x93H1\xa6\xa4,S+\x80\xe4|\xfb>\xa23)>\xf71\xbf\xaf\x9b\x82\xba\xb3\xaf\xd6s\x96\xad\x989Hy1\xfb\xe3r\xdb\x8e\xd4\xdb\xb9\x0fi\x16)B\x84L1\xfd\x04\r-E702PV4\xfdJ\xdb\x0c2\x11x\xc4f\x1d\x9djl,\x98r/s\x1b\x812+\xf8\xb0\xae;*\xc9~3k\x8a\xb9\xff\xabe2e\xaez\xb8\xba\x10U!\xd8\x81\xb3u\xf6<22\x96\xf3\xfb\x1eTV\xd5\x1c\xb7\xf7\x8do;z\xc02\xc1\xba\x02mI\x00\x86\xf6:\xc8*j\xdbr\xb43\x0f\x11r\xdb\x92d\xacE\x00\xafi\x13Z\x1f 3\x0f\xee:\x8c\xc3\x89\'\xdc\xca\xc5dO\x000\xd23\x11"\xd9X\xa3\xc5~\xb0;\x9d\x88\xc2\xf9{\xf43Ej{e\xef\xd3\xdeGR\x8e\xe4\xbd\xed1\x073y\xc0\xaas/w\xe6\x18\xc3\x08U\x8e\x82\x18\xc53\x9da\xc4\x18\x00\xd6\x15Q\xa1\x978}U\x1e\xd03\xd5\xd9\xd3}\x11?{J\x86y4\xb7%.\xda3\xe5l\x1d^:UCJw\x92\xe3\xb6 Z\xba41\x00H\x12J7\x99!l-;u\x95\xbf\xc84q\x00V\xd4\xed3Mu\xe4\\\t$\xb4qm4\xa5\xdd8m\x19gaB\x16\xb9\xc8\xf8\xca_\t4\xac-\xe94\xe59\x99\xf0}L\xf6ob9\xe44\xbe\xd1\xe8\xae\xb1\x872\xc9N\n\xd6\xe3\x8bv\x105[M\x07\x02\xac\xe2\t.!\xd6\xccR#+\x145\x81~\x98\x92\xca\xdd\x8d-\xbb\xca1\x84\x91\x97\xdb5\x8d\xb08\x8f)\xbe\xfb\x97\xb9\'js{\x8ab5\x96lf\xc3\x03g\xd5\xd1m<\xb2\xa4\xb4b\x865\xbe\xe1\x0c\xd3\xa0\xb7\x19\x1c\xae\x97Pk\xd5uV5\xceq?r\x19\x83\x14b\xef\xab\xdcs\xb4\xda\x965\xe02f\x0e\xdb\x92\x1c\x0c\x0c\xe5\x9b\xfa(\x9d\xc55\xe5\x91\x17\xd9\x94\xb1\xcd\x86\xe3sq!\x1fZX6Oj\xe5c| \x9d\x8bM\x83+\xe6\xea\x1e&6a\xa3\x14\x8b\xb4|\xa6\x12\xd4\xfc\xc6%\xc2\xd4:6\x8f<XB\xb4m\xb7\xbe\x87;\xc1\x88\x9c\xa7U6\x93\xca\x83\x8f\xa6z\xb9HFp\x1a\xbe\xa4\xdd\xcb6\x9b"\x08\xc4@\x96c\x8c\xba\xb4\x94\xebS!96\xa4\xa2\x17\xe0\x15\x98\xe9X\x9b7\x0f>4\xd2\x166\xab\\\xa0\\\xe7\xe2\x00$u\xc1\t\x03\x97\'K6\xfb\x10V\xfbK\xbdJ\x95\xb2=\x9ea\xea)I7\'q{\xbe\xf4\xf0\xe6\x8b5\xcc\xd71Y\x91\xe97F\x8a\x97\xe1\xb2/\x15\xfb\x1c\xcb&8w&\xc47\xd7\x011\xa2cG\xdd\xfa\xb0\xa7\x97\x8a-\xc7"8\x1f\xe0\x95)\xbdBDQ\xaa\xeeD04\xcf\xf38,T\xab\xe1yM\xab!\xd3jE\xccd\x0bj8N<\xe27\xfa\xcc\xb7V]\x1c_\xc2\xc6_\xc68h\xee\\\x0f\x0f\xce\xcf\xae\x84\x0e\xa5\\\x01\xe0\xd18l\xc9\x13\xc6F\xa1J\x82\xc6.\xec\xa8\xdb\xee~8x\xae\x8e$\x92(\xa9\xa3\x99h\xaa\x15,\xb3\xc48\xa69\xf8\xb2\x13h\xfa\xf8\xfe\x18\xbc\xc3o\xd0\xf18\xaa0\xca\x9fl\xe2\xd322\xc9~\x05N\xbe\x848\xabu.\xc0\x83\xe8\xd5\xb0\x12qX\xf9\x88\xe7"8\xcf\x8f\xec%\xa1\xc4\x85\xfa\r\x85WN&v\xdf9\x0f!\x00-\xc3\xdd\xb8\x90\xbc\xc4\xb8T\xff6\x059\x1b\xbf_%\x84\xea\xeb\x03\xbe\xa5\x12\xdf\x97\xf1<97\x83\x15(\\f\x81\xfc\x132\x0b\xb5\xcf\'\x919DM\xf7Emp,\xf9hy\xf7*\xa9\xc0&9K\xd0\xd4,\x02\x96\xcb\x11a\xb8\x8a\xcdQ\xcb-9Y\xe7\xb5\\\xb6(\xc8z\xf2\x18\xb0\x17$\xa2\xbe9|#z\xeb\xe1[\xc2}\xd9\xcc.\xc0\xe1\x11C9\x86\x03\x97<\xbeZ)\xd0\xb1\xc3\xb5\r\x85\xaf\xc49\xb9"\xdc-\xe9\x80\xce\x9a\xf8w\x8a\x93$\x18\x899\xc0s5\xed\xb6\xf5P~R\xf15\xa4\x90\x0b\xe69\xccJ\xbfbG\x1eT\x86\xc0\xba\x84\xb8\xb8\xc6Y9\xd2\x9a\xc0\x86O&\xa0\x81\x82\xc0\xc4\xca\xb5]u9\xe3&\x1cG$}\x04\xfd:4_`\xdbB\x179\xe6\xa7\xc8Y~\xeb\xe5\x04 \xfb\x80\x133\xc7u9\xf9\xfd7\xcd\x1b \xe6N\xfd\x08U\xd7_\xd5Q:\x05s3b\xcdT\xbe\x0e\xa9\xf1=^ \x90\xba:SDp\x06\xd7\xa94\xde\xe7\xefk\'\xae\xae\xfe:\xa8\xc5\x1f\x04\xbd\xab\x95\x83?\xe8G\xef\x10>(:\xb6\xb87\xd26\xc6\xf2`\xeebk\xbe9\x97>:\xcb\xb7N\xe5k\xfcO\x8c\xf8\xcb\xd81\xf3\xb9\xc6;\\=\rH\xa5\x84\x03\xc7\xae`\xa8\xf7\xab\xc7\xa7;_M\xb0\xc5\x1c\xe2\xc3\x816\x06\\\xb4\xd6of;qsU\xe8\xb0\xa1\x17+GwP\xd1\xdd\xba\r;}?\xb0z#\r\xb3\xb5\x93\xfbB\'\xb5\xed1;\x83\xf2\xb2\xd1\xa5\xcd\xb5=U\xb5\x9bG\xb5\xec\x80;\xf5\x01\xf0\x10\xa3\x92)\x1a\xbd\xf84\x7f\xcc\xe8h<\tq\xbc\x05\x1a\xcf\xd5\xf3\xb2:<\xf1\x87z\xa5<\x0e3\xb1>$8\xaa\x17\x82\xc6V\xd1\xf6\xe8K<2\xb26\x9c\x16&\xbe\xec\xd5\x9d\x03\xf0}\xb6\xe0<:\x98\xbd\xc5\x1e\x97az\x1c\xb2wY\x85\xe9;<T\xe7\x1d\x00\xd6\xa4G\x08a\xe5*~\xa9\xe9L<\x8bdBz\x81\xe0)U(\xa2\x1f\x04\x1c.\x96<\xd4\xb4\x85\xab\xc9h%bo\xb9\x9a\x83uF^=\x02\xb5L/u\xcc\xca\x85G\xb0He|-\x03=/+\x9fUQ\x8b\xc0\xf6!x\x86\x03\xfe3d=\x93\xc3\xb8\xb8n\xdf\x8e<\x9a\x18i\x1ew \x80=\x9f\x03-\xc7a&\xa7\xaa\x86\xcc\xac6\xe0R.=\xef\xb0\x90\xbc\x13\x94\xe4\xdd\xe4\x07HO\xd9\xb1\xe8=\xf4\r\xeewa\xdecDv\x8b\xe8\xc6)#\xe9>\x16\x959$\xee#\xde\xe5U\xfb\xdf\xfa\xd8[\x14>+\x9f\xa8\xe4\x8a\x8b\xc3\x9d.\t\xb2\xaf\xef\xe9\xb0>2\xb1\x80\xb7\xb4\xbb)\xd0\x06\xdf+\xed\x02oj>\\Y~\x0fY\rQ@\x8e^\x03\xa5^\x8ex>\xa8\x0b\xc5e\x89p\xc7\xe366\t\xed\xaeA{>\xd3\xba6\x87T8\x0f{\'V\xd4\xd9<0\xa2>\xe0\xe0\xe4R\xa0\x04m\xe0\x8d\\\xf8\xbf\xfd\x06\xff?\x10>{\x92MMW\x8f\xdc_]^\xe22\x99?$HM\x12\x93m\xd6\xbf\xa59\x8e4^W\xb8?E\x88#\xb6<^\x9ac\x8b\xd1\x0c8\xc8\xa9c?K\xd2\xeb\xe9\xe5G\xbc\x15f\x85j,\x89^\x12?S\x0b\xac\x0b\xfeK\xc3\x06)\x89R\x1f\x10\x0b\xb4?WI\x8b\x18\xf4"\x88&\xaaJg7\xfb\xfcs?p\xcc\x0e\x0c/\xdb\x88\xfc\x9c\xd4\xa8\xbd1\x8a\x8a?\x84%\x10\xed\xc3|\xfa>\x01\xf4\xa3\xd6\x86D\xb9?\xa4Md\x8e*\x8aN\xa1\xa3\xcf\x00\n\x97\x86\x88?\xa9\'\xf4\xad8\x9a$\x03\x97\xdd\xe0^\x01T\x11?\xbc9\r#\xaf&\xe7@\xe0P\x80ekg\xac?\xe5\xe3\x0f\xb4\xc9z4\x18\'\xb2\xa7\xcc.\x829?\xfa\x1c`\r!\x99\xf9\x14,\xad\x95B\x15\x0f\xd1@P\xa8Aa\xe3zh\x95\xe6\x1b\x15D\xb5\x1b\x1a@X\xe3t6\x11{\x0b\xbct\x9a\xb0AK`S@vI\xfcX"u\x8f\x84BHE\x84\xba\xbfS@\x93\x1c\xe0\x06\x89\xfb\x14;9\xac\xbb\x9c\xe5\xeb\xde@\xbf\x07\x03\xae\xefJ~\xbe\xcdo\xa2\x02\xc3d9@\xf8vf\xc9\xbb\x0b\x000\x03\xafl8R\x1f\x1b@\xfa\xda\xd2\xfe\x7f\r\x0e(\x91\x87h\x0fbE:@\xfc\x12\xed\x10\xf25\xe5k\x83\xb3\xcdgYJaA)\xc8\xd7\xc1\xfd\xe9\xe72~.\xc8\x13\x05\xd0\xc2ABs~\x87\x0f\x03\x84?/\xb6\xd5\xf0\x9c\x87AAB\x94\xb5\x00\x1a0g\x1e\xf2\x91k\xd3\xba\x9aZAI\xa7\xb4\xf5\xcd<P\xd0SK\xe0x\x00\x97yAS\xca\xbe\xdb\xadO\x16U~/\x8f\xa09\xad\xf9Ap\xce\n\xa9\x8fA\x14\xba\x1f\x01\x8f\xa1\xfb[\x94A~\x879F\xd4\xc0(i\x18_G\xe9Si\xc6A\xe58\x83\x12(\x8e\xab\x1a_v{\t\xd6/\xdaA\xf1\x15qY\xe1\xbd\x84B IzW\xa4TeB:\xa1V\xf0\xa60Z\xf1h]-L"\xa9\xfdB{4;\x99\xf7w\xa7\xd7\xe8\x96\xb1\x9d]*\x1fB\xdd4\xa8\xf5\xd9\x7fk\x96\xde!O\x01\x85\xe2\xebB\xf2\xfc\x94\xb5:\xe0\x989\xc6\x9a\x7fm\xfa\xfb\xb1D#\xfe7\xceF\xe4\x81\xd2H\xa5\xa8\xdd\xef\x17|Dw{\xb2-\xc6\x8e\x0b\xb2\xe7\xbc-An\xf4\xd7D|\xed\x03\x9d\xb8\x1e\xc5\x9e\xe9\xc3\xc0\x18SG\xa1D\xe6\x89\xbf\xddw^\xa9T\xda\x93?}\x9c\xebbD\xf5\x84\x08c\x07\xb8\xdf\x05o\xdc\xaea\xc8\xcf\xb5E\x16T\x89\n\xc0\x89\xb5\xb2t\xcf\xc3a\\\x1f\xfcE)E^\xea\x1c\xf3\x8e\'\x8f\xa2\xe5\xad\xcb\xcf\xfbE,fd\xe45z\x8feX\xbb|%\xb2\x0e+E?\x08H^\xd9\xban\x01\xea\x90\xe1\xf0\x00\x95\x13E\x95}\x1e\xb7b\xb8]6k\xdaO\x83\x0b\xf6OE\xb9\xa1\xd1f,\xc8\x18\xd5\xc1\xe8\x14*`\xa18E\xcc/\xe8!\xd4\x89;\xc6\x1f\xa4\xbcs(\xbe4E\xd2\xde\xd7\\\xaa\xa2\xfd\xc0\x92,\xbe\x08\xa8\x91cE\xe5[l\x02&\xe2\xcf\xad\xfb\xb4\x90\xd3\xc3\xa1\xcfE\xe5\x9d\x96\xe9\x93t\xbb\xb9\xa4q\x9d\xf4\x8c\x89\x1eE\xe8f8]\xf4d\xc8\x94\xb6 \xfa\x94\xa5\xefUF\t\xfb\xe8\x1e\xa9QD-\xd2)\xb4\x9b\xe9\xee\xbeF\x11q\xf4\x00\x8em<\xc6\x13\xd5p\x1b\xd2\xa8$F \xfb\xbf\xbc\xedG\x94\xa2\xb6\xceE*5\xa8\xc3F3\x11\xc8#]&$0\x86\x14\xbbd\xf8\x9b\xfeFB\x0f\xc0\xed\x93\x80\x87\xc8%\xf8\xac\x80yg+FO\x02\x87\x9b\xd0\xe1\xfc,\xf0x\xe8\xf3\xac\x99GFk\x8f \xed\xc4\x18\xdc^}3Ul\x1a\xde\xc3F\xa4|\x1b&\xbbk:W\x9e\xfe9\xf6%X\xc2F\xd9\xae\xfbX\x87\x7f\x03~!\xa1 \x8bo]VF\xfc\xfa\xdf\x11\xcd\xbf\x16\n;y\x19\xef}\nKG<K\xd1V\x96\xda\x84?\x82\x87\xd8\xe8\x03\xed\x88GD\x98\xd97\xda`>S|\x18\xccMFO\x96Gl\xc3Y\xe0g+\x18\x86\tq\xde\xd5\x01\xc3tG\x8d8}k\xf8|\x95\x87q{\r;\xdb1CG\x91:kV\x1e\xd6\x80r\xb2f\x14/\x8a\x12\x87G\xa7\xc0\x80\xe4yN#\t\x86\x15?\xb0I:\x9bG\xb0Qi(\t)W\x0b\xda5\xe5\x90\x90\x1eQH\x06\xc0\xe7c\xec\x94\xb8\xaf\xcc\x7f\xa8@\x92\x8b\x87H/\x01\xd9F\xb1\xcb\xe6\xfa\x9d\xa8&\'\x81\xea\xe4Hf\xb6V\x8e\xc9\x12\x17\x99\xbd\xec\x0e5\\\x08\xf6Hj}\xb7gU\x05%\x88\x8a\xc7\x037\x8c\xb0\x1dHj\xc8k\xea\x86Y\xea\xcd3\x90\x89@739H{\xe5\xc2\x8d\xbe\x83F\xc3\xef\x01\xe8\xb1\xda\xab\x15H|\xeaZ\x03c\xaeuZ\x04\xa6\x8d\xe7=\x80hH\x80h-\x8a\xdd\x19J\x17\xd4\xe1\xa5\xe2[\x93\xadH\x9d2\xa1\xa97\x84>\xb9\x9e\xfa\x88\xb7S\xc1\x04H\xa7\xac\xbf\xe8\x93\x0f\x90\x17\xb5\x03\x01A\xbc?wH\xac`\xab\xbb29\xfao*\xfe=:\x89\x97\x12H\xb7\xc9\xdd\xaaD\xb2\xddkA\x07B;\xf8\xd5\x01H\xc8\xdb-\xfc\xb2\xcf\xf3vo\x05\x01\x99k2\x03H\xf7*R1\x0f\x9c\xfeA~^\xd6\x97N\xc8\x90I\t{\xe0\xbd\xcdu\x13t0\x96}N\xe6U\xaeI>\x90\xa0\xb4s\xb9\xb0a9\xb0<\x17\x0f\xfa\xbcID\xfbV\x83;\x9e\xed\xda\xc0\'\x07\xd4#r\xd7Id\x9c\x9b\xa3\xf0\x05N\xe4\xf2\x88\xbd\x92\xfc\xe8\xd3Iu\xca\xd3#\xd1m\xe9\'$\xca\xf5zQ\x8d\xaaI\xcb\'(\xb6\xd9\xe9\xe6\xa4\xce\x87\x87\xcdN\x8f\x85J\x19\xf8\xdd\xa1\x9a\xe1\xb1\xfb\xb6\xe4\xaaF\x06\t*Jr\x1f\xd5k\xe0\x8b{\xc2\\Q\xe0-\xb5\xdb\xe1J\x8b.\x1e~i\x9b\x96]\xe4\xee\xabG\xa1K\x10J\xa6P\xa4\xc3\xd7\xcb\xb100DO\xbdz\x14AK\x03\x96\x1f\xa1>\x14\xc9}\xddGG\xceJ\xbd\x01K3\x9aX\x03\x98\x99!{h\x8ef\xdb\x14\xd6\'KNQ\xfc7\x1c\x872}\xefn;\xaf@\xdf\xacKiM\xebgC\xeb\x7f\x1bJ\xbb\t\xc3\xc43YKp\x9b3\xbaR\n\xb4RY\x80\x92&\xa0^\xfaKq\xfe\x17\xc2r\x7f\x9c;\x15\x00\x19\xbd(\\\xb5Kx\xa0\xa6\xa1g\xec\xd6!(\x89\x85;\xbc\xff\xfeK\xbd\x84\x96So"A\x93\xa0D\x7fj\xd7,\xc2K\xc7\xf9\xd6\xc6\x97\xcc%\xff\x90d\xecQ\xea\x82\x0cK\xc8s(\x06\xda)\x0c\xdd\x90>\xe6\xd0\xe8W\xe3K\xc9*;\x85\xcc\x8c\x04?|\xea(Q\x86\x0e,K\xd5o6s\x06\x142\xc6\xda\xfa4\x8f\xc4\xf1\xb3L\x00\x8f)\x8bO\xb8F\x8b\x96\\\xc0\xe3\x91z\xcbLF.7^\x16S\x98\x9fs:\xc4\xc5\xa0>xLY\xbc!\xf6\xe2|q>\xc5o\x12\x8e9\xbe\nL\xc0j\x9a\xce\x99\xcf\xcdEZ\xc2\xac\xac\xd2-\xa4M\'K\xe2\xb6c\xf3\x18=;1\xac\x81\x9cM\x12MJ\xdcB4\xf1\x91\x1eGOnyh\x1d\xb8HMMA\x167d\xb4\x9f\xd8c\xb7\x02\xf7\xaf\x9fdMS\xa6U\xda\xb5V"\x08\xa6l\x9a_\xb7./M\\\xa9x\xf9\xd01\xa5O\\:\xf5#&\xca\xbdMe\xd8\x9e-\x81\x04\xe4}\xac\xc4\x96\xc7\xde\xc1\x98Mn\r~\xdd\xa4*\x06\x1a\xe1\xeb\xbc\x0f\xaf\xa4=M\xf2\xd6\xf2\x91 \x1f\xf8\x7fE\xc0&eSh\xf0N:\x91H\xbb\xa8\x9e\x9a\x9e\x922\x18\xdc\x8b\x19\x11NJ\xd9N \x8cI\x97l\xd8O,\x00ez\xdbNb?wE\xadEX\xd3\xdd\xb7o\x12\xff\xff\xcdN\xd3\x92\xbbu5\xea`\xa0\xfb\x00\x0e,\xa3T(N\xf1C\x8e\x8a\xf6\\\xd4M\x03\x10\xbcq\x0e\x052Ok8\xbf\xdecX5;\xf8V\xea\x0c\x8f\x1c?O\xc4\xe56\x1e\xd7\xcaW\xa3\xbb\x90P\x90\'\xb2lO\xcd\x1f\x16\x98\xa1\x9f\xe2\x12\xc7\x91q\xa8\xaat\x99O\xd2|Q\xf6\xe5\x17\xdf6-\xe02\x01\xcf\xe4\xffO\xedc\xb4\xbb+t\t\x9f\xa0x\xee%\xc19\x03O\xf2\x83\x83@\xe6&\xb7\n\x8c\x16\xcb\xc6y\x1fTO\xf7<\xd4\xdf;"I\x90\xbcU\xed\x10d\x1b\xf0P\x11_la\x9b\x90I\x1b\x9d\x8eG\x05|<%P\x11\xf0\x8c\xf4C\x19\x01\x12`_\x14=\xbe\xb1\x90P\x130\xca\x86\rX\x90\x86\xd6[Y\xec\x12\xf9\x8bP\xa4B\xfb\xe4\xac\x95?1\xff\xd0\x13\x91\xaa\x00\x93P\xa5\xa6uGZ\x9c\x01=\xac\x17\xbb\xfeM\xd4\xbdP\xad{\xd4q\xe9\xc7\x95V\xabRl\x93\xb7C\xf1P\xb2\x0c\x9f\x00\xc4\xaf\x8d1\x84N:\x80%\x0cCP\xb8\x96\x8c\xfe\xdaP\xd6\xcb\xc5@g"\xc7\xb3\x1aP\xbb\x10<\x8e\r5"\x14\xf0f\xa7\xe2\r\x1e&P\xcd\xa9es\x8c<\x07b\xed\x95\xae\x86\xfff\xb3Q\x16\xe8m&\x81\xd1l[\x1d\xcd\xc4&8D\x9bQ\x1bIa\x1f\xb0\xc9\xdcv\xf39\x94\xe3;\xa3\xe0Q\x94U\xd6}\xc7\x83\xd3\x88\x83\xe9\x10\x12y\xc9\xd2Q\xad?\xfb$\x93\xbel\x10\x89\xf9\x84\xa7\xe5\x98\xfdQ\xe4\x92\xe32Vi4z\xc0\xe3\xe89\x81}\x06Q\xe7E\x11\xd0\x9e>\x06C\x15\xe3-\xe0\xc3\xab\x82Q\xf3\x87C\x94\x89\xf3p~\xc8\x88\xbb<\x1e7\x88R\x11\xc04\x1a@\xe8\xa4~\x8c=q\x05\x01*7R\x18\x9d\xba\xb9\xb4U\xaduV\xd4{\xfa\x88\x82\xe8R"\xe2a"\xc1\x93\x12\x13\xeb\xab\x9c\x06\xf81\x0fR.\xdc\xbf\xc8\xfb\xd9\xc0\x1b\xca\x03\xf8\xc1\x9c\x1f\\RR_\xf1XG\xf0\x0c\xf1\xea;\xd9UHs\xe0R\x8e\x02\xc3\xbd6\x18\xd8s\x96\xba\x8c\x19I\xe3\x0fR\x98\x81\xbf\x7f\x86Oo\xe5\x18\xa9\xbcn\x1f\xef\x9aR\x99\xe3\xf4\xd6~\xe8\xe7z1\xa2\x91\xad\xf1M\xb3R\xad\xc9\xde\x9e\xab\xe6,\xc9\xc2\xec\xb8\xce\x80\x18\xa0R\xba>k]Lvs\x02\xa6F\x0c\x9ao3\xa4R\xc1\xd3\xea\xb7\xdf&\x00\xe1\xe0$\x92~\xd9*\xf5R\xea\x13\xe0\x8f\x87\xf1\xb2\x8f%\xfa\x1c"$\xaa\xffR\xf8E\xcbwn^\xa7\'\xa1\x94\\\xc7\xd4"\xedS\x06\xe6\xe0\x8c\xa9\xa3d\xb2=\xa9I\xf0{2\xd5S\x19\xe1\xa4\xee\xea\xb0\x15\xa9\xd8d\x11g\x8cu\xa2S \xb8\n\xff\x8a\x18\xdc\x7f>\xe5\xb2\xaf-\xc3\x83S9c\xb3\xac\xfb\x08\xe3\x17\x8fS\x90p[@8Sj\x8d7\xd0\xc6mw\x1bN\xa0d\xff\xa2\xa8FS\xc5\xc2m\x10\x16\xa0%\x89\x90\xf6\xf1d\x159\x16S\xfa\xfc[\xbf\xc2\x95\xb4>\xb6k\xec\xd7\xdb\x06\xadS\xff\xeb\xd0\xdf\xbfxf\xd1\xfcA7\xa42\x14\x1cTDi]\x01)\xc9#\xcf\x8c\xf1\x15\xddm\xadfTY\xdadCN\n9\x04\x9dLQ@"Z{Tf\xf6\\\xd5\x93\x01\xce{\xea\x82\xe1\xcb\xe2M\xcbT\x81\xe6\xce\xbc\xff\x07$.5\x97\x90\x16\x1e\x0b.T\x89\x8c\xe5]~{\x01"x\r\xf0"`d;T\xc1\x9a\x95\xad}\x1c\xd9\x9f\xf9sQJ\xcbJ\'T\xc9i\xa9\xb8\x81r\xc33\xa5\xfdD\x10\xee\x16\x9dT\xcb\x0e\xd4?\xf9\xd6x\x81\xb4\x8bK\xc3\xc7p\x1bT\xce7\xe5I{\x8b\xf0{!\x0fdra,LT\xf2\x07}\x1c\xb6\xfc\n_\xe7\xe3\xbeG\xb6.0UM(\x14\n\x98\x87kB\xf7\xce\xfd\xf0Jl\xaeU\x83\x93\xe9\xaa^\x1f\x9c\xdd\xb8\xd6c]\xa9P\x0fU\x8f-\xc92V\xecy\xce\xdc\x9azg\x10M&U\x91\n\xbcx\x91\xfb[\xb3\xedf\x9az+\x87\x1aU\xb4j\x84O\x0c\xec\xbfp\xbb\xfd\xa0\r\x90z\xffU\xc8\x1f6\x17o\x12\xc7\xdb\xf8\xfaA(\xb2 5V(\ts\xf7pr2Va\xf7D\xc6\xcc\xe1\x00VlY\x80#\x8b\xd8\xfd\x01B\x06\x034\xb5\x8a\x18V\x93\x13\xfd\x10\xc5S\nP\xfe^\xbb\x0f\x90J\x8dV\x93\xeb\xb5\\>\xd6\x1b\xd7#\xba\xceS\xb2\xbf\x8bV\x95\xb3\xec\xa9\x8eRe\x99Sp\x10\xcc\xa4}\xb8V\xa1\xb4\xefQ\xb1\x9feQ\x80\xb0\x12\x83\x9f\xaf4V\xe7\xd9\xef\xb0\x19p\x90Dy]\x979\xf2\xa5\x9aV\xf1\xa3\xa6j\x05\xb4\xbd\xde\xbc\xd6ZDS\x88\xa9W\x1fYVE\xe8\x14\x97EO\xe0\x0b\xfe"16W8\x1a\x15\xaa{\xda\xe7|x\x05\xd2[0}\x1fWh\xb4\xa9F\xb1\x0c\xc5\xbd\xd9L\xa6o~\xf0eWs\x9ad\xf1h\xd2\x1a{IpK\xaem%-W|>\x89Cs\xf3\xb3\xa9\xe1\x18t\x9c\x98\x07WW\x85\xb2\xe7\xca\t\x1eJK\x97E\x1b\xbf\xc0\xfb\xedW\x90\xa9\x05\xee\x80\x05\xa7\xdf\xda\xd0\x88\x15W\x95\xd7W\xc3\xaf\x0e\xde\xfeZ\xeb\xb1\xdc\xb9\xd5\x99P\x9b\x17W\xcdy\xe2\xaeM\xb1;s@\x98ism\xe1*X\x05\xd6\xfdh\xbb\xb3\xb79\xe9\x895Bf\xb9\xa1X+\xc1$\x1dn\x7f\xe7f9\xac-t\xb7\xb5\xcaX_@\x85\xac31\xae\x1f\xb7\x0f\xe2\xf3\xd4\xfa\xf2Xd\x03\xd3[\x198\x1cr8\x06w\xc9\xe6\xb4\x12Xv\xa2\xe4#\xf6\x94f;A\x83\xf8w\\T\x8aX\x94\x95ke\xd4\xeab-P\x8b\xd3\xd8;\x8evX\xbf\x87D\xbeg\x8a\xbd\x8d\xff4\x8c\xc8M\xe3\x05X\xc9(\x89P\xb4\xcd,\xf2M\xaamU8\xfd+X\xd7)\xc5\x7f\xc5\xe5\x1dgd\x99x\x9czg\x0cX\xe6d\xb9\xb8\x1d\xba\xda\';\xa4A\xa8z\xf6\x89Y%\xb6\x90\xd0\xea\xe6|\xd1HE\xef\xdc\xe3\xeayY\x8c\x80\xd0\xe1F\xd9\xc7\x1bO\xf1\xbe\xbcw\xf1OY\x8d9\x1a\xde~+\x94\xe4\xc1\xd7j\x9c/0\x07Y\xab\xd8\xdb?\x12\xbbl\xf3?\xb3\x0f\x9d\xa6E\x96Z\x05K\xe3\x93f[!\x0e\xe3\xe5\x18O\xff\xe3zZ7/o9[\xe1\xea\r)\xbb\xe5f\xa6k\xb2ZU\x00\x8e\xe8\x9c2\x04U\x0eO\xed~h\xeb\x0bZel\x18\xd6pk$s\xa7rU\x0c\xed\xe9oZ\xa3\xf84\xca\xd71\x07\xf0\xd6\xdaI\x88\xb7\tmZ\xae\x03\xbc\xf6\xa3#+\x93\xda\xe3\x16\xa5\xda\xe8\xe9Z\xbc"\x8b\xd4&\xd8u\x92U\x83\xb4\xac&c\xf4Z\xd3=p\xf7U<\x87(\x18\r\x84\xb9\xff\xbc7Z\xd9\x9f)-\x93M\xfc\x93N\x9b\xd2\x93\xb5\x109[NViZT\xff\xe4\x80n3\xf9q\xab\xa8\x05[](\x14!\xd9H&r\xac\xc6^\x05\x1e\x05L[qc\x82V\x9d;\x8e\xd5J1N\xb8~\x0eM[\x8aB!\xd4\x8fh!\x88\x84\xd0\xae,\xdd\x19\xab[\xe1\x93)/`\xc0$\xec}\xbf\x86\xd7\x88\xda [\xe9iV\x02\xbbbT#\x9d\xc6\xe75nU\xd8\\\x03~\x02\\\xc0v\xdcF\xd6\x15\xa3r\xd7\xb7k\\\x12\xdbq\x95\x16\xe1\xb8\x11\xf1\xed\xc0B\xc4"X\\\x17Af\t\xb1\x16\xfb!\x1ef\xdch\xa8=\x91\\)\xcd%\x1a<\x8dCd\xbd\x84\xc0\xd89\xb9a\\i\xb1\x9b\xdcu\xe0\xa0\xbf\x02\xacA\x00\\\xb8\xe0\\pP\xbc\xabB\xa7r\xa3\x0e\xba>dH\x08R\\t\x1eU\xa4\xdc\xfff\xaf2\'\x862\xbbA\xd6\\\x8a8\xda=\x05\xeeJ`\xa1:\xea\xf5\x08\xd14\\\xafv\n\xa3\xa2\xb34\xfcY\xb5CXA\xc5\xbf\\\xc9\x90\xfb\xb7FJ\xe3\xe2\x12\xa0\xf1\xf1\xf3u\xe9\\\xf7r\xe1\x0f\xc5\xd01R\r\xa6Q\xda\xc3A\xb2]$\x93\xbbx]4\x0f$/\xbe\x82\xca\xe2\x00j]\'\xc2\xff~\xcft\xb4[\xca!p\xd91\x95\xd5]bn\xb9-\xa2\xf4\x93%4\xd36\xfe,1@]nn^\xe9`\x90@\xa9\x94\xc6\x89n\xe7N\xb3]y-\xadt\x84\x85\xbc\x18n5\xa9\x14\xc4 \x94]\x92\x12M\xefc\xb4\xedC\xb0\x11\xc5Q@&\x95]\x97\xca\x84\x14\xf7\x9c\x81\x8b\xa4\x8e\x0f\x97fd\xda]\xf1\xb3m\xd3\xbd]\x02\xf1\xeb\xf7\x96\xce0\xec*^\x1f\xd32\xaa\x18d"\xee\xf7\x19K\x99Q\xe3.^-W\xdcw/W\x96"\x08Bo\xec\xe2u;^IW\xca+\x10\x91\xb2\xaa\xda\x96\xff\x04^\x90\x14^hi\xac\x86v\xe6\t=\x95\x8b\xe4j\xb9\x0b\xb4^n\xb7i\x94\x83\x17[\xa4e\x89\x1a\x8e\xaf\xf1\xde^|\x14r\x99H\xfd\xaa"t\x02v\x8a[;\x00^\xb2\x1d>\x166aj.X\x93PQ:Gq^\xd2>\\\xc9/\xa1\xb1\xf2\x88\x17\xad\x94\xbf\xa5\x1e^\xe9\xa6\x9f\x07=\x9e\x864\xc5\xa0\x13\x10\x94\xbe8^\xfb\xd5\x00\xd7\xe94\xe14\x0b\x14\xa9\x1e2c\x1e_>N\xd5*\x87\x8em\x0b&t\xf2\x98\\\xd6\xb1_\x81\x0b\xac\xf6\xf0qIF\xce\x00\xc7J+@\xaf_\x8d4\xe1\xe8\x11\x8a\xf7\xdb\xccg\x85E\xeaO\xf5_\x8e5\x9ew\x8d\xf8\x0b\xb8\x08db\x97\xe23\xd5_\x90\x17\x9b\xb9d`=\xb4I\xd6\xee*\x9a\x8a\xa3_\xaeQ\x01+\xe8]\x95\xd7HqU\xc3=xD`\x15\xbc\xfd\x1f}R\xf0@\x90\x88)\x82\xad\xab\x7f`4\xc13\xe2P\\}\x1cz&\xe4Xo[\xab`L\x8c\x0c]\x87\xfco\xc6\x8bE\x83\xc1p\xb0b`]k8#\xe7B\xddCV4\xd9\xcadhE`c\xf8J\x84w\x8a\xec\x8d\xc3\xf0\x86\xcf(\x8by`f\xf8\xc5c\xe3\xfa\xf6RLp\xbfz\x85x8`gx(\x9aiFT\xcd{Z\x81\x1c\xca\x081`\x85\xd9\xcc\xa2\x0b\x08~`\xff\x12\x0f\xa4kN\xd8`\x9a\xb7&\xb2m\xe1\xf9\xd3R\xec\x86\xb3\x15\xd8F`\xb6\xabZ \x1f\xc6\x86uss\xf3\x03\x00V;`\xe2\x85\x81\xb9\x93\x8d\x9f\x07\xedW2P\xad\x1e]`\xf6\x82E\xad\xa7\xc2\xb5\xb9\xebt\xe8\xb3w\x1e\xfeaHG\x1e\x89a\xd6\x05\xa2\xccY\'\xff\xb9\xf6\xc5aJ\xe8W\x93^\x00en\x95\xe4\x9c0\x9a\xfb\x86aP2M\x17\xc1\'4!\x86\xaf\x82z\xe1\x8b\xfdai\xd5&\xa8\x1cQ\x94\x17E\x80\xc3]hH\x0ba\xbf\xb9\x89\x0f\x84\x1e\'U\xc0U\x9e\xa3\x01\xd0Na\xe6\x16>w\xd1T\x08\x1f\xa09x|n\xc5\x10a\xf0\x19o\x8e0**[\x8cX\x01\xe0l0ra\xf7\xfd=\xa6$\xb1_\x15\xc9\xa3\xafE\xdf\x82\x90a\xff\x9c\xb0W\x13s\tQ\xa0>\x8b\xcdk\xc8\xc8b\x07p\xdc=J\xb9\x19}\x17\xdf\xfbK\xf2\x0f\xd8b\x13\x83s\x98/\x82\xbeF\x98\xf1\xc4F\xc16?b\x1b\xeeG\x94\xe3\xa4\nu\x90\x12\x92\xe2T\x80\xcab$zy7u\x19\x93\xd6\x81\x9f\x8863\xe4\xb8bR\xf0\xd8\xf7\x1d\xad\xb73\r/\xe9\xcd\xfc\xc1*b|a-%\xd4\xc8\xeb\xcf\xbe<\xa2r\x9a\xe0\xa9b\x85\x8dA4S_VP\x83u\xed8X\x8cRb\x8d\x98\xab\xa8\xe3\xb2\x07bu\xe3\x9c\x91a\x7f\x01b\xa4\x05R0\xf5\xb1\xf5\xc6R\x0f\r\xf1\xd8\xaf\nb\xd0\xa7\xda\x17l-\xb2?j\x87G\xdd\xc1c\x84b\xf3\xa2\xc1\xc1\x8d\t\xd6\x9b\x83\xfe\x93\xa6K\xee\x1fc\x19\xb1\x9dvD\x9a\xbb4\x0bI38\x9f\xceic*|\xf68\x11\xdb\xac\xea\x89\xb0\x93my\xfbKcD\x00,\x1e\x16\x8a\xf8\xedK\xbd!\xcc\xb4v#cD\x15%\x9c!\x81\xb0{5\xfd\xac\xe7 \xdaIc\x8ck\x1bk\xcba\x85~e\x85=\xba\xb7\xbfPc\xb8\xcf\xcd\xc8~\'U\x06\xaa\x1c=\xaa\xff\x06\xd1c\xbd\x94W\xea\x03>\x12\x9b\xa5\x8e\x81\x12O\xcesc\xde\xae\x1d\x07%\xe8L~\x9c\xcc\xe35\x8f\xd4[d9\x94S\x81&X\x99\xb9\x80\xee\xbaie\x99&dA\xd8\x1f\x1d\x115\xc9z\xef\xf6]\x8e~\x84\xe9dS\x987l\xdf\x1f\xa4LFT\x1bML\x85\x98d\x85H~\x8ceW\x86\xb1\xd5\xd0F\xbe\x08\xfa\xdad\x8e\xa7\xa8\x01\xbf\xbdh\xdf=~F\xf6\xd9 \x06d\x95\xffe*]\x96v"\xb2^/j\x8d\xf5\xe1d\xa6\x14\xf2JT\xee\x860\xcb\xe9\x12`\xb1\n\xdad\xa7@,k6\x89II$L\x80\x0f\xb5\xec<d\xbb)xBw\xe7Fe\x1b\x8ej\x01\x10\xaegd\xd7\xb2B\xee\xe6\xe3\xa7"S\x89\x843\xe0\xb9\x0bd\xdfR\xe5\xaa\xb9\x87\r3\xf3\x95J\xba)\x00Je\t][`\x11c{@\xc6Ek\x978\xc6ieKh\xb0}k\x9178\x8cB\xb3\xf7\xf2*\xebe\x91\xfc\x99\xbb\xdfn\x1d\xb6\xee(1\xd4\x11mie\xcaH2\xabh\x97\xb6@\xe4\x91\xc1\xa6\xbb\x10\x08e\xfb&\xddC\xcb\xdf\x05\xc4\xf1Z\xd3\xea[\x8f\x0ce\xfbN\r\xa2\xcf\x1a\xcf\r?Q.\xf2\xc1\xee\xd5f\x13E\x17\xd9\xb3\xc7\x9f\x89R\xda\xe59\x85\xd9\xeff\'\xa95\xdb\xe2\xdf\x1cw\x183\xb3\xc9\xebD\xdbfoZD\x95\x1f\x19l\xb4\x7f$\t\xf0\xb0\xfb\xf1f\xac\xef\x0c\n\xc8\x8e\xfb\xb5OLI*2#\xb4f\xb9;RrE\x17\x1d\x8a\x1c\xecy\xd6\xa2\x9c\xe8f\xe7-]<r\x87\xee\xf1\xf7\xebe\xd1\xfa\xfa*g+|\xc1v\xd8^\x03h\xf2\x08W\xdc\x05\x01HgH\xab\xcaJu+\'\xaf\x83\xad\xcfB5NYgzA\x0ck9\xc40\x10\xd77\xc6\x88\xaf\xac\x8cg\xd5\xb8K/\xec-\x0c\xacw\xdf\xd7\xb4v\xd4\xc4g\xf5:2\xcd\xd1\xfa8\xe8\xff\x1f\xack`\x0b\xdeh0\x9a\xa1\xc0\x92\xa4\xcc\xdd\x86\x88G"\x97\x93\x89h\x82\xd3SL\xfdm\x0b\xc3\x91\x01\xcew\xc6ath\x94\xb5\xb7\x86\xf3b\xb5\x9c(\x8a\xcb:\xdd\xe9\xf1i!\x98\x97\x00\xf7\x80e\xfdI\xca\xfb\x8f\xac\xc77iO\xfd=m\xcc/IJE\x84\xf0\xa9m\xdb\x15i{h\x1ff2\xa4\x18\xf1\x80\xd0\xa0\xc5\xc8b\xc8i}\xac\'\xcc2\x93\xce\xef=\xf9+h\xad\xf1\x9ei\x94\x02\x994\xda\xbb[\xfd\xa2\'\xa7\xc9N\x15\xa9i\x9bOB\xddv\x96\xcd$_Qu\xf8\xa1\x07\x86i\xc4\xed=\xed\x01\xa6\x9a\xa5\xb1\xfb\x9ax=\x98ei\xe3\xbfH.\r\xe0\xf3BV\xaePAE\x88 i\xef\x07\xdf\x8dp\xdbV6\x04o\x14/\x03I\x00i\xfb\xdd7\xff:/UaOm\x084a\x99\xa6j\x04.\x89(\xd6\xfc\xbe}=\xabR\xbdY\xa0\x85jm\xccpgd\xdf\xb4\x11U[\xe7\x98\xecp\x13jo6\xaf\xaf"h\xae\xe5\xbb1\xca\x04\x12[+j~\x82\xb6\x8br:W\xe7\xf1\xe76\xc7\xee\x96\xb4j\x87~.;F\x04\xc1\xff4\xcc\x17\x05\xbf\x98\x17j\xb4=y\x1cPo\x9a\xce\x96\x8eIO\x8d/\xf5j\xe2;\x9b\x99K\xd9\xb8R(\xfe\x0b\x165[\xe6j\xf8\x8e\x83YVp\xd21\xf2^\xb16V\xda\xb8k\x07\x11R\xafo\xcb\x18\'\xd0*;\x14u\x9b[k<R\x95\xcf\xa1\xf1;v\xd8\x15\x8a\xef\xc0N\xf0k>\x9c:\xd9{&\xacHi\x07\xa2\xad\x0c\xaf\x98kD}\xbf\x1f^v]\xeb\xcc\x96}r.*\xbfkS\xba;\x8b\xcf\xf0fn\x8e\xfd\xc5u\xc2\xc3\xf2kV\xe5\x0c~\x96.\x04\xfah"\xf7\xf5;\xf3\x81l\x1a\xe3"\xfa%\x1e(\xecV\x05\xa3\xad!f\x0bl\x1e\xbd~\xf0x\xe4\x89\xc1x\x06Bc\x86\xe5\xd3l?\xdb\xc3\xb2U\xa4\xdeb0\x99\xd1,>\x00PlAC\xa7v&`\x92\x8c\xef\x15\xd1\x7f\x0f\x17\xealY\x8dwA\xbb*!Q\x14\xffa\xbe\xee\x11gla\x93\xdfp\x87Jkzq\x00\xff\x8f\xe0\xd1"l\xb8\xcc+,\x86\xe9F[\'\x8f{\x98\x9e\xdc5l\xe5\xcde\x9a\xf4\x03j{\xa8\x90\xf9\xb9\xd4i\xaem\'\xa1+]\xaf\x01\xbb\xac\x86d\xb0y\xa2\x7f6mQL\x0f"tVdv1S\x11=\x1c\xe6@m\x9b\xa2\xeb*\x9d\x867\x15\x08 \x1fq\t\x07\x92m\xb1 Lbj,\xbf\x11\xd9\xceJ\x96YU\xd6m\xf2\x00\xe4\xc2\xf8\xaf\x15)\xeal\xd0q\xa6\xe1\xfen\x02\x8eG\xb7O\x13\x8c\xfb^\x80ku-T\xf9n\x17\xc5y\x92\x16\xe1I\xf2\xea\x8fz\xe8e\xe2\x91n\x1d2\x1c\x14s\x87C\xab\xaa\x9b\xec\x04\xf7\x93\x03n,\r\rq\x9d\xa2\xb9\'Fe\x15\x97\xca\r~n\x8d\x99\x17\xa8T\xf4\xc7O\xc6Z\x1f\xde\xe6$>n\xbf\x05`\x95\xa2A\x9cW\xdce\xb9\x939%\xdfo\x04\x98\xba,\x0b\xca7hli\xa7\xbb\x97\xc9Vo\x10j\xc9\xbcy\x01\x99\nZU\xed\xeaO\x01\x07o\x14\x18\x8a\x83k\xc5v\x90{4\\\x94\x84O\x99oq\xdc~\x08\xaa\xe3>\xa4N\xa0:\x18\xd12\'o\x93\xbe\xce^\r\xccV\xc8\xbf9,\x1c\x1f\x88Io\xaa$\xa4\'\x8a\x8a\xb0>9L!\xd9\xf4\x86\x80o\xb9\x90\x9d\x87\xf5\x84`\xeb-\xf0U\x1d\xbej{o\xcc\xcb\x898e\xb7Dto\x18@5S\x05\xaeo\xd8\x975\xb8\xd5\xed\x13\xef\xd4\x8e\xd2\x10"M\xa6p\x05\x07y\x0e C\x00\xe7gG\xc0\xfb\xd2whp\x06)y\xa7\xdegN\x12:\x96\xddW=\x91\xaep<\xed\x00\xab2\x13\xf9G\xf6\xefR\xe7 \xa0\x85p\x86_\xe2*\xde\xa1\\\xb5\x82\x971I\xec\x18\x98p\x87\x9a\xf9\x8eG\x12Y\xab\xcc\x91\x7f\xeb\xb0;6p\xad0\xbcO?\x1f7YqM\xbc(w\xf9\x83q\x0f\xf6xe\x18\xaa\x11\xf3F\x8dc\x08\xb1\x1fbqNX\xaf7\xd6\xf5\xbd\x8ec\xc1\xaa\\\xa5\xdflqi}\xa5\x83\xce,\xd5R?\x11\xb4AN*\x05q\xb3q\xd0\xc5Cd\xd1UN\xde\xa2\xe6k\xb1\xa9q\xbdr\xe2\xd9b\xae&\x9a\xfc\xacP\xdaS\x91\xbbq\xf0\xcf\xfa\x84X\x07\x9a}\xd0uh\x92\xa0\xcfGr\x13yhL%\x9eq\xf8\xf4\xa9a\xd1\x8dw\xedr\x14\xd3\x00\xdc\xae\x15a\x18T\x1cv\xc4\xcb\x8a\x03r!\x8f\x17\xf8\x03\xdd;\x03\xfc\x10:\x82\xc9\xe9Jr-\xca\x1b\xdd\xe8\xf2C\xfc\xbb\xe1\x00\xc1],\xb5rc@\x82\\\x9d\xe2\xee\xf86n[\xbe\x00#\xcdr\x84K\xbf\x80\xb9\xe71\xbe\xc9\xea\xec4\x9e4\xb7r\xb4\xf6Y^\xe7\x17U_\xa4\x1b\x06\xde\xbe8;r\xf2#fo\x7f\x982\xfd@T3\xb9\xaf{\xb6s\x11t|\xea\xfc\xbeO\x05\xe1Zr\xf0dd\xe2sQ>\xb0\xb8Y\xd1pS\xed>3\x8c\xdfE\xb9sl\xd8\xe3\xfb\xe0o\xadh\x89z\x18:%\xd8\xbcs\x90\xf1\xd2"d\x96\xa0N\xacQ\x1f\xc6 \xb0\x04s\xb5\x1d\x13wh\xa09\xbb\xb2\xf7\xff?"Jus\xe1\xd7\x02\x86\x96\x08\xcb\xeb\xe2\x1a\x80W\xca\x11\xe2to\'\xc2-_B\xb5\x8b\x9f\x9d\x99\xfc\xa9\x080t\x86n\x1dd\xb4+\xfb\x1e\xf6[\x17\xef\x114\xa6t\xda\xfdZ\x17/\xb1\x00/I)\x81\x117\xd2\xd0t\xdejl\\\xfan&\xa0\xc0^\xc8\xdet\x80\x1dt\xe0|#\x91\xc6J+27\x92\xbd\xdcb\xf1\xd3u\x0e\x1f\x96eJ\xecP);\xa2\xba\x92\x10\x88\xddu\x10\xbd\xd3\xe51\x0e\xc7eZ\xc4\x89]\xc3\x9b\tu\x1d\xf4\xe0!\x0bpr\xe3\x9a<\x88ek\xc4\xe6u1\xc8\x9d5\x8e\x8a:8W\xf9\x16_\x02a?uB\xfe\xabj\x06\xd4\xf0\x03\xaf\x08V\x1bK\xe9\xe7uV\x1b\xd0-Kc\xcf\xb5\x00\xcd\xda\xd8\xcc\x99\x9fu\x9f=\x87\xe6}\xa0Y]\x0c\x0bkMc\xcf\xa0u\xda`\xcd\xdd\xab\xda\xe1\xddU\x08%\xea=\xf7\xe3u\xf5,\x17\xd1\xab\xee[n\xb8z\x84`\xd2g\xf5vRD\x00ktLN\x1c\x89\xae\x03\xe3\xe6a/v\x9c\xf7\xc0\x80\xe0qW\xdcgQp0\xcb\x8f\x9cv\xb2\xbc\x90\x1f\x8c\xe7-\t\x91\tDK\x96\xe6\xadv\xff\x8d\x9c\xe9\xde\xe41q\x8c#\x84]\x98{\xd7w9\x10\xb4I\x96\xdd\xf8\xb9\xa1\xb8\xc1d\xd7j\xdcwI\xc2e}\xfc\x1eM\xa5\xac\xb1,k\x9e\xc3\x8cwg>\xd0\xaf\xb8S\xc6a_\xd7E)e\x96Bw\xdb\xaf\xcd}\x03\x05b\x8e\x06\x86<\x7f\xfa9)w\xf4\x1c\x12\x83\xda\x80x\xe9{\x91\x1c\xf9\x92.dxC\x18\xe6\xc3:\x96\xa2\xcd\x17\x80\x90\x7fp*3xQ\x14\x8f\x19b\xb8\xf1\x94\x12\xd7f[m\xbe\xb4xX\x063\x87%yM\xbb\x7f\xae4k\xf0\n\xd7xX\x8c.\xc8s\x0c\x82\xf5X\x9d\xe6\xf9f\xad\x03x\x81\xe2\x97\xdf>"+\r\xf2Q\x0f#\xc9\xc72x\x8c+\x96\x1b\xe6\xbf\xac\t\xc6\x95\x001\xc2\xfczx\x8d\x1c\x01\x9f\xbb\x9f\x08\xb1C\x1a\x8f\xd7\xc3E3x\xa8X\xa3;\xe5\xc9\xc1OVGs\xec\xb0(\x8ex\xc5\x9d<<r\xcf@\xb7T.\xd2\xa2!\x06\xaex\xd4\xfa\xa4H\x94\xe3#\x9b\xc0\xb5\xbd\x8ei:.y%N\xe3\xef\xc6\x88u\x17\x91A\xf40\xe9\xcdWy6\x08Bf\xdc\xc5\x9b\x0b\x15DR\xd5\x17\x87\xddy9N54\xb2n\xfb\x95\xaf\xfd}\xda\xe5\x1efy@*\x10\xd5&T\xf2\x06\x9c\x12Jr\xb7\x8dyyP\xfdDB\x05\xd4`\x12\x1d\x18\x1d\x8dK#+yX\xa3\xacj\xdfQ\xac\xf5\x81=\x89\x19\xf2!By[\xf1\xba\x82\xd1@\'\x99\x0fRh\x06\xae\xe5\xady\xa6\xd0\x9b\x99\x94\xafj\xe9\xbd\xbc\x93\xe5\x12\x1d+y\xe0R\xcd\x13Kf\xe1\xf0\xe1)7\xc0\xc5\x98\x82y\xfb\x949t\x12\\Sy\xc4;?\xf3R\xd4\x86z1\x83\x9f\xd3\x06U\xf1T\xa0=(\xf6\xc9\xc4\xa9z_\xbbT*}V\x01\xb6\xcb\x8e:\x8a\xad\xfdQz{\xbdz4.\xbb?`\x87?0\x9f0m\x04z\x85\x95/\x01W\x83\xae\xec\x98v\xa5^\x8codz\x89xcM,r\xcd\r\xd8l\xa4q\xa3Q\xaaz\xb9\xc5\xd9(\x1cq\x11\xec\xe5\xd8\\2}C@z\xbbe\x83\r\xf6l\xf4\x85.\x15`R(g\x05{\x18\x05\xe0\xcex\xf3\xf5"?\xfcj\xf65\xba\xfc{%\xa3\x07\x88T\xc0\xd0\x94\xd0\x1c\x15Q<b\r{\x84\x18;i\x8d\x90\xa6C\x05\xbe|\xaauu\xda{\x8ex\x02Y\xfc\xa4p\x82D\xce\xcc\n\xe0\x86\x0b{\x90\xa6\xb8\xb6}\x10\x8e\xb1\xf3ig\x9a\xa9\xbb\xe8{\x93\x86x\x8aJr\x02f\xe81or$\xbf\x04{\xb6X\xf5\re\x8c\xe2\xadE#\x1c\x11,\xf7D{\xc1*V\xe6X-\xc3\x13\x99\xa0\xb1i\xc1/\xc0{\xc2\x7f}\x848\xf3Y\x80VS\xb4ey\xbc\x1f|\x03\xb8Bl\xf4<\x9e\x07e\xb2:\xd5\xf7;\x08|/{\xff\x9f\xe4\n\xd0\x93\xd2e\x03\xb1\xbc\xee\xbd|A\xb5?h-\xb1\xf6\xb5\x80\x15\x9c\x0e\x0e\xa5\x18|Z$,\xc8\xfc\xce\x95\xdd\xce\x11_\r\xc11\xbc|\xcdh\xf1\xcd\xce$\xd4Do<\x83\x0c\\V"|\xdaN\xe1(\xaa\xb9\x80\x06\xb9L\x1c\x87\x98E\xd7}\x18\xcdzj\xac\xbb \x94\x17\xd7\x81\xb1]=\xd4}J\x0b\xf0\x19\xb8\x83Y\x9d=\x7fR\xfa\xfd\xef\xb2}Xg\xfc\x03\xf8\xf9\xfb\x07\x18`\x8c\x9f<\xf9\x9a}\x90y\xcd\x95\xe9n\xb1I_,\x8e\x7f#g\xea}\x98\x17*\x01x\x12\x1d\x14K\xc9\xb9\xcf\xbf\x10i}\x99\x1b61\x10\xc0\xe2!\xe5\r\xee\x87"\xeb\xc7}\xb3)d=\xc8\xf6\x05\xa9\xd6\xb1\xa5\x1a\n\x98j~\x04\x0f,6:\xda!\xf6`\x83\xf1\x86<\xd2\x94~)%g_\x13$a\x11-ev\x051\xa7\x06~e\xc3\x9a"\x9es\x88\'5\xf8\x0f\x14g6\t~s\x18#\x06\x82e\xb4\xee\xce\xbe\xe2m\x9f4\xd3~{\xba5\x88\xde\xa9\xb1A\xfa\xaa\xda\xf4\x91\xe2w~\xf6(\xc2\x88\x0c`\x1f\x01+\x05!\x92\xb1QP~\xfe8\x95\xa1\xe9_%\x8e\xd1\xaf\x9e(\x9b\xac\x1d\x7f\x028\x15\xe4\x01\x88\xbc<\xe2y\xb1\x9b]_\x8c\x7f\x0e\xff/\x9a\xc6\xa5\x9a\x1cM\x97\x7f\x0c\x7fy\xf2\x7f/\xd1`\x08\xf9\xe5\xe0\x97\xaf\xded\xab\xa0k\xb3\x7fO\x9dI\x8cC\\\xef\xe8\xc1\xa6\xb9\x80\x8d\xa2\xd6\x7fZ|\x00\x90\xf2\xc8\x84\x9c\x1a\xf7_\xf0Z;\x94\x7fbP\xa7bU\x10\xe0l\xf3\xda\x92\xb5A\xad\xdb\x7f\xad1\xae$.\x95\xb7|,?\x1aJ\xb9\x83\xa8\x7f\xcbh\xcf\x97\xa2\xa078\xad\xe9\xec\x19\x95\xa9\xe0\x80\x0ba\x8cDXL\xa1\xaeu\xed\xffT\x1b\xf8x\x80.I\x0e\xb4\xd0RzRK\xe2\xa2\x00\xf6 4\x80h\xd3\x9f\x93\x95\xdd\xd6\xdaU\xac\xb4zo\xceh\x80\x9d\xb1\x9e\x1a\x1b\xbbn\xc7x\xd8\x91\xbd-\x13\x0b\x80\x9d\xbd\xd2<be\xac_\xb60\xeb\xb2%\x92)\x80\xaf\x11\xa5B-\xf8h\xbcDW\x99\x8cKSC\x80\xb2*&\x8f\xc3>\x9e\x0eg\x80}\x80"W\x8f\x80\xe5\x8f\x82\x04\xe7\x8a\xcc\x07,\xc0\xf2HC\xcf\xd8\x80\xeb\x87\x9by\xe9\xfcal+t\xca\x12f~\x18\x80\xf6\x17\xb8\x8bcu\x9b\xf6g4\t\xc1\xf6\x17\xa9\x810*iwF\xe5R\x91\x15\xe2\xd3%2\r\xd7\x81JL8\xf4\x0e4\x04\xbf\xd5\xe1\xc5\x17\xa4+J\x81\x8d]a\xac\xc8\x02s*\xbc82\x04\xb4\xa9\xa7\x81\x96\xa8\xcf\xf7\x9a\x13\xb8\xd3\x81\xa2\xe8\xa52\x0e\xea\x81\xc1$\xa5\xf3,_\xc6-Q\xe2E:\xe4<z\x81\xc7\xbc\x7f\xc8#\x84\xfd]\xedMW\xf8H\xaf\x1c\x81\xd8\xb71\x01\xd7a4\x7f\xa1\x19\xd0\x8b\xce\x00\xff\x81\xecY\xdcH7\x9a\xc7\x89\xf0\x0b\x9bEM\xac<\x826O\xca"\xd8\xb9\x86\xa3\x1aV\x1d\x1fA\xa5\xcf\x82o\xce\x05\xc2!\xda\xd8\x02<\x94\xefJ\xf3\xf2\xd7\x82\x8f\x9a\xe0o\xfe\xec\x19.\xb9\x8br\xa5\x96\x0e\xe8\x83p\x1c]\x90\xeaX\xb9\x8a\xd1K?\x9d\xc2Q\x8f\x83\xa7SQ=v\xceA_v\xc4*\x13\xfbFQ\x83\xc6\x0b\x1f\xac\xee&-\xf2\xca\xf9ZM\xab\xbb\xc6\x83\xe7N@\xfe\xf7\x04\x02>\xd8r\xd1\xc6\x91\x84\xe5\x83\xea\xb5\xed\xc8\x18\xe1\xdcDn\xdb\xab\xd8h\xc7K\x84\x02\xb2\xc8\xffQ\xaa\xaf\x1a[g\x07\x1a\xf8\x9d\xf4\x84*h\xd8\xa2v~\xef\xb6\x04\xdb5\x01\x98(Q\x843\\[\xf3\xaa[,"*\x81\x1a\xa0j\x1a\xd3\x84<\x1e\xfb;S\x96\xe5\xff\xfe\x85Y\x7f\xc3[g\x84O(u\xd0\xeb\x00e\x94\'\xf1\xce{r\xe0\xca\x84P\x8c\xc1\xa4\x16j\x1a\xe2\xc2[\x92P\xb9\xa6\x08\x84SE\x1b\x8aji:U\xd7 \x8a\xf7g\x7f8\x84\x8fX<\x0b\x1a\xc9k\x07\xe0\xa2!(\x84\xd7`\x84\xa2O:\x1d#\x8b\xd1\xe1\xb0\xc4\xec\\\xc1\xb7\xe7\x84\xbc0\xb7\xdfd\xd3]\xd7\xf4\xfd\x9c\x02\xc6\xf2t\x84\xe6hK\xf9\xf4$\xe4\xb5\x9f&{$\x184k\x84\xf2f\x92o@\xdb\xfe\xd3U\xf2(lT\xd3_\x84\xfd\x9e\xa6\xc1\xa1\x9d\x9d\xb8k\xf3\x89\x15\x11O\x13\x84\xff\xdf\x1d\xd5\xad\\\x0c\xc6\x8d\xeb\x13\x86\x94\xb1\xf5\x850\xe8P\xf6<>@\x1f\x04\xbe\xedf\xa4\x9bb\x85[e \xe4\xa2C,\xb6\x88\x13\xf9\x8a\x02\x06\xde\x85oO&\xad2\xd2R\xf5\x831\x90\xe8\xf9\x06U\x85\x82\xfe\x1a\xf4\xdd\x8bGh=\x8c-\xc2\x9e6x\x85\xad.\xb7\xdd\x805F\xa6r\xb1\xeb\xbf\xc0\x90+\x85\xc8<\xb5Q>9jsP\xffHW\xa6D\x84\x85\xd0\xfei\xd0O\x9aGg\xd7\xcf!\xe2`Iz\x85\xd4%\x1b\x95\x91\x8eqM\xae\xbc\x19\x91\xa8O\x8d\x85\xf8Ph\xbd\xa1\xbe\x19\xbc\x9f\x8c)X\x0c*\xcd\x85\xfe\xd2\xfb>\xef\xbb\xcf\x8f\xe7H\xa2\xf9l\x0e\x93\x86&\xa1u\x92!\xcf\x13p}\xc1\r\x17\xe5\x8c\x8a\x86L0\xfa\xb2q\xae\xe5\x93\xe9\xdf\xa5\n\x88\x98\xec\x86[;Ka7\xf5\xb5\x1dm\xc5wj\xb4\x14\x97\x86c\xd3\xd5{\x18G\rT\xa8\xf9W\xb6\xd2\x8c[\x86g\xa5\xbe\x14\x867 \x03!;\xff\xb5\xf3\r\xc4\x86\x85m\x9d\\G\x95\x03`ma>:z\xe8\xca\x86\x8d,\xa2>\x96\x04My\xf7\xed\x02\xec\x00\xb8^\x86\xcc\xc0\xc4(\xf3\x18?\x8b~#\x8b\xaa\xde/]\x86\xf9\xe6\xfc\xf4\xee\xe0\xac\xf78\xa1.\xfbp\xd0\xaf\x87=\xc5w\xc9v\xc3\xcf\xadmA\xa3d\x85\xd5\x7f\x87t\x1d\xfe\xe4\x8aW\xb6\x8b\xe0\x90$\x1a\xfbx\xa7\x87\x86\x8d\x13\x1f\xcaa3{\x9a\x82\xc9\x1aD\x1f+\x87\x86\xb5:\xfb\xe5\tX\xef\x8a\xec\x83\xd70\xac`\x87\x95n\xaa(8\x08\x90\xe7\xda\xd8\xfc\x84\xa4\xa9\xc8\x87\xa1J5\xba\xe1\r\xaf\xedF\xfd\x8a\xc0\xe6\x89,\x87\xbe&s\xd2K\xc6\x80\x8ci\xfa%?F`%\x87\xdd\x03\xb6\x05\xd7\xbbGi\xeb\xa5\x82&\xbb\xea\xbf\x880\xc8\xba\xd9)!\x10\xa6\xcd\n\x9a\x83\x80\xa7\xc1\x88C\xed\x99\xcb,\xb1\xae\xfc\xbfO\xb6\xb7\x8b\x9f?\x88GK\xf6\xb7\xc1R\x92\xb5yTfu1\xd4\xf6\x88Qz\x02\x8d!\x82\x95\xb5\xc6\xb1\x90\x10#W\x93\x88\xa2\x0461\x0f\xcf\x00\xe0\xc6\xb0_\xec\x07?\xd1\x88\xdb\xb3\x0b\xd0\x90\xb2\xe9\x17\x0fG\xc9v\x8b\x9d~\x88\xe2\xb1\xccL\xbe\xcf\x17\x05W\xc0q7\x18\xa4\x8a\x88\xe2\xe7\xebV"\x0bnx\xb4\xd5\x1c\xd2D\xc6+\x89"\x9eEEJ\x9d{\x10\x10\xef+v\xfa\x81h\x89+;5\xfbh\xfe}\x9b\x861\xec\xc2\xaetK\x89A\x8c\xd5\xf6=\xec?\xe6\xe4H\xc0\xb8\xa1\xf1|\x89q\xb0\r\x1bc\x9c\xb2\x1a\xb0\xc4\x17\n\xd1rt\x89\x8c[:\x0b\xb7}\xf6\xf5\x83_\xc80Q\xe7$\x89\x8c\x8c\xcf\xaf\x9d\xa3qN\xdd\xcc\x00S\x8cj\x17\x89\x90\xce\xa5\xf8\xda\x81\xbd\x8a\xafy\xd9{\xb8\xab\x97\x89\xc58P\xe6\x9f\x9d\x17\xc2\x10`\xf6:\xa0x{\x89\xdf\xafO\x1dc\x86\xc9=gf\xd6\xaf\x93\x93\xbb\x8a\n\xf5E\x0e\xc8\x92\xe1\xe3\xceL\x1c\xab\x08\xb2I\x8a(<s\x9a\xf0\xa1>\xb2*@\xd7\xf8\xe3\x17\xa1\x8aWXdx\x9a\xe5\x1e.y\x98\xd7\x963D=\x8aZ\xe4d\x89rG\xe2V\xc1\x8b\x85\xef\xf2\x04\x1a\x8a\x94 \x0c\n\x16*\xcb\xe8\xb1)\x065 $\xe1\x8a\xa3*\xe1\x97\xd3\x02\x7f\xe0w5\xe4p\x17\x13>\x8a\xfc\x8dj\xd4\xb1\x95\xfe\x1e\xa4\xc5W\xac\xaa\x90\xd7\x8b)t\x03\xe6\x0f\xcf\xd2<\xa2\xbd/G\x84\xdd\xc7\x8b/p,\x9b;Q\xc4x\xe8\xba\x05\x85\xbf\x1b\xbc\x8bQ\x96mbZ\xe8\xdc\xc4\xa2\x80\xc3\xbe\xa42\xf4\x8bX\x18u[e\xc9\xa9\xf2\x18\x15e\x98\xbd\xf2\xf6\x8btwTz\xf1\xd9\x99\x8b\x0e\x1d\xb8\xa9~>\xe4\x8b\x81\xc1\xc8\x11\xda\xb5G\xb3\xff{\xa1\xfdbd\xaa\x8b\xae\xe8\x9cn\xee\xd3y\xa7g\xd9\x16\xe0\xd3\xfb\xcd\x8b\xb1\xf3l\xb8\x06w\x8b\xbd\x00Lf\x01\x86\xfd\xf2\x8b\xe5\xee\x95\xd7!F\xad\xd5\xf0\x17\xa1(q\x81r\x8c&!\x0bo\x0b\xc6\xf4\x92\x1e\x99\xa9\xc4\'\xa3\xd5\x8cPoH\xcc\xd4\xbd\xe3\xfb\xe7\x86>\xb7\x803I\x8ce1\x1c\x18\x95\x9a\xbcn\xedP\xadHa\xb1\xa4\x8cfM\xf9(\xec\xf4B\xb6\xe2\xaa\n\xe2\xc5\xb0\xf9\x8c\x82\xba\xccqQ\xce\xc5\xc2\x01\x1d\xc0\x9a\x053\n\x8c\x8d\xa6\xcb\x91nM\x07N\xb7y\x0e\xe3\xe6\xa0F\x8c\xc0\x00Z\xde)0\x96\xd6v\x83\x05\x05\xa2\xaar\x8c\xee\x98\x12u\xeej\xca\xcf&T\x80\xac\x98\xaf]\x8c\xf9Y\xf9_\xe1\x95e\xd1\xda&\x1e(3\x86=\x8c\xfc\xa2p2\xd6Ny\x9c\x85jX\xccJ\xeb\x01\x8dS\xa1\xcd\xaaE\x8b\xb6z\xeb\x07A\x99\xbb\xa9\xd3\x8dYl\xd1\x83\xad\xbcE\x1d\x86oK\xf2\xe0\x0e\x07\x8dnY\xbb\xec\xe6\xe0\xe1+\xc9\xcb7\xad\x8a\xd8\xcc\x8d\x8b\x990b\xe3{\xdc/\x8dV\xd2Z]\xbc\xb8\x8d\xb7\x80 9j\x97\x9b)uV\x1d\x18\xf0\xaa\xbd\x8d\xf3\xcb\xeb!"\xd0\x9c\r\xae\xdam\x974 w\x8d\xfb\xce\x83\xcd\xe3\xef\xccq\x14f\xa7`$\n\x1b\x8e:=S\xe1E\t]I*z\xfb\x9e\xeb\x885\x8eG\xd9*\x90\x89\x19\x05\xa4y3\xd4\xf3\x01\x84\xfc\x8ec\xb8\xf5\x8a\x1c\x1d\x8a\xc7\x9a*2&\x9fm\xf1\x8e\x9a5{*\x1d@\xcf-\x94\x9b\xa3Wf\xae\xb3\x8e\xdb\xc5\xc40\xbc^=fuD\xb5\xd4\xf1\xfa{\x8e\xe0@\x9c\x81\xfeW\xf0jG!t9\x1c\xc2\x02\x8f3/\xee\xfc)l\xe1\xdf\xd8\xd3\xe8\x9au\\\x02\x8f;WXBLy\x8d\x82\x06\xd8\xe7Q_\xa4{\x8f\xa1\xb6\xd1\xeb\x81\xb7q\x9a\x8a\x00\xc8\x19*aI\x8f\xcf\xb2{\x9c\x13\xf8\xabe.d\x16\x99r\x86P\x8f\xe6\xec~Tn\xdc\x91\x85\x7f(\xd7J[\x9d\xdc\x90\x04\x84+q\xf6J\x98\x17L\xbc\x18)7s)\x90\x13\xff_\xe2\xb4\x924\x03\xd4\xfd\x96[\xc9q\x15\x90FD;\x08\xa6j\xe8(\x82\n\xfd.2 /\x90c\xeb6\xcc|\xb3y\xda\xdd\x84AP4\xaf+\x90\xba\xc8m\xa8\x8b\x89\x1b<1\xa3P\xb5\xc3\xcaS\x90\xdf~\x91\x89\xb8:B\xbf\x0c\x1a\xa6\x7f\x92JD\x90\xeeX\x83{\x95+\xc8\x9b\x19\x8f~\x13\xf0\xb7\xb7\x91\x12sf\xfd\x9b\x07\xd6\xb4\x996\x13\xf2#\x98\xc4\x91\x16\x97\x82L~\xb2TO\xf8\xf7\xf8\xc2\x03\x80X\x91;\xb9\xabz\xd7\xe8\x94\xd2<\xa1\xcfFP\xb1\xd8\x91\\\x99\x92\xf0\xd68\xa8\x0b\x96#\xbb\xa5/\xa0\xa8\x91\xf1\xeb\x8f\x9d\x14\x94\xd5\xc6\xb4r\xc7\x04K\xddz\x92\x18+\xbcQJ\x0b\r0\xfe\xd1\x8e\xa0%\x8b=\x92\x1b)\xcd\xc1\xd3%\\\xbb\x05+\xfa\x1fo~V\x929\xe4\x94(\x10\\\xcc\x9a\x1e\x86\xb4i)\x05\xd0\x92@m@\xea\x1c\x8f\xbc\x04\x97\x1eU\xd6\xfa\x90K\x92Gkr\xb0o\xbcz\x0e\xf8\x00M\xe7\x94\x95>\x93T\x07\xf1\x1e\x19\x03\x12z\xa3\x1ek\xd8\xbaI\xc0\x93j\x1fGC\xb7\x1c\x8d\x93\xba\xfd\x9e\x1dNc\xab\x93~\r\xe8o\x7f2\xce!f\xf3\xd8s\x03|\xd0\x93\x837\xb0|v\x8eLe:7\xcf\x0f\xdc\x07\xb8\x93\x94\xa3^`\x8f\xa6\r!A\xcc\x99fK_\xfe\x93\x97\xa8\x9e\x1c\x89\x8f1\xd9\xff/#\x91\xf4\xad\x02\x93\xb9\xbaS\xc7\xf3\xf9l\xd1\x7f\xc0;\xe3\x8dw\xbd\x94F zUZM\x05I\xc44\xbe\x0c\xf6\xe6O\x94ef\xc8\x1a\xe4\xc4\xd9\xab>\xcb\x7f\xe1!w\xea\x94r\xb8\xd6\xdb\xf5v9I\xe1\xb3\t\xe5\xdb\x15W\x94\xb0%\x8ekG\x18>\x838\x9f\xe1#\x94\'#\x94\xfb.\x1a\xc7\xc8\x89:v]\x06u\x9e\xb5\x8e\xb5\x95&\xa9\xee\xed\xfe\xff\x1e\x8fW\xec\x03\x081\xeb\xe1\x957\xec0\x10<\xcd^<|NW4M\xb6J\x95C\xf6a\x88\xd9\xe6\x83Y\xe81\xdc\x9f\x9cN\'\x95\x89\x9d\xb2\xf6jdj\xf7\x00\x94\x05\x95\x8f\x12\xbc\x95\x8a\xe0?\xdd\x1a%\xbc\xe62\xafS\'_8q\x95\xbfC\x90H\xaf\x04-\x83%J5\x8c\x1d\xc5I\x95\xd1\xa7\x19\xc3\xf8\x10s\x85\xfc$t+\xad\x11e\x95\xed\x0b\x1b\xcf\xb3w\x109\xb3\xb3VQ\xa0pY\x95\xf6\xdd2\xa3]\xf6\x8f\x9e\xfd-g\xf2\x07\x87\xda\x96\n\x7f9D\x84\x04=\xfb+\x93\xeb\xf0\x8f\xf2\xc1\x96\x17\xfe\x80\xf4\x1c\xc8\x03\xfeG\xd2X\x7f\xbf\xd2\xa7\x96.\x84\xe9\xd7\xdb\xc3\x92\x141\x95\x84\xa8pjx\x96m\xc8o\xd28\xe0\xfb\x02\xb5\x02\n\x04\x0f\xb2\x06\x96\x8c]\xd5,ren\xacF\xaf3\x88\xd5\xc7J\x96\xd4\xaa\xd7\xc1\xd5\xc3(\xca\xca\x06\x06\x9a\x8a\x02\x05\x96\xf0\x1c\x08d\xfa\x8bD\xb80\xa3\xf6R\x0e\x1f\xeb\x96\xf0~!A\xb5Y\x84?\xe0\x00P:\xc3uJ\x96\xf8}\x14\xc5\x00\nT\x97b\xf1v\xbb\x1bm(\x97G\\\xab\x0bw\xe0|VoR\x99\xe1\xb6\xfd\xc0\x97TC\xef\xd1\xe7\n\xfb\xc8\xb7k\xeb\xd7\x1b\xf7\x18\x97|\xac\xfbmt\xd6k\xe5D\xf6~]u,\xa9\x97\x93\x96\x96\xc8\xf9k\x83\x80\xa3\x91\xca\xd5\xd2\x03\x1c\x97\xa2\x084\x9cG\xeb0\xe3\xe7\xd1\xb6\x1d\xb1V\x96\x97\xda\xb1^\xce@\x08\xa6\x9d\xc2\xef\xc8\xd8\xf0\xc5\xa9\x98\x1a\xcc\x0f"\x13t}\x0b\x9b\x1f\x1b\x97t\x88\x01\x98G\x9c*\xb3.\xdd&\nijs\x949\x0f\xe2\x98c\xdc\xa2\xdd\x13}\xf4\xafR-\x0b\xd0[i"\x98n\xc7\xb5\x1b~K\xcd\x00\xea\x1d\x8c\x07\xe6\xfd\xc4\x98y\xf2\x90g\x0b\xf6E\x08\x1a-\xcb\xbb\xbf\x19\xca\x98\xa4\xef\x90\x99;\x96\xb7\x0b\x04\xcbU@m\xd1q\x98\xd1D\x92\xbe\x94o\xb1?\xf6k\xf4\xef\xf3\xbd\x7f\x98\xd7\x17.\xd7;V\xeb\xb1@\xf8\x9b\x05\xfd^\x8b\x99\x0f0\xeeb\xe0p\x83\xac\xf1E\xf0\xa7\xb0\xf8\x81\x99\x0f\xed_R\x05\x1ah\x81\x0f\xab\xdecTP(\x99\x10\x87\xd7\xdc\xd2<\x19c\x97x`&\xa9\x93\xbe\x99KX"\xdf(\xda\xba\x9a!M\xca\xc2z;\xc9\x99k\xd3~t\x1c\x1bq\xb2\xe8\x9d\x95\xb2\xb3\x16}\x99vJ\x1c\xe9m\xf6\r\x10R\xd3\'\x04\x8a5\x88\x99\xf5j\x80\xde\x1d\xb1\xe1\xea\xbc:\xafE"\x0c\x14\x99\xfb\x9d;\x02&e\xb9\xc1\xa9\xe7\xaa\xacH\x89\xfd\x9a<\xb90\xdb\xc7\x16l>^\xc3H\x9d/\x92|\x9aY\x7f\xf6 aU\x81;\x94\xde\x13x\x1c\x120\x9a`\x85\xf6\xa2\xc9\xb9\x94\x9b\x82\xd7\xda\x9d\xbb\x1a\xf0\x9ale\x05\x86\xa7G\xbc\x0b\xb6\x05\x86M\xbd\xd4\x11\x9a\x9f\xbb\x8do\x1f\x08\xf9&0\x15\xe7Y8r\x0e\x9a\xa9\xd4Yji[\xa6JR\xf1G\xc2i\x87\x99\x9a\xaf\xb9ns\xe2\xec\'\xe9p"\xba\xe5\x1a\n\x93\x9a\xd0\xd2!\xa3\xa0\xa0H\x06\xa1do\xda\x84R;\x9bA\x92\xd9\\\x9a\x94\xf6\xd3\xbb\x84WzT\xbc\x11\x9bD\xec\xc2\xe8G!\xa7D~\x98.|\x83\xa8\xc6\x9bPwR@\x0bB\xb65\xab\xc4x7Mf\x90\x9b\xa3\xf7)h\xd6\xf5[i\xf3j\xfc\xca\x12\xaa,\x9b\xb4\xe2\xc1\xb6%3M\xe9\xbfr4>\xcb,K\x9b\xe6#\xe3s\x03\xd5\x941\x82\x9a\x98@\xf3\xfa\xf5\x9c\x00<\x8c~wkY\xa0\xc0\xa9V\xd9\xdd\x1c\xe6\x9c\x08\x9e\xed\xee\xc9\xff\xfeLx\xf4\xce\xbc\x17E\x15\x9c;?\x86Od=\x04j\\\xc1\xf6\xe9\x18\x15z\x9cTTN3\xb8V8\xe5C\xd6\xc7\xf2\x84\xfeE\x9c\xb9\x9c\xedA\xbd\xa4\x11x\xe6\rU@\xe1m\xc1\x9c\xd3\x13\xbe\x94\xa0*\xbf\x82P\xdcK\rP\xc7\xe2\x9c\xd6\xb8\xad\x02\xb2\xa1\x9d\x90\x9c[F\x0fl\xc9\x92\x9c\xe1{<vm\xcem\'\xec\x82\'\xb0$ \xdd\x9c\xe9|\xaa)\xc3z\xab|\xc9\xa1C\x9e\x826V\x9d\x0f\xb4\xee\xde\xd5\x8e\x848n\xde\x0c\x92\xf1I\x8a\x9d/\xb1\x98D\xce\x9f\x0eCG\x9dl\x8de\xe8\xdc\x9dVJ\xc1\xc2\xa8\n\x15\xaa%\xc9F\xd6\xbb\xf7\xc8\x9d\x94\x01\xe1P:]?\xc8\xbdYNH#\xb0m\x9d\xa6.\x8b\xf4\x1c\xe5\x1f%@\xbe\xdeQ\xff\xc2\x9f\x9d\xa7\x13\xdc#\x1fU+\x87\x89\xe0t\x81\xda*\x85\x9d\xbb\r\xe0\x0e\xc5?]C\xac\xbc\xb9\xf0m8)\x9d\xbf\x92\xbf\x8c\x9b$^\xcfQ\x1d\xb4R))b\x9d\xd9\xcc<a\xe3Z\xe8\xb9:\x95\xab\x91\'c\x89\x9d\xfe\xc5\x9d\xa9\x07I"\xac\xbf\xf7\x1e\x00\xf9Al\x9e\x1fZ-:\x8b\xc9\x99\xfa<\xe20\x86\x06\x1c\x9a\x9e)\xee\xe1.\xa3\x9a\xe2KS3\\U\xc6\x905\x9e3qsL\xc7\x90\n\xce\xb1\xea\x19\xa2\xb60\x1e\x9e7\xa5Y\xf3\x93\xa0X`\x8c\xb7\x88\x89\x11\x9dU\x9eZ\x06\xcd\xa5>\x17\xbb\xcez\x1f\xbd1\x8f\x1c3\x9euh\x11!\x16<1b\xb4\xc1\x99\x18\x03\xa4\xed\x9e\x8d\xa6\x0b\t\xd3<^\xc0\x7f\x908\xff\xa6\x9e\x92\x9e\xa4b7\xad \r\xfdSOa\xac8HMQ\x9e\xach\x1bk\x84\xae\x84]\\\x8f\xae\xdbA\x02\x95\x9e\xce\xbe\xd5\t \xc2<4E\xcf1\xc2\xed\xd5\x89\x9e\xdb\x02\x84\xc8Z#$5\xdd\xd46\xf8\xdc>\xe4\x9e\xfd\x87\x91\x02l\x99\x12u\x11[\xba\x13a\xa7[\x9f\x0ctifl\x8c<\xc5\xea\xaa\x15\xe7\xeaj\x9e\x9f&jL\xaf\xe3\xd3q\xe5\x111\x80GU1\xbf\x9f8\x7f$\\]\r\xb8S8\xbdb\x02O\xf6\x7f\x9f\xb6m~c\x0c\xa1\x84\x9fq\x8bVZgZ2\x9f\xbe\x98\xad\xe2\xf6\xe9/\xf6\xf2\x07\xd0:\xf3\xb2B\xa0\x17\xb9\x98L\xd3+\x08\x95F\xba\x93\xef~\xe5\x18\xa0\x17\xd1D\x93\x1c\xf1\xb89r\xe5\'\xd0^F\xfa\xa0=\\\xcd\xcf\xd1\x7f\x05a\xdd\xf9^IC\xef\x8a\xa0A\xa6\tT\xd3\x8b(Y9\x97E_2\x88\xa4\xa0Q{\x16\xf0cm\xea(\xb11 \x9c\xbb\x87\xf7\xa0c\x84\x88_p\x8d\x1a#\xd1kV\xfdV\xe2\xda\xa0{\xf5 k\x12d\xe7U\xc3\xe6;\x8c\xc8*\xbf\xa0\x93^\xc4\x1cI}=\x0c\x16\x1d>\xcc\x1c\x15\x0b\xa0\xae\xc3\x97=\xd5\x1b\x0c\xeb\xe3\xca\x01\x04\xed\xa5X\xa0\xbb\x9f\xfa\xba\xda\xb4\xe2i\xefz\x99p\xca\xdf\x96\xa0\xcc\x9d#\xbe\xd2`\\\xa2\x14\x94\x84cCK\xb8\xa0\xe3YD\x91\x93\x8e\xd3\xf7\x0c\xe6\xb3nU\xa82\xa0\xf8I\xae\x8cIU\xdepH\xd0\xcc\xd4\xe5\x8eF\xa16W\x80a\x84\xc3\x17*\x07W\x13\x0e\xdf\x13\xe7\xa1N\x99\xda\xc0K\xe4_\xea\x1bw\x9a\x9fVz\xa0\xa1e2Os\x19\xd6\xcf:a\xbc\xc7\x91\xae 4\xa1\xab\x1f,Z\x1c\xc1\x02b\xa9/6\xbc\xc4&\xfd\xa1\xae>\xc0\xbe\\\xa0\x12\xea:\x9f\xda\x98$\x9b\xe5\xa1\xaf!\x15\xa4_\x8dYO\xdc\xef\xceQ\x88~\x9c\xa1\xb35\xca\x9f\x18P\xb3P\xd32X\xb2\x965\x93\xa1\xde$\xcb\xea(.\xe2\xb0\x88}\xbd\xf2\xf7\xcc\xd3\xa27Zc\xcd"){;\xaa\xbeB\xa1\n\xc7M\xa2\x94Di\xcb\xdd+\xd1+-\x98\x18\xe2\xf9\xfd\xab\xa2\xa0\xe0w\x0e\xa0\xdez\x80\x01v\xe6\xb6\xa6\x052\xa2\xa2\xed\x0e\xcb;\x05X\x8c\x81c\xa36\xac\xef\x0b\xa2\xe1\x87\x11\xab\xedo!i\xb2\xd2\xc8\xf8\xfc\x9b=\xa3X\xbal\x9e|\x98\x18\x1eoYu7b=\xc4\xa3Y\xf32g]H\xb9X\xda\xcf\x82\xdf\x9b\xd6%\xa3\xbd:K\xeflmB\xb4\x120<\xa7Q\xce\xf3\xa3\xde\xa2c\x12N\xba8\x9db\xa5\xdb\x91\xf5J4\xa4&S\xda!\nT\xb6\x87O7\xf0\xd4\xa1-\xa5\xa44\xf5\xb6\xd7;\x99\x84\x96\x03U\x82\x18N\xaf\xf6\xa4\x91\xce\x8cx\x8fh\xff\xaa!r\xa2\xbd\x85\x9bf\xa4\xbc\xd9Eh\xaf\xfb\xbe\xf7\x07\xceO\x8e\xf5\xf7z\xa5q;\xe4\x00\xc1<\xb4\xf1;\xbc\xdb\x0c\x05\x93\xd2\xa5u\\\xa7\x14\xc1\xb9\xe3\x9dXJ#^\xb8\xd8k\xa5\x8d\xff\xfeR\x13\x9f92\x06;\xd9\xf1\xbb\xb8M\xa5\xb1\x9f({s)\x15\xbc\x96\xcdv\xdc\x87\xf5\xa8\xa5\xbd\x1f\xf3\xc9-\x1a\x9em\xdd\xcdON\xe8\n\xc6\xa5\xf2\x98\t\\\x88\x04\xe4\x8e\xb6bJ\xbe<\xad\xa5\xa5\xf3y\x8d\xc5\x98C\x04\'\x04\xb2-\xd5\xfd\x83\x96\xa6\x11.\x05tV\xa4\xd5F\x912F\xe8P\x91\x8e\xa6\x13{\xc7\x85~\xcf\xa6\xb6\x11\xc3\xca\xe8v6\xfa\xa6 \xba\xac\x99\x0c\xd9\xf1u8D\x85\xa7P0\xf9\xa6^>\xe7\xbaa\xb7\xb0\x14\ti\x06|\x08\xe7\xc8\xa6\xad\xdf)\xff\xb9\xd4\xcf\xd0\x98\xe23\xf1\xb6\xd6\xbf\xa6\xb4\xb3\xb6/\x97Bzs\x13\x81R\xaf6\xfa\xb4\xa6\xbd\x88\x17fy\xa0\x81<O\x8c\xbc\x18\xb58\xd8\xa6\xef\xbbB\xe1\x88S\x1c\x99\xee\x98\xdaTp\x99z\xa7"\xa4\xb0\xc7G\x89\xb8\x1a\xd8D\x9f\xe9\x8c\x8ff\xa7F\x92\x1d\xdd\xd9\x0f\x1f\xd3Z\x88\xf0J4\xc5\xb5\xa7hA\xdf\xf5\x95\xe4\x04d;\xfe\xa2j\xf6F+\xa7\x99G]H{\xbe\x05\xf3\xf3\x84\xd49oSg\xa7\xac:\xf4\xdaD\xc7\x86uY\xc5\xd5\xd9@\xa2\xea\xa7\xb8V\xd3\xd3\xd2\xf0J^\xca&\xcc\x93\xafT\x8d\xa7\xc2\x19\x9b\xda\x96\\\xb5\x1cm0\xba\xc2\xf4\xde4\xa7\xe4^\xd1K\xb9\x12\xee\xf5\xea!\xce\xd8\xad@T\xa7\xf6\x15fB\x81\xc3PMt\x19}T\x94\xfe\x06\xa8\x12G\x9c\x99\xa8\xa9\xa7\xe9\x9d\xcf\xd1]|\x82\x11\xa8\x1e\xe0Y#QE\xc8H\x99\xb1\xf8\xf1h|\xd3\xa8\x99\x81\xf8\x83\x1d\x92<|\xa3\xe1\xa3mr\x1d\x99\xa8\xad\xc6\xccl\x81\x9c\x10\xc83\xca\x07F\x1b\xe3#\xa8\xd0\x9cpW\xa2\x12\xa5Y\xe6\x81\xf0y_R!\xa8\xdf\x91\x93gw\xdd%%\x8bU\r\xc2*#\x0f\xa8\xf5\xe0\x90h\xb3\xb8\xbd\xed\xf7\xf6\xaaX\x87u \xa9\x06\x05\xf7\xd9\xad\xbd\x89\x0ct\xfc\xceJR9\x01\xa9\x15a\x81\xe9\xe7\xea\xd5aC\x87"\x1c\x03y\x10\xa9N\n\xb3\xdd9\x9a,\xfa\xe6{\xe4\xb7\xc0\xad\xe9\xa9\x85n \x19\xf4\xd90y\xf3\x18+b\xc8\xec\xe7\xa9\x88\x80\xc8\x9d\x10\'\x8b6\x90\x08\t\xa1\xd8]n\xa9\xe7L\xf5$\xda\xca-`,\xc8|\xcb\xd9L\x0b\xa9\xfb\xf0am\xa0e\xb8\x0f.D\xc9L\xc6\xf3\xaa\xaa\x00IK\xe59\xa3\x11W\xf7\xc74\xf1\xb3^\xa2\xaa\r\x9d\xe6\x8a\xc1_&\x1e\xed\x96E\x95J\x01\xb2\xaa\x1f!\xa0T\xffq<w\xdbT\xe5\x08q\x90\xa8\xaa:\xe5Y@;\x80\x10\xa9\x90Q\xacSf\xea\x92\xaaC\x17V5<\x15r\x1d\x8aYe\xed\x1a\xe8;\xaaL_\xeb\xf5\x96\xbe\xb6\x1aVW\x98<i\x81m\xaaT\xc6@O\xb5E\xd7\x1a\xf9l\x1e\xb2{\x10\x8d\xaay\xdb\xbe\x0e\xe2\xe0;\xacB\xa1\x8e\xfc=v5\xaa\x85\xf5at\x9a\x11\x8de\x14\x1d&\xf8dQ\x92\xaa\x9fx\xd3\xc3AM(\xeeQw\xa6\xf3\x16 \xe5\xaa\xbd\xca\x9e\xd0\x87\xd9\xb6\xc2\xaa\xf1w\x89\xc5\xd3\xcf\xaa\xd2-\x10\x99R\xc3f\xe9\xba\rR\xba\x9b\xdb\x86\xaa\xdeJ\xe3\xf9\xda\xe0\x80>vGK/\xb2\xd8\x13\xaa\xfbi{4\x93\xfdC\\\x84\x1f\xbc\xdf\x92O\xee\xab\x00oIp\x110\xcb\xc9\xfa\x947\xf2\x9f:F\xab*\t\x9d\x93Z|\'\r\xfb\x1c"\x80\x88\xb7\x81\xab>\x16\xef\xea\xcev\n\x1eO3\xeb\xf4\x0f\xa1\xb8\xabB\x90bd$\xacq\xb5\x946B\xac\x82WT\xab\x85\x8fQ\xc1ov\xee9\'\xd3\x01\xa7Q\xd0\xe1\xab\x8a6IEz\xab0\x13`\x9fK-Ls}\xab\x99t\xac<qo\x05\xdd\xc1\x1d\xdc\x1aI\xd3$\xab\xb8y\x02;\x0e\xa3a\x90\xde\xa9\xf8P[\x15i\xac\x10\x95\x91\t:v1M\x81\xbf\xf1L\x1c\x16\xc6\xac>\xd7\xe0\xdaS\xd7Q.\xc1\x9a\xb7\xe1\x97\xfcN\xac@YX~n\xb9\xa8\x98X\xdf\x85Dv\xf6\xcd\xac\x85Pc\x17\xa4\xeeZC\x19W\xe4{]\xb8\xbf\xac\xb9\xfbY#98\xe1\xc4\x19\xdc\x83\xb4\xf9\xfb\xed\xac\xcc\x82\xe7\xcb\xac\x0f\xc3\xfe]3\x8d\xb8N\x86P\xac\xe6\x1e4\xac\xafH\x16\xa8\x060\x91\x03\r\x9a\xee\xadm\xa5V7b\x83\x8e4\xeb\xe7\x10\xa6\xfc\xca\x0f\xadq,y`\xe7\xa8\xa8u\xcf\x06\xf5\x8c[W\xc5\xad\x84\x0b\x81\x17\x05\xe4nTc\xfb\x95?j\x81!\xad\x8e\xf7\xe1\x81\xc1\x7f\x16e|\xf3\xa4\x11\x9b6\xac\xad\xa9\xe1L\xf9\xf9|\xdb\xa9D\x11\x8e\xad\\\xb4\x02\xad\xca\xae\xd8\xdc\xfdR\xb50,\x92\xe6\xc7\xbe\x1d4\xae>\xf9\xc9)J1\xcf\x17%SK\xf4\xa3|\xa0\xaeD\x05\'\xe0u\xec\xbc\xcd\xbc]\xa9\x18\xd9\x0b3\xaej_\xbd\xab\xcdC\xffG\xcad\xff>\xa7v\xbb\xae\x83\xe3\xfd\xaef;-H@\xc5.\xe1U\x8d\xdf\xae\xa6\x19z\x8d\xb7\x1cv\xe5\x110\xe7b\xf8\xbdr\xae\xb2{R\x8e\t\xc9\xd3\x839\xe5\xf2\xf7\xf7?n\xae\xdeV\nq\xf8\xc1]\xa8\x9e\xad\xc9\x9df\xe5_\xae\xe0T\xc3!\xe5\xb5h\xd67+\x85}\xb5BI\xae\xec\x9bq}\xa9\xbcc\n\xc4$V\xa4\x87\xba~\xaf5\xde*\xdf\x94\xf3SF\xcb\xee0!\xba\xcdL\xafGBon\x1f \xac\xf7\x9e\x06\xdd\xa8\xc6@\xbe\xafO\xcc{.3\xfc(4\x803\xb0\xfd\x98\xa7\xb4\xaf\xc1\xad\xe5H1\x89\n\xc8\xd5T\xea\xe3\x16\r\x99\xaf\xcf\x9dH\x0c\xb4\x8d\xcd\x1f~\xd2\xd3\\\xc2\xfb\xfd\xaf\xd7vN(\x9d\xca\x9f\xa6\xae2YG@\r\x1c\xaf\xda\x9a\xca\t9\xbb\x02\xc9\xc4nbV\xfd\x1d\xcb\xaf\xe1<m\xab\xdb;\x92uk\x83\x91\xea\x83b\x19\xb0\x8a\x0b\x0b\x88Ch\xcb\n\xdd\xc6\xc5\x99oo\t\xb0\xe5\xd1\xee\xdc\x9d\x10[\xf1\x8fK\xcdxV=\x7f\xb0\xf7\x13\x82E\xb8\x82\xdf\x7f\x08\xed\xc6\x85ARx\xb1-\xba\xa7\x82u>\x9f\xcc\x83\x91>E\xa1S\x07\xb1`\xd3\xc6\x90\x8f\xc5\xf1\xa9\xe8\xa7\x1f\xf7&\xab\xd2\xb1p\xa9\xf0P)\x8e=@_^=\xf0\xe4\x842\xb1\x91KM\xc5[\x96\xa29o\xfe\x12p\xe8Tt\xb1\x91\xd7k\x9c\x99\xaa{,Y\xb4\xabe\xd4?\xb1\xb1\xaa\xe7\xc2\x058r*\xd0\xbf\xd1;\x92\xff\x06(\xb1\xac\x16\x9de\xd64\xf15\x18\xeb\xca\x93w)%\xb1\xb2\xa3G\xf8sL\x9a\x86\x82\x92z\x9b\xdc\xdeb\xb1\xb7^\xd4\x1b=O@o4\xc6\xde\xf0\x932]\xb1\xf9\xb0TgO\x14\x9e6\xd2S\x96u\x00\xec\x1f\xb2Z\x84\x8b\x84\x08\xabu\x7f\x81\xd3\xdc\xd1]<\x06\xb2e\x0f\x15N\xc6\xf3P\xffb_\x1e\x92\x86\xd6\x97\xb2\x8f\x18\xa6\xc3)\x0e##`\x83\x15\xd4\xdf<\xd2\xb2\x97\xff\xb0Y\xd6\x11\xbe\xe2U\xf8\xbb\x1d\xa9\xec\xe0\xb2\x9c\x8b\xaa\xef\x9aa2I"\x1f\x9fQ.\t%\xb2\x9c\xb1\xd9d\xc4\xa3\xfch7\xb8\x91\xa31\xf7z\xb2\xce\x95"q\x84\xf6N\xd3\x9f\xd9h\x90\x90\x1e\x9d\xb2\xea!s\xfb{C#\x16\xe1\xb5}o\xa7\x02.\xb3\x01\\\x9d\'F\x94\x7f>\x16\xf9\xb1\x01\x8d\xd3k\xb3\x1b8,\x95\xa0\x98\xa5e\xca\xa2T\xbeG\xf8\x04\xb3+\xec\xcf\x05-+\xb5R\x90\x1d\x02\x85\xb5\x8eq\xb30\x8eF`\xa2U\xc9"[\x81\xa9\x85S5\xb9\xb33\xd7pC\xc9\x80\xc8\x96\xa8Q46b\r\xb8\xb3F#\xe4\xa2\x05\xc3x\xbb\x9f\xdd/2u\xff\x98\xb3F\xe5\xc7W\x86uFG[\xb3"\x9e\x82\xd4\xfd\xb3G\xfb2\xdd\xf8d\x19#\x887&\xa5(\x88@\xb3X\x12\xa5\xad{w\xb9{\xea\x88\xc5\xeb\xe7[\xcd\xb3e\x7fD\x9e\x9du\xd4\xd6\x13%\xf8\xe3\\M\xa9\xb3v\x84,<\xf1\x95\xeb5\xfc\xe9\xc8\x1ah\x8c\x9b\xb3\x8f\xbf\x93\xa5_k\x07\xf4\xa7\xb0\x08\xf4\x11A\xb8\xb3\xa7\xa6\x0eR\xc3\xb3\xd4_k\xaaV\xbfe$x\xb3\xe2\x85[o\xb3\xff\x12e\xe5O#D\x02!\xc2\xb4\x13\xa7\x13\n\x90g\xa3\x15\xc4\xc2\x8aO\x819\xad\xb4;\xdb-\xb4>\xd1C+(M\xd1\xb3\xe2\xcf\x01\xb4Qmo\x9f`\xea]:\xa5w\xd5\xb5\xc9\r\x1c\xb4\xa7\xdaP\x118\xf7\'R\xca\xbf\x1f\x83\xd1\xf4\xf1\xb4\xbc^3\x04\xe7\xed\x10\x00\x94\xd5C\xdf\xc9\xb0=\xb4\xf1\x80\x8d\xe2Q$\xc2\x13\xc5\x05\xca\x0e3-\x0e\xb5\x15J~Wci\xcc\xbc\xe3\x8f\x87(\xff_\xd4\xb5\x19\x9ac\xf5\x13\xee\x08\x1e}\x88\x94\xd1\x9a<\x17\xb5=v\xf1\xdf^\xd7%i\x1a\x8eq\x85\xd8B9\xb5g\xdf\x07\x97\xfcp2\xe0>\xac\xff\xec\xf1C\xa7\xb5l_W\xf61\xc2R\xd2\x12\x8b\xa8y\xde\xcd\x98\xb5r\xac\xf4\xdc;\x07\x16\x9d&\xed\x83O d\xe2\xb5\xa8\x91bL\x97\xb0\x89\x95c\x82\xa9\x16[s\xd5\xb5\xb4\xe5f\x15\n\x1a\x0e\x92\xb7\'\x94\xe9\xe9\xd3\x9f\xb5\xdd\x13\xc0\x00iW\xd2\x0ct\x0e\xf4s\xa2\x9b\xfb\xb5\xf8<D)\xc1\xb0\xff\x9aP\x802\xa9^\xc8\xfa\xb6\x03_L[rm\xc3\xbd(\xd3\xa8c\xd8Je\xb6\x0bv\xac\x145\x05\x9cD\xdfp\xebW\xfek\xc4\xb69\xc7\x95H\x9fp\'\xb1?\x1f\x01\xe43\xc0\x03\xb6j%\xe7\xa7.C/\xc1i]\xacZ\x92w)\xb6s\x83\x04)\x8c#\xbal\x123\x83z=\x04\xc4\xb6\x97w\xb7\xc9\xab\x10\x8b\x9c\xdf\xaf\xd7\x1c\xd3#p\xb6\xb8v\xe0\xd3\x1d^\xff\xd0\xf1\xf6\xcb;\xaap\xdf\xb6\xd0\xefB\x02\x82\xd8\x12R\x86\xe1b\xf1\xfa\x00k\xb6\xe7F9-\xf7*i\xbeg\x04\xb0\xacExo\xb75i\x86l\x87\xa5\xfa\\\xbc\xa2\xb5\xac\xfcF+\xb7:\xd6\x1e=\xdbG\xc9[\xd8l\xb9\xcfm\xb5\x1b\xb7\x89\tcR\xba\x92\xfb\xb6\x90X\x05\xdb\xce\x0bW\xb7\xce\xf2\x82\xbeD=\xcc$\xef\xae\xa8\xb1\nMo\xb8\x02\xe6\x91\xddk\xfb\xe6\xd8\xa8p_p!\xbd7\xb8.D\xb6<\xc3\x92\xffT\xd6\xb7DU\x84b!\xb8S\xf0\x8e\xd3U\x00\xd4\x95\x19S\x0cI&.\x1a\xb8\x8b\x9eQ\xf5\xea\xfd\xb7\xe0\x95\x17\x93Kv\x89\x1b\xb8\x93\x19\x87\xbe\xa3\x1d\x1eU\x0b~\xd5\xe9\x81\x94\x11\xb8\x9b\x87<\x83\xa5\xc1\x14\n\x9b@\x93\xcb;\xeb\x19\xb8\xa25\xffB\x87\x928\x8d|[\t\x00\xe3\x14\xe9\xb9\x1c\x12{\x0c\x07\x18\x9dDM\xd9\xa3\x9d\x06}2\xb9\x1f<\xc1@w\xe4;\x99\xdaA\x11s$]+\xb9I\x1f\xec\x11 \x1f\x9c\x19\n\x90\x937\x84\xee\xdd\xb9J4\xb4\xf5-i\xb6a~\xb0YS"\xaa8\xb9k\xf8\x89\x95\x00\x9eb\xa8\x12*!\xd5\xcb[\x1e\xb9sS\xd4\xfc\xe3\x01V\xae\xf1\xbe4\xd8\xe3\x00 \xb9\x83\xda\x80\x97\xd0\xeb\xddE-\x16w\xec)k\x85\xb9\xf3\xfcL{\xf0z\x1co\xbc\x8bZ\xd2\x16s\xe0\xba\x01\xc1\xa4\x86\x19E\xd5\x18Rk\x9e\xff\x8f\xa6&\xba\x08~\xeb\x86\x8e\x8a\x14\x08\x05\x9a\x15\x11~\xeap\xba\x11\xb4f\xb6\xdc/KW\x9e!\xa3\xcb#&\xfc\xba$\xd8\xc6\xbdX\xb3\x8a%\xf1y\x91v\x1aK\x18\xba=\xf6\xab\xb8f\x02@\xe2F\xb4,B\xf1A)\xba\xbf"\x8f0rM%\x91\xc7du\xbf\x86\n\x02\xba\xc1h\xd1\x05\\\xdb\xd5\xfaU\xc6\x1c\xe5\xa2\xeb\x1e\xba\xed\xf3\xfb\x8b\xf4\\\x07>]<$\xd8\x04u\xec\xbb!S\xaf\x94\xb6P\xe9\xd7s\xd2\xadc1<\x07\xbby\xf6\xe4\x82|\x89s5\x8e\x12D\xcf\xf0\x93s\xbb\x8e\xe4\x02\x11\x85)mX~A\r\xfbC\xee\x8e\xbb\xcb\x9cf\xcc6\xb0:\xbd\xeb\xa7=\xf2\xd3#\x86\xbb\xd4a\xf2t\xc9\xe4\xa84\xee\xdc\x98QJ\x17\xe3\xbb\xd6d\xba\x9eb\xe8\x87\xab\xe2VQ\xf8d\x98\xfe\xbb\xf2\x84K\xeeD\xe9\xef\x7f-Q\xe8\x00\x0e\xb7\xbb\xbc*\x10.\xd1P\xcf\x10\xbe{\x04Z\xe5\x93F(\xbc\x9a\x8f+o\xff\xd5\x85q\xe1\x88\xbb\x11\x05E\xf8\xbc\x9d_\x06\x1f\xc6\xb7RG\xaa\xe8\x85\xd0\xf1\xbd\xe4\xbc\xafn/\x0b\x86\xea\xa8d\xd3~\x8095\x13\xd7\xbc\xb2(X\xf5\x0e4\xe9v\xb1\xa5\xd4(\xbcbb\xbc\xc9L\xd5\xa5\x93\xd7"H\xe3:\xb5s\xcb\x14h\xbd\x0b\xa8df\'\xe5\xff\xd2\x184&\x92\xf5\xfd\r\xbd\x1d\xd7\xe6t\x14\x06\xc8\x0c\x8f\x8es\x1c\x04\xdf\xfa\xbd6)\xdc\x8b\x07Y\x85:\x83\x8e_\xc2\xb0\xfb\x80\xbdF?L\xf3\x04.\xfe"C[\xad\xd2G\xa1\xba\xbdc\xa6<~\xd3\'5\x97\xfd\xcf<$n\x8a\xfc\xbdn\x1e\x04\xf5\xf9\xc0\x96\xfb\xa1Fs\x96\xec\xb3W\xbd}}\x1e\x15-\xed\x12\xd3\x86\xe3y\xb5v9\x1f\xbd\x7fW\x80Q\x1c\xa5\x07\xcd\x9c\xfd\x9a8\x0fqp\xbd\x8chd\xab\xc0\xa4\xd0qF\xcd3\xed*2M\xbd\xac\xcbsQ\xd7\xec\x16F\x13\x92\xb5\x8f\x97\xdb(\xbd\xd2d\xf0\xd6\xcf\xf9\x07\x02\xab\x15b\xa3\xe0\xf8\xc0\xbd\xd4\x949\x96\xb0J\xc9\xe5\x99o\x80\x07Q\xa0\x15\xbd\xe7F\xcc\x83b\x1d\xaa\xc4\xf1\x0b\'\x97\xa8\xc24\xbd\xed\x0bcD\xe1\x08\r\xe8\xc2i\xbf\x8ahw\x94\xbd\xf1l\xa8\xe1\xfb\xde\xae\xf9\xcb<3(Tb\x10\xbe\x01R\x8b\x1a\xa2"7`\xb8!>?%\xa0\xab\xbe\x81+\'\xd9j7\xafQ#\x07\x1a\xfa9\xf8F\xbe\x8e\xb82F\xe9\x96}\x02+\xfa\xb3\x98\xe5\x88\\\xbe\xb0\xbc\xeb\x0bF\xd6[\xb1ID\x86-@P\xd2\xbe\xd2g\xe4\xa9m\x8d\'\x05L\x9f}\x14\xf2 \x7f\xbe\xd6N\xb7\xb8\xb3y\x04\x96J\xf9jkp\x86\x12\xbe\xdc\x16+ux!>\x861r=\x87\xd7\x04<\xbe\xf2\x8c\xab\xea\xa9\xedN\xfc8\xb7\xed\x16@&G\xbf\x02gf\xd5XTR\xd3?\xe3.\xf6|gT\xbf\x1b_s\xa3\xbc\xc6\xa2\xd4/k\xe8\x9e\xee}\x15\xbf\x8e\xe5\xf8\x9a\xbb`7\xe45\xef\x9cTx\x87\xdd\xbf\xa8"\xe6o\x9f\xb5\xc5\xac\x94\x80\xd1\xdca5Y\xbf\xb4\xbc\xc6\x1f\xdeM3;\xa1?\xa1N\xd0b\xb6\xbf\xb5wO\xd9\xe0\xb5\x9d\x90"\xdf\xb1\x99\xc7\x12s\xc0@\x1f\xd2U\xf9\x9d\x92\xc1\x08\xcd\xbf\x9cz\xd2p\xc0\x80\x92T\xeb\x0e\x1e5\xdf\x8fZ]\xd3@H\x8d\xc0\x8c-\xc5v\xc9\xe1G0\xfd>\xe0\xca\x97\xb4t\xc0\x90\x81\r+\xa5=\x8a\xa1L[\xbb93f\x99\xc0\xc1j\x94C[\xa8\x18\x84\xe6\xbend&\xeeP\xc0\xe3\xbdVf\x0bkd\x8f\x044\xc9Qr5\xce\xc0\xf4\xde_\xf6\xf1K\x10c\x9a\xfd\xef$\x18\xef\xd5\xc0\xff\x91\x18\x92K\xf96hrDu\xd70\xf4\x9e\xc1;I\x08\x94\x80\x10G\xe9Tp\xc3\x13\x00\xaf\xbc\xc1\x91\xb3\xfb\xb7\x1cK\x93\x86*\xc9\xd0\xb6\xb5<+\xc1\x9cy\xb1A\xc8T\x95\x10\xc4b\x0f\xdc\x08Dl\xc1\xba6\xc7\xf7>\x1fst\xbfuF\xb4\xa8\xf2\x11\xc1\xfc\xaf\xd4\xfecS\x7f\xea>M\xc8\x9dQ\x88\x8a\xc2"Hx(\xed\xf3\xc5\xdcp|\x16\xbf|(\x10\xc2\'\x81#\xec\xdd\xa6\n\xcd\xd0\xf5\xcd\xce\xcd\xe30\xc2.\xc2\x86r+\xc5\x83\x1f\x91\x93\xf5kv\x00h\xc2:\x0b,\x9f\xfd\xc0?HW\xfdZ\x90\xa72\x10\xc2?\xbeG{\xab\x0c\xee\x89\xe5Att\xea\xa1F\xc2r&4Al\xfa\xb7\x1a\xe7B\xbd@s\xf3\xb3\xc2y\x80\x90e\xb1!G\x18\xdd\x1b\x9c\x8b\x85\x11\xde\xc2\x9d\xb4\xb5\x05a\xcb\xefn\xae7\x06+\xe5\xb7@\xc2\xa2\x7f\xb9\x8bH\xf6[\tg.E\x90\xb8\xae\x07\xc2\xa6\xe6\x0e-\x12~\xfcK\xd6\xe8\x94\'\xe0\x08=\xc2\xc5%\x1f\xc2\xd1\xeb[\xde\x96l\x91?\x92\x01-\xc2\xd5x*\x0e\xae\x9e0\x94$\x97\xb8Z;\xa5\x89\xc2\xdd\xe5I\x90\x98d\x1b\x81\x05\x0b!w\x08\x82\xa9\xc3\x05\xeflG\xa4I\xa0\xdf\x0b\xdf}\xd9\x1f;\xf0\xc3\x10g^\x02\x82\xf23\xb2\xb6\xe6\xe6#\xb0\xbc)\xc3\x1dHu\xa5\xa6j\xd4n\x9a\x1a\xfd\xc2\xbf\x9cI\xc3a\x99[\x8a\xf9\x04\x8f/X\x7f4\x1bf1\xb3\xc3\xe3{\xe6\x99\x84\xe5\xdf\xe0{&v\xb0eQ\x8b\xc3\xe6\xedd\xb7\x8b;\xccU\x03\x8c\x96\xe7\x1e\xd4 \xc3\xf8\x8696J8\xe6\x13\x1f,\xc0\x9e\xd9\xfeS\xc4\x003\xee\x91[\xacV\x8c\xe0\x19\x99\xc3.\xc3v\xc4\x1e\x85,k8\xb6\xf0\x0c\xa2$\x8f\xd6\xbf\xf5\x0b\xc4@\xed5gm\x8e\xf2\xdc\x04\xbc\xbdj\x15\rO\xc4B\xb9\x07\xe3w\xda1\x8c\xa7\x1a7\x89\x85\xea>\xc4Z\x94(]\xae\x89\xe3U#D*\x9f\xa4\\\xe8\xc4[\x8a\x13\xd7gC\x83{Z\x9d\xa8\xfc\xca\xa0W\xc4m>\xc7\xa0{\x8a.\x13j48\xd7l\xb4\xd4\xc4\xc9\xfa\x03\x90\xc5\xd2\x8e9\xadQ\x9b\xedR\x8cS\xc4\xd2W\xa1H\xa3C\x96]\x88\x97\x81\xb8\xe8\x1e\xb9\xc5\x17\x13\xc2Qs\xfa\xa0\x01\x96\xbfb\x89\xa0\x0c\xf8\xc52*W\xca\'\xf8\x03U\xee\x84\xa5\x8f\xb2-I\xc5O\x150"\xf7\xf2H\x1c\xca\x1b\xb7\x05\x86\x7f\x8b\xc5\x7fh\x11`\x8dh1\x1f\x90\xc7x26\xfct\xc5\x8cc7\x9b\xdc\xd5\x14\xe5\xec\x9e\x82D\xeb\x02\xa4\xc5\x9cK\xc0@\xa2\xfdY\x8d\xf3\x97Y\x93\x9c\x862\xc5\xbb\x90<\xb6i3:\x01>]"x\xe7"0\xc5\xe1)\xf4-\xe6\x7f\xee\xe2\x0e\x1eKZ\xc8\xb2s\xc5\xf2\x03\x0bM_\x91C\x0fXc\x1c[)\xb0\xf5\xc5\xf64"\xab]Ee\xcfnH{\xa6g\xb7/\xc5\xfb\t;\xea\x122p\xb3\x99\xd3[\xd9\x14\xb7a\xc6\x1c\x8a\xdby\xc5\x13"JJt\x18\x93\xdc\xc5\xde\xc68\x93\xaa\x04+3\xedG\x83\xaaW\\\x8b\x92l\xc6e1=-j\xf9\xfa\x05\xaf\xd21\x8bZ#0\xc6f\xab\xc1iU\x15\x96\xb5\n=\t\x1f\x17\x81y\xc6k\x18\x93P#\xb4\xf9B\xb8\x0e\xd7\xe3\x8a\x85&\xc6\x80\x86\xb5\xabZ(\x19\x8d\x82\xfd\\4\x1d&<\xc6\x85;E;\xc8\xf4\xbbyhi\xceQ\xb1\xb7\x0e\xc6\xab\x97\x1a\\`TZ?{\x0e\x897\xa3\xfc\xc9\xc6\xac9\x97Iip\xb8\xf5\xaf\xfc\x90\xf62\xa7\xa6\xc6\xb56\x85\xcc\x99\x1ed\x82bH\x92\xd6\x12w$\xc6\xccgv\xd36:\x9e\\\x08\xc1\xcf\n\x1b{\x83\xc7HW\xc8>\xf9\x81\x9aJ)\xd1\x15\x146\x97\xff\xc7M\x01\xc2Fci\xe5 \xc2\xa0\x82\xd3\xbeC\x0b\xc7M\x8e^F3\x99\x83\xea\xb08\xd6x\xd8>\x12\xc7g\xb1\x9e\x14\x10\xc1LT~\xa6\x05W\x061\xb0\xc7w\x8e\xf2tX\x03\x97V"1\'\xc2\x13\xf9D\xc7\xb1$\x9eT\xfag\xfd,TD\xbd\x1c\x04c1\xc7\xb7Ah\x8fL]\x01\x81O\xcf\x13\x94\xc8\x13\x04\xc7\xda\xbc\xe4}}\xbbR>\xae\x82\xf4\x8du\xab\t\xc8\x06\xf9f\r\x17.\xe8\xbdc\x87S\x81\xef\x89\x8c\xc8\x0f\xb1BY.\x03~\xa5\xe5\xf7\x08\x96eG\x91\xc8/\xfd?\xe1>\xd1\xe9;\xe2\xd3\xb0A\xa0\xf0\x82\xc8eh\x95\xb2\'\x82p0\xd7\xf1\x08\xb9\x114\xd5\xc8vT\xfd3d\x1de\xd5\xc6\xbf4\x1b\xe3}\xea\xc9\tp}\xbb/\xa9/\x10\x9b\xf6\xe8e\xf1\xef\xf5\xc91\x98\x9c\xe4\xb7\x0c\x02\xedi\x94bf\xf5\xc7M\xc9H\xde\xe8Gg\x15\x0b\x18\xb9\x15\xef\x0b\xb1\x1f\xdf\xc9_=`\xd2r\x96\x1d\xf1l\xe6/k\xfe\x0c\x84\xc9\xaa \r\x83\xc9\x95C\xe3\xa3?\xd1\xf9e?f\xc9\xb1\xaf\x9aD\xd4\xac+\xf9\xf3\xbc\x8d\x8e\x85$\xed\xc9\xd0\x8e\x86!V\xf4@`\x1aM\x01\xa4iCm\xca\t\xea\x04p\x80A\xe5\x93\xb9\x8dVK\xa4)\xc6\xca)O\x8a\xf7X)\xc8\x03\x8c\x887\'~\xe2q\xca*l\xfaK\xda\xe9Z\xa71r\xa0u\x1e\xff\xaf\xca/\xee\xb3\x10\x80\x14shj%V\x93*!\xf3\xcaW\x11U\x7fk\xdf\xa83g\x984\xe9\xe7y\xa7\xca\xb5\xd4\x9a,`\x1bW\x8c\x9e\xedUA\x7f\xae\xf2\xca\xde\'\xaeGo\x8e\xb1\xd9\xf5\xd8\xa9E\x10\\C\xca\xe4\x1al\x98f\x13\x9e\xcf\xfc\xca\x9d.\xd4\x94\xab\xca\xee\xce\xb5"}\xb13\xae\xb4`\x1f\xe6\x0b\xc7\xac\xcb\x0fv\xa0q;` \xcb\xdd\xc6Z\xa87\xcc\x83\xcb,X\x9a\xc3\xb4*$^w\n\x87\x8e\x1f\xab\xb7\xcbYB\xa5\xf9\x87\xc8p\xb1p\x0bc\xb5;UG\xcbq$\xc7Z\xf9\x1c\xa0\x0f\xf6a\xeeh\xb6\xb1\xcc\xcbz\xc6ka\xbb\x8bb\x84\x9f\xa3!X\xcc\xc6\xfc\xcb{w.^\xba\xb9\xef\x93o\xd7\x86\x91$b(\xcb\x89\x08U\t\xfa\x05h\x16\xca\xc5\xf4Yg\x9d_\xcb\x8dU\xb5\x94s\xb32b\x8d^\xb8I\xb4FW\xcb\xb7\x8e\x02\xb0\x01\x1c\x92?;\t\xd6|;*`\xcb\xc7A\xa5\x10\xd7\x91\xb3\xad\xb7e\xfa\xc0\x84\xba(\xcb\xd6`\x10D\xa6\x93\xa9\xf8\x01\x8bD\\\xe5w\xbb\xcb\xe0\x88(\x02\x93\x94\xb9l\xe8\xe4\xfa"\x07\x80\x0e\xcb\xf8:\xdb\x1b\xb7$g\x13\xfe\xeeQ\x95gKz\xccL9\x04\x17\xe7\x0bs\xdb\xafBC\x08b.\xec\xcco6\xc5\x82\xa8\xab\x83\x8d\xe0\x9a(\xd3\xb6\x0f^\xccon8C\x98\xd8M\xea\x07l$\x86J\x86\xfe\xcc\x8az8@\xe1/\xb4\x08\x05\xb9^\x9c\xe8t\x88\xcc\xc8\xfb\xa3\xfe\x85\xd0;[\x8b\xe7\x18O\xe8/\xb9\xcc\xcez\xa7\xbft=/l\xc5\xb0B\xc0L\x99\xcc\xcc\xfe\xa5\xec\x96iw\xdf\xb0\xe7\x83\x02{k\xf8a\xcd%\xbf?\\\x14/\xea\xb3\xeetc\x85\x84!\xf3\xcd*\xbd\'%y\xe3j\x18/N1pj\x89\xf5\xcd7O;,2@\xb0\xd0\x1b\xd8\xb9<\x9a\xd8\xa9\xcd9V\x93\x1eo]\xf2\xa78q\x07\x0bN\xeb-\xcdp\xc5\x96\xf1e\xec\\1>\xcc\xe2;)\x05\xf0\xcd{\xdc~\xa0Iq|I\xb2\x89\xfbk\x9bA\x89\xcd\x8b\x12G\xe0\x87\xa4\x0e\xbb\xcc\xb1\xbf\xcc\xb0Wy\xcd\xb9\x08\xadp\xcf\xccO;\x11\x15\xac\x1d\xbe\x06T\xcd\xc2F-qQ\x15+h\x88\xb4\x1fq\xb5\xd6\xa4\xcd\xd9\x12\xcb\xc4\xb0\x02x\xe0[\xc3\xaf\x1c\xdc[\xdf\xce$\xdc"/=\xea\x07\xdap\xeai\x85Q\xcbF\xce\x98K\xd8\xaar\xeb\xa5\x8d\x81y\xbe\xc94\x1fk\xce\xc98\xf7\xbd\xd15\xa78d\x9d\x05\x96\xa9?\x97\xce\xdc\xfez\xe3\x00w\x91v\x8c3i\r\xc7_\x08\xce\xf4\xdfh\xff\x8e\x8c\xbe\x07i\x98\xbf^|6&\xcf,\xde\xc1n\x03w\x85\xfd\xab=;\xe3\xd2\x9b\x17\xcf/\xff\x82\xc3\x93\x16\xb4\xed\xf3\xf8s\xda\xfb\x8f\x9c\xcfX\xa0\x1d\xccK\x11\xd7\x8fi\x13\x88Gd\xdfr\xcfgu.9.\xcc\t\xc8-\xd9\x83{\x89L\x10\xcft\xd8t\xfa\x86\x8bP\xa552\x0e`\xd34m\xcf~n\x94@\xa9p\xba\'\xd0\x19\xa6\x98\xb8\xf7H\xcf\x8a\xd1-!\xf2\xfe\x19\x05\x8b\x83\x97\xc2K\x8d\xc3\xcf\xbe1\xcb+Dd\xa4LS\xeb\xf6\xaa\x07\xce\x04\xcf\xd5\x81.-\xccA?6\xcf\xfdE\x90\xbb\xb4\x81\xd0q\xa9\x95xU\xdc/\x92\xf6\xabPTE\x98h\xd0\xa7m\xad9o\x9aa[4\xca\xbcv\x9a\x16\x08\xd0\xd83@\xc1\xea\xfbf\xdcV\xf0\xf7j\xe5O\xad\xd0\xfe\xa5\xc7\xb6ka\xde\x12\x0f\x9fr\x83(^\xe1\xd1S\x12\xb3\xffx\xd8`NX\xfe%\x13\x14A\xce\xd1tG\xef\xff\xcc\xdb\x11Otw\x86\xd8q\t\x0b\xd1\x9cS\xfe\xb5#L&\'70\x93\x91z\xc9q\xd1\xa2\xf8-\xa0\x12\xee~b\xf2\xca\t\xe5 \x06\xa6\xd1\xa7x\x9fwC\xcee\x7f\x15p\xfe\xee4$\x1a\xd1\xa7\xea\x95S#)\xbet\xc3\xcd\xe3\xbe\xd83\x14\xd1\xb9\x8a\xcf\xb8\xcb\xc4@(\xcdp\x16\xdd\xe1\x19\xdf\xd1\xbf\xee\xefm\xdd0\x8e\xcc-%\xe3|\xa9A\xf7\xd1\xe4\x10\xf16\x05T\x8a\xc5\xa9\xe2\xc8\xfe\xd5\xc6)\xd1\xf6\xb3\xde\xe9\xdfl\x08W\x9a\x9b\xd0\x12\x90?\x8f\xd2\r\xa40\x98mJ\x87`\xab\xb2\xe6\x10R8\xcc\xd2\x12\xf3\r\xa83\x94\x93%\r \xb5\xc1-\xf7\x0b\xd2\'\xb7\xb4\x96\x9bG\x1f\xedP\x95\x96\x9316\xe0\xd2*\x0fL3{\xc1\xfd\x8f\x98PY\xf7z\x1d"\xd2\\\xa5\x0b#\x98\xb2\x17\xc5\xd8\xaa\xa3\x1c\x83\xbb\x98\xd2o>\xc3\xfdyL\x80%\x19\x00.\x86\n_\x1a\xd2v\xf6\x00\xfc/:\xd5\xb2\xd8\xfc,O.\x8c\xe1\xd2\xbb)^\x91.`\xe5\x00\x91.5\xce|\x92I\xd2\xe3\'\xff\xbe\xa5m\xef\xa5\xc2\xd7\xec\'\x1cH\xa4\xd3\x1f\xf63\xf8\xcb\xc5\xd8^9\xbd\x1c\x9c\xe2\xb0\'\xd3Z\xc8_\x96\xb9\xdb\xdeRm\xdf\x91\xde\xfe\xcd\xd1\xd3`\x9eiME4w\xcc?0V\xae\xaai\\\xd3d\xb0\xd7u\xc4\xab*\xa5@\x91:9,\x97O\xd3y\x1e\x8b\xd8\xd6\xfeR7n\xff8\x98\xaba\x80\xd3\x90\x83\xce\xe8\xa6X\x84\x97v\xd5\xc6\x19*\xdel\xd3\xcf\xc2LE\x98\xba\x99\x12\xd5\r\x93\x90@\xd3`\xd3\xe1}\xef\xa9\xd8c\xbd\xed\xf4\xde\xa7A\x1f}H\xd4\t\xfb\xcd\x83\n\xf6\x15\\\x80F\x00)d\xfc\xd4\xd4\x1f\x93,\xc3V#\xa3\xc8\x1en\xc6\x87\x93\xf6\x0e\xd4(\xe8\xbbs/\x8e\xb3\xb4\xd4W+\xea\x1a\x0c\xd0\xd4c,iD\x8f\xb4\xd9\x18\xfc-?\x16y+\x98\xd4h=\xa2\x02=\x9a\xca\xdd*V.\xe8\xa2\xc9P\xd4\xb7\xb5wGS\x19\xc8x\x1f\x9a\xdc\x99\x7f\xf8\xfb\xd4\xbc\x8b\xae\xc5&\xcf\xf3\x1b\x9aYZ>\\\xdf*\xd4\xc0!\x9f\x15Yw\xf2K\xaf\xda\xab\xd9\xb0=\x1c\xd4\xcb\xd6\x87\x14\xbe\x0f\xe5\xfe)\xb0/\xae"\xf6=\xd4\xf8\x97\x16 \x82\xc4\xb9\xb4Ne`\xb6\'\xf6Q\xd5\x1b\x80\x1e\xd5\xa4(H#\x8b\xb4\xbc\x13\xe7\x80\x93\xd50\x05\xe9-\x996\x8b\xe4\x96\x93\x8f;L\xdc\x8d\xd5k\x0bm\x06\xb5>\x81\x0e\x0f!\xa5\xdf\xd6tX\xd5r"\xb9\x98\n\x87ku\xa5\x91\x19\xfaW\xdb\x80\xd5\x96\xac~\x92I\x93\xca\x93\x01\x95Xtg\xca\x0f\xd5\x9e\x18%\xc7\xbd[~\x0bv\xf8LF\xbf,\xd9\xd5\xc3\x8d?\xc65\xe50\x83\x11\xd4\xb0o\xa9\xc16\xd5\xc5\'z\xa4\x90\xd7io\xa4$\xb6i\xc7[/\xd6\x0c\x85\x85\x95\xb3\xc3\x96k\xcd\xa61\xf2ZER\xd69\xf3]@)\xb8\xcb:\x08t\xb8\xddr\x0e\x8d\xd6E\x03B\x1d\xc2j>?x\x1akS\x1dX\xb0\xd6]\x9e\xee\x9dz\x12\xde!V4\x0fUo\xcf\xd4\xd6\x87\x80:\xe6\xb3F\xad\xe2\xa0as\x8c\xec\x89\x8f\xd6\x987\x17\xe7\xf6\xa7\xbcC!\x1fs\x0f\xc2-c\xd6\xb3\xc6l\x96\x9d\xe9Kb6}\xe3\xaa\xd6o\xa6\xd6\xf1\xf1\xe1`k\xa0\xb4q\x84/\xf5\x00\xea\xc4\x04\xd7\x01U~f\'h\x9eX\xae\x92\xfe\xe5/\x01T\xd7\x1e\xbc\xe5a\xad\x1eZ%\x95\x16C\xd44N*\xd7-\xab\xce_\x96\xf7\x17\x8d\xf6cO\x9f\x1b\xf5D\xd7@\xf3\xf8~\xd1 \xfacB\xf9\xd9<\xcap\x96\xd7\xd6\x98\xceL\x9a\x19N\x95\x8a\x00\x08\xce\xde#r\xd8\x18-b:l\xd4H\x1aT\x8e{\xd6\x9ej\x9b\xd8\x1c\x83u\xf1\x1ft\xb0`4\x01\xf6\x1c\x7f\xe7\xbf\xd8R7\x9aek\xe0!\x8f.\t\x98\x140\xc1\xcf\xd8Z,\xcb\x96\x8b\xc1\x19Y\xb6\x07\x0fi,\xed8\xd8{\xe6i\x04i\x02pB!\xfdp\xa2\xac\xf0?\xd8\x9a\x05c\xa1\x00\x08\x0f\x02\x16<K\xa8\x1cA\x0f\xd8\x9c\xb5J\xe15\x1e2\xf5\xce$x\x15\xfe\x97l\xd8\xba\xd7(\x16Ll%\xaeg\x02\x97(\xb3\x95\t\xd8\xc1"HV\x07`ZNM[\x81\x86\x9b\x9a\x02\xd8\xd5rBGEg[\xf1\xa3 oxw\x82C\xd8\xe1\xf9E\xf4`\xb7hAiL\xaa\xf5\xf2F}\xd8\xe5\x02r\xc1\xc69\x9ey\xa7\xde\xe8R\x0f\xc4~\xd8\xeeu\x05\xea\xfam;m\xbc\xfb\xd8\x1a\x08\xfey\xd9\x13A\x88,|\xa2\xfc\xc3\xe3\xd1\x99!Loo\xd9\')v\xb7\x98\xbc\r\xa3\xd0\xce\xa6FM\x0c\x15\xd9+\xd5\x87\x8d\x81\x9b6\x12\x1dz\xa3g\xff$\xce\xd9-\x162\x00\xa4v\xb1\xd6\xe0\xa3\xbeF\xd42\xb9\xd9:\x15a\xee\x94\xd75`\xeb#<\xe0\xba\xf9\x9c\xd9J\xc1\xfb\x82v\xbem\xe4x\xbb\xd7\xf8?\xa2\xa8\xd9P\xda7C\xe0\xae\xf7A\x03\xcc/\xef\xaa\x80\xa1\xd9u\x085\xa2\x86\x8a\xc9W\x1f0\x04n\x92\xe1\r\xd9\xb8\xdf\xf3\x10}\xe8~\x83>\xc4R\x7f1\xa9\x87\xd9\xc5\x05g\x92F\xf9k\x99\xc7\xd0y0g"p\xd9\xe2\x7f\xc7i\xc9A\x85\x82\x93\x1d\xa0\xd9\x1c\xa8\xb7\xd9\xe2\xb5\xd7\x8e\xe2\xa3\x94\xf6\xad\xf4\xb3\x00\xe5T9\xda\n(=\xf5\xa8\xbb8\x1e\x96\x14\xe0n\xee\xadn\xda\x0f\xf6\xa5z\x939\x11\xee$#\x06\xca\xb5\xf4\xa1\xda\x14\x06~\x9d\xabT\xf0*\xebQ\xf7q\xbd\xdf\x7f\xda\x15\xa8\x07\xe9\xddh\xb0\x10\xa5\xa5\xa3u\n\x1b\x0f\xda:\\B\xf0\x06`a\xe8\xba]\x0c\t/x \xdaJ\x13\x0b!\xde\x03I\x02\xb1\xe0\xac\x99\xe8G\xb3\xdaa\x9d{\xe1 \x147EF\xec\xd9iG\x92\xa6\xda\x80\xc8\x0cwK-\xb0\x1b\xec\x1e\xe4*\x15\x0f\x92\xda\x8e]\xbab\x83#\xa2x\r\x94>K\x08*\xc7\xda\xe1,\x8ev@H\x88\xed\xbf\xb2\xe6\\\xe8\x83\x8c\xda\xe9\xa2\xb6mX\xd5K"H\xa9\xcd\x05\xf2\x1c\x1b\xda\xee\x1d\xab\x12\xd3o\xe97\xa1Z7V\x0e\x8f\x88\xdb\x12A\xd8\xb5\xa5UY\x97:\xb9\xfc\x88\xdc\x99~\xdb)\x10:\xec\x1a\xe0\x03-\xf86\nsp\x8c\xfa\xdb)L~\xb5\xf5\xc5\xa8{\x95g\x80\xa0\xee\x17\xc7\xdb*\xa6\x8a\x17\x8a?^\x82\xb1\xc2N\xf2\x83\xbe\x88\xdb9m\xe7\xa4\x1d\xbd\xa7\x06\xa4\x08\xbb3\xee\xadX\xdbI\x19\xb7Mt\xd3\xd0\xd1\xdbr\x8b9\xeaGi\xdbT\xb4\xaa!W\xd7\x81!\xc1\xf5\xca\\\xa5\x9e\x18\xdbU\x04\xd4\x98}j\xabE,[\xebq]}\xc0\xdbdb\xe9\xa4VVK\xa4|\x9e\x13\xbeM\xb3\x1d\xdb\x9f\x91\x9d\xbaV;\xa1\xeb\x10E\x94\x92\xd0&u\xdb\xa1Q\\\xd9\x82\xe9\xe0\x1a\xdd\x85CF\xa2\xde\xaf\xdb\xae{\xc0\x86\x13\xe8\xfe\xa1\x90t\xcb\x82\x91\xaa>\xdb\xb5\xbf\x1f\x9d%N\x8c\x89\x88\xef\xd1\xb3\xc2\x8b\x06\xdb\xb6\x12\x88\x8b\xb6|[\xaap+\x02\xcaI\x90\xde\xdb\xe1+IZ\x9e=]\xb0\x00[\xb6\x97\x90\xbf\xa5\xdb\xee[\x97\\c\x8b\r\xe8/\\\xe4\xdd\x8c\xba\xbb\xdb\xff:1\x9a\x05\xec\xbbYU]\x1b\xc15\x85\x14\xdc\x03\xa7\xc6\n\x82\x986\xa6\xc8t\xe6\x039\r~\xdc\x06\x0e\xaaM^\xa1t\x18\xd9\xa2\x17\x03^\xa7u\xdcn\xeb\xe3uL7\xc4\x95\xc4\xc2\x80F\x93\x03\x9c\xdc\x8d0]\xb9@\xc5\xf0\xd3f\xaa/eq\xd8]\xdc\xdf\x11\xec\x1d\xce \x8fn\xa6D\x1dJ\x8b\x80\xf1\xdc\xff\xa5\xe5\x84\x1c\x03\xcd\x06\xba\xa7\xbc\x87\n\xd5M\xdd\x1f\x0b\xea\xf5\x8f\x99>\xe9\xfa\xd7\x1e\x15\xaa\xb1~\xdd`\xbdH\xa2\x11\t\x8b\xe4\xeag\x99\xb3\xc3\x84\xab\xdd\x96\xd6\x10\x95.C\xd0W\xb7e-\x84\\\xcah\xdd\xb0\x06\x99\xdf\x9c\xaa\xaeh\x80\xd2\x85C\x81\x95\x1e\xdd\xb8\x1a\x01o.\xc5\x99\n\xb6\xdc\xf1\x9f9|\xb7\xdd\xdd\x8c\x11vj.g\x92"SB\xeb\x9eP\xb4\xde\x023\x1a\nd\xdb\x9a\x8a\x1b\xbf\x0e\xf3z\xc8\xd6\xde\x1c0R3\x0e2\xd5U^\xb8"\x9d\xc6I)\xdeL{Gu\xf0aYac\xd8yw\x8e\xcd4\xde~}\x1c%\xa1\xc30MJ.sy]\xc6\xef\xde\x86i\x90\xde*\x1e0\x93\xd5;\xccE\xdc\xecb\xde\x8b\x92[\x9a\xe8\xf0\xdf\xe5\x8c\xd1\xc1\xce\xab\x84\x85\xde\xa9\x8f*\xa9{a\xbe^\xaemO\xa51\xf8q\xde\xb4eK\x8a\xc6\\\xe0\xca\xe1?\xd9\xcf\x11\xb6%\xde\xcb\xf8`\x8c\x96\xcc\xde\x08\xc0of\xd7\xd4!\x99\xde\xcev%\x94\xd4@h\xac\xc0 6\xc6\xa9\xdc^\xde\xd3X\xbdT&\xd9\xfd\x0b[\x8f\xf7\x9c<8\xe9\xde\xeb\xc0\x93@\x97\xa7\xc2b5B\x1f\x1c\xdfx\xe3\xdf\t^\xcb\xde/!\xac\x85/\xc1\x82\x83\x85C\xc4\xdf\x0c\xe8\x1e\x0c\xce\xfc\x10\xfcY\xf1\xa1\xbc\xab~\x01\xdf4B\xffk\xac\xe8}\xffI \x9d2\x8c\'\x01\xdf@Z\x8f\x1c\xac\x1a?\xfd\x9f<\x9eA\x89:\xc8\xdfV.\xa5bQ\xd8n\x13p/\xb9\xd7\xcf\xca~\xdfh\x94\xf0x\x07\x92\t\'\xfe=\x9fWB\xcb#\xdf\x84\x19\x90\xe1\xdc\xf4\xff\x0fB_`7\x19\xa6\x03\xdf\x8b\xf1\x04\xfbN\xc0\x01\xbe";;\xaby\x8c6\xdf\x8c\xc81\xbda\xa1\xb2N\xaa*\xde\xd1K\x1d\xdb\xdf\xb6\xfe\xd3\r\xf8\x00\xca\xb9\x8f\xd4\xd0\xefy\x82\xce\xdf\xcf\x94\x01U\x05k<c\xa3\xed\xe4C\xa8\xde\xa1\xdf\xde\xc7AF?g\x81i\xf7\x9f\x86\xb0\x86\xf0M\xdf\xf3\xa7#qZ\x02\xef b\x92\x94G\x1aJ\x9a\xe0\x01\'x]Q\xe8;\x8a\xb7\x0bZ\xb6nn\x8a\xe0\t\xb5\xc3\xd3\xa9\x93,\x94\xee\xe4\xadd\xc56\xa4\xe0\x0b|\x91\xc6\x02\x1a/\xb8;\xc88\xe1\x02\xbaf\xe0!\xb3\xfc\x04{\xfd\xad\x8dj\x91D\x8c\xb0x\xf3\xe04\x84(\x8e\xebo>[4J\x97\x88\xcc\xa5\x1a\xe07Au#\x12ar\xcb6Y\n\xc7\xac\xf4\x01\xe0O\x00\xf6\xbf\xc1\x0c\x08_W\x0f<\x1dmE\xee\xe0\x97\x92\xce\xda(;k\xef\xfc\x07W;\xb3\xab\x8d\xe0\x9e\xcf\xe8a\xe1\xed\x1e1\x1fd\xdd\xd3\x03-f\xe0\xb5\xce\xd1\xad*\x1e\x91:\xb7\xa1\xa7\xa5\xed\xe6\xf9\xe0\xe1/\x16\x93a\x1a\xdf+o\x8f\x08\xe8\xb5\xebn\xe1\x07#\x8e\x85\xb0\x00_7\xab\x98\xc8V\x99*d\xe1\x0f=e\xfa\x80\xd5rA\xe5\xe3K\xccy:"\xe1\x1b\x9bP\x93\xbf\xcf\x06\x80\x1b\xd10\xc6\xf99\xa7\xe1$\x03\x97t\xad\x7f`\x13A\xe6\x8f\xca\xcd\xe4\x08\xe1b\xe7&G-\xae\x16\x8b6\xa0\xd5&\xea;H\xe1\x99P\x18\x1a \x13\r\xf8\xc0\xe3Ex\xe3\xfbr\xe1\xa9\x0fV\xf7\xcc%L\xb2Q\x96\x96`\xc7\x95\xcb\xe1\xd7m\x0ea\xaf\xd8\xd3\t\xd1\xd4\xc5e\x82:_\xe2\x12\x13N\x17\xce\x03\xe6[\xc6m<\xcd\xf0(\xf4\xe2\'z\xef\x92\x1b\x97b!\xaa\xbf\xc7zZ\xac\xd0\xe2D\xd2\x0bK\xd1\x1c\x01F\xcd\xfdy\x8e\xae\x02\'\xe2F\xfb\x8fs8\x15\xca\xfb\xd3\xec7hw\x8f\x9b\xe2pLo2\x0f\x83yc\xe6\xcd"\xdbKz\x85\xe2\xf6\xf1\xc7\xb6\xd2\xec\xcb\x14\x8d\xb3\xe8[\x83\x19\x88\xe3\x1d\xb9\xe4\xd5F\x93\xf99\xac\n\xc40\x8a7\xb4\xe3\x1e\xf1o\x97\x14\xbf\x97`n$d\xf9\xae\x08\xa0\xe3Cz \xef\xfcYu\rK\xb9\x18\xebz\x06\xf4\xe3\xd8s\xf5\\\x02LU\xda_S\x0b\xae\x87Ts\xe3\xfe\xf2\xdf\xd5\x93\x19\xd6\x0f\xe6s\xf5\xcd\xd67R\xe4\x05\xfc\xeb\xba\xaa|Sy\xc8\x95\xd7\xb4\x9a\xea\xf3\xe4(\xe5\x80\x10+Ug9\xce\xea\x81bQ\x81\x8f\xe47\r\xc2\xbb\xd5\xe43\xab\x9877\x8f\xfa\xd9\x08\xe4=\xfe\x06U{\xf3\xd1\xac~2sl\x00d)\xe4>\xad\xae\xdf\x84\x08\x18Lx\xcf\xff7c\xbd1\xe4O\x05\x00.\x06J\xfc\x8c*\xe1\x13g\xac\xa0#\xe4j\xc3~Q\x869\xeck\xde\x8f\xf9\xdf\xda\x19p\xe4\x83/%X\xf6\x05p4\xdfU\xae\xdc\xd2\x7f\xc3\xe4\x9ar\xa7X\xa6\xd8+\x12\xa8\xa0-DU\x17\x99\xe4\x9e\xe5\x90\x1b#\xbbJ\x0c\x17UR`\xeddC\xe4\xa8\x14\x0c\x0b\x00\x05\xd9\x99\xb7\xf1\x92\xb2\xb5\xc3\xc6\xe4\xc1WR\xcc\xd4V\xdf\xee\xcd\xdb\xc7\xa5\xa8\x1a\x11\xe4\xc3Y\x80\x01S\xfc\x01jW\xaf\xd4\xa8\xd6\xeeD\xe4\xcc|u\xd8%\xe9~\x03<\xe9\xb2\x90\x84\xca\xc8\xe5\x04\xa7\x0b \xc0\xbfm\xed[\x9d\xb8\xad2\x02%\xe5\x05\xd2\xf3\xd5\xe0\xcdOC\xbd\xb5ZQ\xd3M/\xe5q\xde\xd4\xaf\xde\xa7x\x94\xb1\x0f\x1e\xb1\xec\x0eN\xe5\x7f7\x11h:2\xb71\xc8\xd3I\xf0^\x8eD\xe5\x80\x924\xa6\xd6`>\xd9S\xf7\xe4K\x98RN\xe5\x96\x91\xc6\xac\xf1\x00_\x14\x8f\xa0\n\xea\x99\xa4l\xe5\xb8\x05\t\xef\x8eA\xf5-j\x1e\x92r\xb3\x06\x9c\xe5\xcaA1\x91\x80a\xe0\x01\xe6\x87\x94\xf8\x91pm\xe5\xde\x07\'\xfc\xc7I\x9c\xc2hr@,\xa53\x18\xe5\xe8J\xd2\xaf\x8d\x8bI\x9e\xf5\x9d8\rG\x15\xe4\xe6\x11\xeb\xcb0\xb6*T\x03\\Z\xfe\x10\xb9n\x91\xe6\x16\x1eM\x10p\x90"\xb5\xab\xc1cE\xb9\xdeo\xe6\x82\xe0\xee\r\xb0i\x01l+l\x9d\xaf\\\xeai\xe6\x84[\x15V\xf4\x06\xd8\xacU\xea?\x94\xa5\xadx\xe6\xb4;\x16"\x8aq\x87\xd2\x96\xc9Y\xf392Y\xe6\xbd;L3\xfdMi\xa3\xc9~\xba\xa4\xbfu=\xe7\x83\x87\x06\xc1\x13D\x0e\xb9\x87\xdaD\xde\xb9_ \xe7\x92\xe3pq}]|\xf2_\x98`!\xe3\xe7\xc3\xe7\xcf\x11k\xb2D/)#\xa4Q\xa9\xdb\x1d2\xf8\xe8\x02\x0f\xa3\xa3\x87\xf2\xbc\xf3\xb2J\x9do\xdf\x99y\xe8E\xbfn\xcb\xe3\xc9\xb3\x87\xed\x1e|f\x8f\xc6\xab\xe8X\xbe:zDq\x9f\xef\x02p\x86W\xa2\xebz\xe8p\x03\xc5X\xbbv\xb4@R\xcf\xd1\xeaLl^\xe8zjx\xd8S\x1e\x8e\xbd\x8e\x0e=\x8d.\x12\xcd\xe8\x8d\xe8;\x1aY\x19g\x1c!^M\xb3\xed\xcb\x0e\xe8\xc6y_\xbb\xa4+\\"T\xb5\x12\x11\xb1R\xf4\xe8\xc7\xb9\xfct~I(8FSKH5\x9d\x14\xe8\xca\x16\xdbl\x8c\xfd\xf2\x8a\x8d\x84Aq\xa8\x8a!\xe8\xe3\xb7QW\\\xef\xfe\xb9\x03\x07\x13\xdb\xc7\xc7\xe1\xe9\x0f\x8cw\xd6\xa83T1\xb0J\xd7&\x96L\x97\xe9-\x9a\x05\x17\x8b\xf9g\xc4\xe4\xc8\xa4o\xae\xc3}\xe9.\xf1\xd5 h\x14\xe9L\xb5\x7f\xcf2\xfcO}\xe9\x8d\xb3\x0c=76\x0f\xff\xe5\x98w\xb7\xd7\xd3\xb6\xe9\xc1\x1c\x10J\x8c\xbf\xf6H\r1\xd4\xf2\x06\xad\xf5\xea\x08\xc6\xcd\xf5I\xb2p\xbf\x9b\x9b\xc3\xfe\xfd\x01y\xea\x15\xb9\xaa\xe3\xad\x12y$\x1bg5^Jq\xb4\xea.\xd5S\xf4\x85t_0\xaa\xf6_\xb5\xf9\x07\xa2\xeaG\xd5d\xf1\xac=3t\xc5\x94\xd5\x18y\xf7.\xea\xa1\x1a\xa7K\x8ft\xa0\x05\xb7(\x87\xb8N\x91\xb9\xea\xc5\x98\x99\xc0\x03\x95\x12q\xa2r3q\xaa\xeaU\xea\xce\xc0M\x97ZF\xa3\xfd\xb4\x8f\xd6dj\xa4\x97\xeb%\xd2\xd0\x1b\x16\x8e\xb8\xe2\x93\xafJ\xdf"]\x86\xeb0\x04\xe7\xf8~\x9e7\xf8\x1eKm7K\xb6\xcd\xebL@n\x05\xe2\x12~V\xbe\xed\x96\xfcg\xc3\x7f\xebU\xf5V\xed\xfe\xb1j\r\xc2\xca\xf7Y+9\x0c\xebcV\x85-\xd8q\xbbW7\xa3\xa1%\x98r\x02\xebh\x85hj\xde\x8c4\x12_\xef[\xb6\x94O\x11\xeb\x7fk\xe6\xcba\xc0_\xb2\xe4}\x8e\x99\x94%T\xeb\x96\x9b\xdd\xcaq\xab\x14\xd4\xd2j?\xcf\n\xe9\xbe\xeb\x99\xa6,\xe9\xe1\x1d\xd4\x93\x80\xea\xcb\xde*)g\xeb\xaf\x8d\x94\x9d\x9f\x14YB\x11\xae\x01\xbb\x8b\xf8\x10\xeb\xd4\x1b\x1f\xeb\xdcXo\xeb\xb8\xb5\xcdX(\xbda\xeb\xfcrI\xd9p\xd2Le\x82\xf3\xc9\xe4\x1bO\xb8\xec\x12\xb7\xad\xfc\xbb\xd0\xdf\x84\x11\x04D?\xcey\xb3\xec;\x87\x93\xbd\x9c\x9c\xe1c\xb4w\x80:\x08\xe8\x9f\xec_\xcb\x97\xa6C>6\xedg{\x8e\x16\x12re\xecc\x1d\x9f\xaa\xce\x17\xc9\x19@t*\x87\x13\xb8k\xecf5\xbe\x883A\x93j\x96\xfd\xcb\xc3)\xbd\x1f\xeck\xd5B\xb2w\x0f\x04\xf0_\xcd\n\xea\xf4\xff\xa9\xecn4\xc2@\xb6\x19\xed>\x92\x17\xcf\xc2\xe0\x87\xec\xecq\t\xb9\xa2&g`U\xa8\x96\xcf}"(\x11\xec\x8e\xd8~|4m\x8a\xa3"\x97#\x1b\xe3\xf8$\xec\x91\x1f\xedh\xf4\xc6g\xf2\x919{.Us\xf4\xec\x93\xf8\xd3\xf5\xdb\x10Q\x1d\x9a\xf9\xf7\x1c_>\xe1\xec\x99\x98\xaaX\xf0\xd8c\xd1ma\x0fI\x82"0\xec\xa8\x8e=\x923L\x91e\x82o}\x02\x84\xf1H\xec\xafm\xb3M\xf9\x81\xc1F\xb8\x1dH\x1fus\x04\xec\xcd?\xaf\xb5#9\xd3\xf9L\xa0E\xbd\xb7\x83\xc1\xec\xf3\xd2\xc6p\xfe\xd0\x03t\xaf\\{\x80MYY\xed\x17 \xd0xs\xd9\x823\x812\xcb\x89\x96\x955\xedB2\x9c\xeb\xac\x18\x9f\xf9\xa2\xad\x80[\xa6As\xedZ\x92n\x04\x1fk_\xb1\xbf6EVGt8\xedj \x187\xc0k\xf4A\xcf\x9ew\xf8\x05\xe9\xa2\xedz\x151\xed\xd1\xe9a\t\x1b\xb7\xcf\xa0/C\xe0\xed\xabd\x92\x8bQ!`\x89U\x9f\xc99w\x03\xab\xed\xaf\x18\xe6|\x96x\xe5w\x15O\x7f\xd85\\(\xed\xbcKA\xb3\xe0\x1a\xad\xda\xb2W\xd7np\x0c\x87\xed\xee\xd3\xbf\x9dc\xe5i\xf1 \x0e\xdb,\xce?\x0c\xed\xfd\x8f\x0c\xa8\x00\xf5\x1e\xeb0I\xb9\x1fS\x8cj\xee\x04\xceNB\x04*\xaf-\x85\x98-u2\x979\xee\'\xc0P\x9f\xd5\x17\xb3\xf3\x0cs\xe7\x02_\xb3\x81\xeeu\xf9\x98\xb5\xc3r\'Di\xba\x10\xc1]U\'\xee\x87\xf7\xbd\x99|(\xec\xcc\xa1\xcf6\xc2\xe8_\x83\xee\xa9\xa4\x7f=\xa7S\xb5oBv\xdb\x9d\xb1\xc4\xf3\xee\xc7"\x8c\xac\xbcn\xb1\x8c*5h\xd7UL\x94\xef\x05\x03L\xd4l\x85\xb8\x1f\xe5\x133\xfcf+\xf1\xef\x1e\xde8\xa4\x94W\xb9\xda\x94\xfd\x0e\xf7\xd2p\xcb\xef\x97C"2\xb3\x83\xc0\xc7\x1d\xb6\x82\xce[\xd5C\xef\xb1y\x16 \x8bz\xf6\xf0z\xf7\xca\xe5\x87\xc4\xf9\xef\xe5\xd2F\xea\xe9Z\x0bq\xfa\xdb\xd2\x0f\x94\xb8R\xf0\x0f\xff\xfa\xb5\xfc\x07\xc6\xac\xba\x94\xa5\x98\xe0\x0c0\xf0\x13D!z!`\x01\xc1qm-8\x7f\x93\xb4\xf0\x15s:\x06)K\xdb\xa7\x0b2\xb54Z\x05\xd5\xf0*\xa4Cmb\x89\x15ii\x8f&!\r\x8a\xc8\xf0+`1\x007J\x8e\xcd\xefP7Y\xfe\xb7W\xf0H\xea\xa5\xd9\x9a\xeeX\t\xab\'d\xa9\x9a\rx\xf0NL~\xb2\x89!\x8b\x1f&{\x11\xee\n\xfb\xf0\xf0R\xdcG!\xcc\x19\x7f\xb3/\x18\x90\xa4\x9f\xae\'\xf0_\xd4]F\xed#\xf3.\x9dD\xeaG\x0b\xf2\xfc\xf0o=8\x01\x8e6\xcdn\xf7\x811Q-=\x9c\xf0p\xb1\xb9\xb5b\xddA\x9c\xcc\xcf\x97\x87\xa9\x1d\x8f\xf0\xa2\xc2\x8b\x91|\xcc\xa6\x8b\xc2\xcc\x1d\xe9\xdd\xf4_\xf0\xbb\x18S#\x00\x1dOG*7\x07\xf3[-\x8e\xf0\xc1\rM\xa5\x8e\x1d2\xce\xe8X*5\x1fc\xd4\xf0\xc3,\x1b\xb6\xf22Z\xaa\xfd\xc7\xfe\xb3g\xc2Y\xf0\xfb?0\x8b\xdcG\x9e\xb0\xf7J\xb9k\xe1\x10\xc5\xf1\x01rD:3\xa5\x95\x9b\xe0\xadB)\xe4\x10c\xf1\x0b,\xe9<\x0fG#bFV2c\x8c`\x1f\xf1\x15%`\x92\xa3L\xdf3\x95\xb6;\x95\xef\\^\xf1+\x03nt\xa7\xba\xf2\xde\x00f\xdb\xd2q2<\xf10\x95\x9b\xb9\xff\xfb\x8e\'\xa3D\xaa\xdb\x0b\xf2i\xf1N\x18Q\xfeK!\x96\xec\xfb+3I=`\xe3\xf1V\xab-\xaf\x03B9\x16\t\xaf\xb0\xd1H\xec\x95\xf1\x8b\xde\xb44\xb9\x80\x1f\xae\xfd\x92#\xbf\xa2\x15\xa2\xf1\x9d\xfb\xaf\xd5\xf7\xc24\xc5\xc4\x8f\xd3d.\xd2\x87\xf1\xd5\xed\xb8\xba\xe6B\x9e8\x1f\x17\xde~r.u\xf1\xda\xe1d\x97\xf7\xf2\xf0\xf7\xf0E\x94\xaf\xbc\xa9\xe0\xf1\xf5\x89\xd6k\x9c)\xd9U\xcap\x86\xe2\x9bb\xed\xf2\x15\x87\x0e\x16\xea[\x92\xc4\x19\x16\xd5X\xbd\x05^\xf2\x1d\x16\x02\x9d%b\xb2\xcf\xad\xec\x94\x86.\xbb\xaa\xf2KN7\xd1\x0f*\xd8\xac\x84\xa3\x8cS\xc9\xb3\xfa\xf2l)\x0c5\rY\xb6\xab\xc2\xd7\xfb+%M_\xf2s\xa2\xb9*\x04\x80\xe8\xab}\\\xf4\x85\xfe{C\xf2\xf3\x99Z\x18N\x881\xf8!\xa7w\xad\xc0\xf5\xb2\xf2\xfe\xbe\xe1Nn\x1b\xef\x93\x8b^\xa7\xab\x8e\x81\xe0\xf3O\x15\xf1\xa2\x07w\x92\n\x9d\xde\x1f\xe9c\x81\xe7\xf3~\xbeB8\x1f\xb9f+\xfc\x99p\x02,Z\xa8\xf3\xa7\xc5P\xbd\xaa\xacm^\x94\x17\xc9Z{\x98\xbb\xf3\xac\x04;\xd1\xd0\x83\xc1s\x1e\t\xda\xab\x8c\xed\xa7\xf3\xb3\rm\xff\xda\xb4C\xbf\xc7asi\xc5\x97{\xf3\xbbv)\xb7_\xc5\xd7u\x043\xf5\xd7\xc208\xf3\xbd$\xac\xa6\x110d\x1b\xf2=\xa3S\xe9Q\xd9\xf3\xc3\xf9V\xca\x12X\xb2\xd9\x0c\xe6n\x8d\x86\x17\x0f\xf4\x14P\x04\x92\x0b%\x8cK,\xfe \xe6\xc5\xdc\x9d\xf4\x1fW\x81A \xbahn\xf9O\xf2\xc8\xf2=\xee\xf4*\xb2E\x94\xe7!<\xb0/\x0e\x98\xace?\x9b\xf4,\xd9<\xda*kp\x0bF\xeb\x9c\xf7t\xdf\xef\xf4.]b}\x00\xdc\xd2\xed\xc8\x83vV\'\xb9\'\xf47\xa7\xa2\xd0u\xff\xf4\x87\xa7]\x8a\xe8^\xfbE\xf4>\xfc\xe2P\xf7\x86T\xb2\xdfNZKO\x92\xbe\xf4M\xfc\xdc@\x8a\x17_\xac\xa6\xa6\xe1\x9c\xa7sq\xf4x1\xe8\x9b\xd8\xd1\xd7\xaf\xf3Q\x14\xb2Tq\xcb\xf4x\xf9\xca\x00\xc7\xbe\xb8:\xba\nD\xa1\xb5[\xfd\xf4\x8f\xae\xae:tl\xcc\xc2\xbb\x97\x1cl\x01\x8a\x06\xf4\xaeW\x176\x01\xdf\xd4$=\xc3\xe2\xd5$.\x07\xf4\xdc\xdc\x12K\xc7\x7f\x9d\xe5\xd7\xe7\x0c\x7f\xa9u\x8f\xf5\x02SK\xe0\x10\xb0\xb0I5\x084\xd7\x8f0s\xf5\x15".\x10\xda\xbf\xb3O\xc9\xee\xad\xcd\xf8\xadH\xf5\xc2\xffT\x95\xdf\x15\xb2\x86-\x87\xb4/=\xf1\xba\xf5\xd9@\x03\x1b9\xe4\x92\xc2q\xe3\xf8\x91\xd1z\xfb\xf64\x97n\x05\xdc\x05\xb7/\x85\xc6Q\xa1\xa3\xa8;\xf6B|\xef\x9d/\\!\x1dW\x88\xc9E\xd8\xf9o\xf6[5\xc9A\x91\xbd0\xa7\x90U\xceK\xe5+v\xf6s\xc5^M9\xb7|\x05\xac\xb6\xe8\xbeS\x92\xe6\xf6\x97%\xc0ZFm\x02\nZ\x9a\x1d\xaf@\x06\xdc\xf6\x9f\x81\xee\xc2j\xb5\xf1!\xf7\'\xf0\x02N\xf9\x8e\xf6\xa4\xb3\xff\xe6gHy\x8c\xacW\xec\xfaj\x02\xd2\xf7\x0fL%\xbb&Q\xb1\xb1\xe8\xd9\x1bV\x86\xb9\xa0\xf7f\xe7\x0c\x19A&^\x05\xfc"*\xe2\xb5H\x19\xf7h\x8eP\xb7\x1c\xb6\xfd\xb3C\xddVD\x8b\x03\x1f\xf7\x89\xe2\xe3V\xf5\xb8\x05}\x10\xe8\xfaKJp/\xf7\xb7\x16\x80\xcf\xb0\x19\xec3\x1cD\x94\xa7v\xed\r\xf7\xd5\xfd4e\xfe\xd9\x10#\xc2pG\xa4\x06\xab*\xf8\x031P\xf8y\xa5t q\xfa)\x94\x13\nH\xf8\x08\xf8y\xc1\x0c2\n\x03%\xa8\xae\x8f\xca\xcc:\xf8\xa5\x13\xdc\xc0\xdb\x82\x1f\xc9\xba\x08{\x9d{\xea\xc7\xf8\xfbv\x10\n\x1d[\x0b\xec\x0bgd\xe5\x91\xbd(\xf9$l\x0b;\x9e\x14x\x94\x08\x14\xed\x1c\x1e\x89q\xf9nH\xb4c\xf3~\xf1\xe8\x1c\x10\x88@N\xc5j\xf9o7\xb2\xd8\xf9\x96\x80l\xfb\xfc\xc2aB\xbb\x1c\xf9{L,B\x951\xf0g\x0f@aU\x80R\x1b\xf9\x8b\x19\x18e:4\x1e\x8d@\x89\x03Y\x1fCW\xf9\xcb\xc5\x1f\x8a\x84\xa2\xadO\xcau\xbdG\t\xfcM\xf9\xf41\x7f\xc8T\x0fk\xf0\xbep\xa4\x8e\xa2\xac\xc3\xfa-\x18>t\x17\xe6\x07,r\x14\xf3CbZ>\xfaB}\xeca\x89\xf4+3\xf0\x0e\xc8\xads\x11\x93\xfas\xf6\xa1H\t\x92x\xec\'\x82\xe4m\xad\x10\x00\xfa\xa1c\xcb\x0fv@<\xf5\x04\xf8\xc9,f\x05Q\xfa\xc3>GU\x16\x8bK-i&!@|O\xb2\xfa\xd7\t\x9c\x18\x83\xbf\x90\xbf\x13E\xe9\xd2\x14u\x99\xfa\xdb\x80\xea\xf3\x9f\r\x97\xc9\x0cm\xda\xee$\xf8E\xfa\xef\x9d\x9czx9\xba_\x06k\xd8M\x17\x89\x1f\xfa\xf34h\x8c\x1c\xd5\x0f\xee\xd4\xa4\xb4\x84\xf3)q\xfb\x050\x80\xe4nI\x83 \xaaf\x91\xa4\xbe\x87\x95\xfb;5\xbc\x85\x86\xc0\xe0\xcfP\x9b\xa3?\xf8\xf9}\xfbJk\xc2;1\x0f\xd9\xdc\xb3+\xf8-\x89N\xf7\xfbLz\xe5\x08Xr#\xebL\x0e1\xd3q=\x8d\xfbM\x8f<(\x80:\xfbh\x84$T\x93)\xad_\xfbi\xdc\xeez\xcd\xe4\x07\xc5U\x96\xf0D\x13j\xa8\xfb|\xa4V\xde\n/\x05)\xd1\xb4\xa2o\x12O\x88\xfb\x9c\x19L\xe2d7\xedf;\x849c\x95\x06q\xfb\xb9pM\xd0?\xb9\xd0l3\xb4\xf0V7\xba\xfb\xfb\xc5>M\x88\xdb\xdc2\xd9\xfd4\xef\x0c\xd5\xd2\xce\xfb\xdc\xacG\x95\x10\x10O/\x05o\x1e\x1b\xdb\x9a8\xfc\xaf\xaf_)\xe8\xde\x95\x0c\xad=u\x94p3\xad\xfc\xca$\xc9a\xa1\xad\xdc\xaf\x1c\x8e8\xf9\xd9P\xac\xfc\xe6bG\x88\x1d0\x8dE\xcd\xab\xbe\xe7\xbb,\xfa\xfd&\x9a\xc0\x96H\xedM\xc7W\x04\xec\x0e/2\x06\xfdm\x89\x06\xb4r\xe2\xd3\xdc\xe0\xe1\xab\xb6\x83E\x8c\xfd\xaa-\xde\xac\xa4\x1a"\x83@\xf7\x96\x9fFy\x8b\xfd\xe3ejj\xd2:7\x8aM\x90)\xacD\xd5\x11\xfe\x1ev\xed\x14\x00\x15\'\xc4Cb\x1fzb\nL\xfe4&\xc6\t\x06\xd4"7\x97+>_8Mt\xfeW\xf8\x81\xda\x01\xe9\xd4\x12\x15\xfd\xed^\xd5kV\xfej\x84U\x02q\x12\x16\x1b7\xa6\xa4\xca\n\xfa\x1e\xfeo$\xc4\xba\xcdi\xa8\xcb\xf9\xefu\xef\xa0\x1a\xc5\xfeu\xc6P!9\x98X\xc8\xd7i\xacVv\xba<\xfe\xc1\x1d\x17\x17\xbd\xad\xc9@\t\xc3\xa2\xd9\x91iv\xfe\xc6\xb5\x0b\xc1L\xc9\x90\xdb\x9ff\x00\x10\x14[\x1c\xfe\xce \xfa\x85\xa2\x98\x1d*\xbd\xa9\xa4\x10=\x1d\x81\xfe\xd3\xc0\x0c\xbf+*DR\x9a,\x84\x122\x06\xb4\xfe\xd4&|\xd3\xe2\x948\xf1\xfb)\xe3\xb9\x91\xcbQ\xfe\xdc\xaa\x02$\x1b\x9fXl\xc7\xe5)q\xa8\xe5\x88\xfe\xe8\x98\xbaT\xb0\xa9\'\xf9R\xadUNe"\xa8\xffP$\xe2Dq\x069$`\xe8\xff2Y\x06\xd8\xffU\xca\x96\x8dz2\x02\x87\xb8\x9f\xa0x\\M\xb9\xffwC\xfaH\x8a\x06\x7ft\x88\x7f}X\xbe\xe9=\xff\xe1\xcf\xb6\xd2\xa2\xf5\xd9\xf5\xdeCX,\xbe^\x9b'
\ No newline at end of file
+url_hashes: '\x00\t\xb6\x80&\xf4(\\r<+_4\xe5S\xa0\x00\x0c\xa4\x11Nt\xed\x84\x99*HO5\x88\xcf*\x00\x17\xd1\x90\xe0\x82&\xbc\xb5\xd4\x11\x1e\xcf\x07[J\x00g\xc7x\x17\xde\xc1LQ\x87\xa3\xb6\xb0@@\xde\x00~\xe3\xb7\xdb\x9e\xd8H {U#Q?y\xa8\x00\x9c/8\x83U\x8e\x98\xa2H\xba\x11\xae\xb7\xad\xfa\x00\xaa\xb4[\xbc\x7f\xa1\xbe>\xda 9\xc7\xe5@.\x00\xd7E\xbdCm0\x13\xa3\xee\xbf\xb7H\xf1@\xcc\x01\x01\xa5#/q\x8f`\x1dI\xd4u\x08C#f\x01\x1b\x97\xdd\x04\x96\x1c\xdb\xf8\x82\x9f\xd1F\'\xf8\xb1\x01rr\x0e@\x8e\x9aw\x06\xc9\x81F\xf7\x06\x82\xe5\x01\x8e\xc4|=\xf5\xee\'\xc0\x96\x18\xc7}\xc1\xe9\x92\x01\xe2\xe0\xd4\xa7\xc9\xdb\xf0r\xd1:\x02\xb8\xb8k\xb2\x02\x13\xfc\x17o\xaa9 \x9b\xda\\\'\x0c\xb3\x94\xfb\x02J\xd6\x00@!t=\xf8\xdab\xc6\x8f\xf0Q\xf4\x02Sx\x1a\xb6W\x07\xf8\x8a\x87\xfe\xacv\xe4>7\x02\\\xa1tY\xfa)i\x92h\x1b\x91l^G.\x02\x9c\xeb\xfa\xc7\x94\x85y\x9b\xdd\xafd%\x93\x15\n\x02\xbf\xf4b"4\xe72\xe6O"\x89\xb5g\xa7N\x02\xca$u(\x17\xc43z\xad\xde\\\xc8\xca\xb6l\x02\xee\xf2\xa5\xd4\x88\x16%,\xa6\x10\x9b\x1dYw\xec\x02\xf0]\x06\x0fC\x16!\xc7\x86\xa1?\x03Ob\xe2\x02\xff\x13e\xe7\xaf5\x8bZ\x17\x0c\x117\xf2\xac\xe3\x03\x15\xa3\x12J\xb9\xfc\xcf`\xab6\xb5\xf0\x15_B\x03\x1fX\x16`Q\xd0\xd11\xfd\x95v\xa6\xb6\x8fP\x03I)\x11\xc0\x01v\xfe\x95Ox>\x12\xd3\x85\xdf\x03y\xd1q\xae\x1ar\xedPkv\xb6\xa6\xb2\xb17\x03\xeb+\xb2\xbc<\xc6(\xe36\xbd\xcfFI\xbb\x1f\x03\xfd\xf9\xed|\x90\x0f\x12K7\xfeQ\x88\xc6\x95\x11\x04\tr\x02\xa0`\xd1\x8b\x18/\xda\xafE\xdbk\x14\x04\x0b\xd8-\xd7|\x1e\x06\xff\xd5\xa9\x06I\x13\x935\x04\x1f\xd7`\xb9I\x17\x99\x8ff\xf6\x01\x86\xd9\xd6\xcb\x04/\xcbc\xf2Ew\xd1\xbb\xb6%3)\xc4\x18Z\x04BuI\x9d\xe5\x80\x83\xdeF@\x10J@\xff]\x04e\x95\x8d4\xb4\x16\xc9fs\xec\xdahD\x8b.\x04h\x90C\xe3\xb0\xb5DPA0\xbd\xa7\x9c}5\x04\x86\x1bi\xd8\xad\x88\xae\xb1\xcf\x1c\xffd\x89\xda\xce\x04\xb4\x17\xde\x81yx\xb2c\xc7a\xfc\xe0\xce\xfbv\x04\xdcb\x8acQ\xeaiJ]\x01\x12\x14\xc0\xe4\xbe\x04\xff\xa7g\xe8\x02\x0f\xc0\xa5\x0bO\xb7\xdb\x02W\xd1\x05\x15\xc1\xa8\'V\x0b\xf7_\x1f\xba\xaah\xc4+\xf9\x05!\x1c\x13\x17\xa97O{\x11\x12\x10\x98\xa4^\n\x050\x93\xde\x97r\x7f\x19d6Q\xcf\r\xd7E\xe5\x05\x98\xdbe\xd4\xb6\x8a\xfb\xbe,\\s;\xcaL<\x05\xd2 \xd2\xdf@D\xe3\xb8\xb2\x88\xef\xab\x98\x8c&\x06\x0b\xf5}\xbe\x98Y\x9e\xcbJg\xa4\xe5\xc2o;\x06\'(o\x8ci\xf9\xa1\xc9\xe3\xe8xVn+\x15\x061\x1d\xabG#\xac\xbd\xf9\xb7\n\x84\x94b\x11\xaa\x06BM\x1doe\xebL\x83\x13\xd5\x1c\x93)\x1cv\x06n\x83\xa3tpKq\xec\xa4\xf6N\xb1\xd8\xb4\x9d\x06\x8c\x8fc\xf05\xf8\xc5\xd2\x1e\xd5\xab\xcc\x1a!\xbb\x06\xbc\t\xc8\x8c\x8e\xe0\xf7\xd9\xdd\x94\xc6I3n\x10\x06\xe2\x00o,\xb4\xfc\xc6\njb\xa4"\x1c#\xd9\x076\xb9\xa5w@\x1fV\xfc\xffp>\xc4\xdd\x1fS\x077l\x8a\x90\xad\xded\x14I{?V-\n*\x07RU\xf9\x13\x17J#r\x10\xec\xfeU4Z,\x07}\xa0z\x1f\x9d\xbc\xf1\xceB\xdc\xec\xcd)\xc3\x80\x07\xa2|\xdb\x8f$9\xb6\xca\xef\xa1^vl5\x87\x07\xcf$\xc6Z\xf7\xb2\x0f\xe6\xe9:`\x145\rZ\x07\xed\x04,\xb46\xadcM\xc1_3b\xe6h\x92\x08\x0f\x9e\xacN\x05N\xa3\x9e\x97 b\xc2\xfe\x9e\xd7\x08E\xf8j%\x85\x1a"A\\I\x91\xdd\xdbt\'\x08L\xacG\xdf\xdc\x87\x84\xdf\xa5\xc3\xc4N\xe4(\xbb\x08\x86\x0b\x00\xe2\xa3\t0\xaeyt\x8d\xf9\xe9k\xfb\x08\x9f\x05\xb9\xe9\x92\x9bSV\xc1\xf8\x13\xc4\x88\xa2K\x08\xc2\xb6\x1f\xc4\xeeCN7\xcd2\x17\xa6\xc0f\xad\t\x17mB\x19\xd7;\xde.\xf6\xf2q\xb0+\xf3\xeb\t-7\xda\xfb\x8b?\xc2\xf2S1\xd1\x11\\KD\teC~a\x94$\xd3\xdfJ=C\xb2\xed\xa1}\ti\xa4\xf3{Nq\xba\x88\xd3\xc8\x8dg\x98{\xde\t{|\xf24<m\xfc4R\xa8\xe0\\\xd6\xd7 \t\xb8u$.V\xc0OQ.\xbd\xe3\xc6N\x82\xfb\t\xff\xd2\x9d7;\xf8WnQ\x0c\xd6>)_\xd8\n:\xf6M\x07|*l%&\xe5I\x11\x8c;%\n\xa9\xc4\xba=\x99\xf4\xfc{5S\xd4k\xb9wg\n\xabS/\xbf\'\xf2\x02#2\x05\xd7*\xf0\xe8\xa3\n\xb4\xc07\r,\x03M1\x04*\x81\x9d\xb2U\xc5\n\xe1\xb4Zx\xf4\x0e\x8b~\x89(D\xe5\x81\xc8\x80\n\xe8\n\x82.Y\xbf\xc7\xa9\xeb\xba\x90\x1f\x1f\xe1\xf3\n\xe8\xa2\x1c\xcc@\xa0\xe4\x07\xb34`8\xb9\\\xe4\n\xf3\xba\x94<\xc1\xbe[\xa9\x9d\x98\x05Q\xd4\x1e\xec\x0b \xe2\x99\xf4GYy\xa3\x9a\xach\x0c\xc7|\x94\x0bD\xce\x15\xc4\x0b\x18j\n\xd5kfL\xa5\xaec\x0bR\xad\xbf\xd3\x9f\xd6\x12}\x92M\xce\x84\x9f\x94T\x0b\x91\x9em\xe3\x1c$]\xb8\xadx|t\xd2\xc8\x02\x0b\xa3:\x03\xaf\x95\xed\xe6r\xa4]u[\x95\xac\xbe\x0b\xd9\x8a\xf7w\x82T\xaf\x9f\r\x95\xe0\xf9\x0c$\x02\x0b\xf6G\xe5r\x80v`pey\xf6\xffB\xe3:\x0c\x03\xee\xb8\xb0\xaeQN\x9a\x12I\xe4\xac\xd8\x12\xcf\x0c\x07\xe5n\xd2I/!/I\xc5\t\x0f\x13E-\x0c\x96f\xfeB\xbb\x03\xe8\x90f\xa2N\xfa\xa3\x1a\x80\x0c\xac\xb0\xdbg\xa8\x9e\x0e\xe3v\x11\xf6s\xfb&b\x0c\xc40`g\xee\xbe\x84\x81\xdaZJ\xde5P\xa6\x0c\xd2\xc1\x9d&A\x81\x17\tL!\xee\xfb\x02,0\x0c\xd8v\x93{^\xde\n\x1b\xb72\xf9Q\x9f\xfbF\x0c\xeb\x91\xbb\x00\xa7\tf1\xd0R\xd1/?\xb46\r\x18\xfb\xa4\xa52Y3\x07>;\n\xf7*\xe8$\r:T\x8b\xa0O\xd9\xc7\xf3\xd1\xf3\xda4T\x84Q\r@\xde5\xa3\xe9\x8b\xe36^\xd9\xe7\xaay\x10\xec\r\x89\x1eW\x87v\xc8\x06Ku\xa9\xe4T\x04Z\x9f\r\xdc\xf1O)\x0cd\xf1\xe1\xd6\xa4\xf4\xf4E/;\r\xe3|\xfc\x95\xa8\x10\x93A\x92,a\xa3\x95\x0cp\x0e\x15\xc5\x97\x99\x01e\xf4K\x13\x8f\x08\t\x0f\xe4\xa7\x0e\x16M\xa8\xfbE\xa5 ~\xc5\xa2F\xaf\x82\xe1e\x0e\x1d{\xb1\x81\xb4\xf1R\x82\xd2\xfe\x1dL^\xc3\xd9\x0eE\x1a\xba\xbf\xb5\x9d\xbf\x93\xa6\x9c\xa2\xbe\\\xdd\n\x0er\xc8z\xb9\xc3|\xc9\xf1\xd1\xdb/5\xac\x98\xca\x0e~\x91\xb2g\xed\xb5\xdaq)\xe2E\x12\xfe\xfb\xd8\x0e\xc2j\xb4e\x03e\xed\x91\xe0\x8evEE\xd4\xf4\x0e\xd7\xfc\x06e<\xce\xfbS\xb9z\xb5\xa8\x9dE\xa9\x0e\xdd\x7f\xc4T\x90\xa3\x00\xf7\xba\xc8$l\x8aQ\x98\x0e\xf1\x1fK\xd2;\xc3&\x9b\x02\xc4] \xad\xafk\x0f\x07\xfd<\x1c\xf9\xb1\x93\x9dzIN\xd3;^\xf6\x0f\'\xc1\xef4j\x0c\x1a\xe2]\xd3\xe4L\xd1#9\x0f*\xf6D\x86%\xf9\xa3\xfd/\x81JnR\xc4H\x0fGlb\x019\x03rv\xec6\x08\x88\xd8\xcd[\x0fU\x81\x18 \x0c\xc2\x02#\xcaY\x8e\xc9\xbf\xd4|\x0fl\xc9\\\xf6Xh\x7f\xb8\rY\xd8\xb5R\xf6,\x0fv&\xa2\xabM\xdb\xc8\xdc6e\xda\xef\xd7\xb8\xb1\x0f|T\xb0E#\xf0\xe0\xef\xf1\x91\xfbA\xf1EW\x0f\x92mzN20\x948\xeaO>\x9d\xa9J\t\x0f\x93\xbc\x8e\xe2\x12\x9fV\xef.Z\xe4N\x00k?\x0f\x97\xd7X\x9e#\xcbL\x9a\xd6E\xfa}HB\x07\x0f\xdf\r\xc0\xeb\xf3\xe6\xe5.|\xf7\x1calB\xe1\x10\x11\xde\xd0F\xb1J\xd0R\xd0\xb4,\x846\x19\x83\x1072\xf2\xe1\x9d \xf25\xa5\x8b\xd1y_\\\x01\x10o\xc6\xea8\xdei2\xe3\x9f0\xe6\x87\'u\xca\x10\x80]W\xeb\x0eP9_\xfe\tKV\xe5v\xf6\x10\xa2\x1b\xac\n\xe0\xf6\xc6$\x94\xff&^*\x11\xa0\x10\xcf\xa6\xe7\xd5\x95\xfe%\x05\xa5zeRK\x0c\xb8\x10\xde\x1dJ\x01\xf5\x0c\x1e\xbe\x8b\xcb\xc9\xa1g{\x9c\x10\xf4:\xf53:\x81z,\xe5 z\x12\xf7\x9e\x90\x11\x16\xccb\xcc\xe3\xe6i\xe4"\x17\x89\xfbVD\t\x11\x17\xd6-\xc5\xb6\x85\'\xec\x06[nI\xa5c6\x11(\x89\xf1\x85W\xe5\xeeUL\xa0\x80\xf1\x1du\x11\x11,\xb3!Q\xf6\xd6\xc3\xa6\xfa\x90\x0c\x8a\x85\x9f\x8b\x11D\xab\xa9T\xec\x13i\xd3T\xa1s\xd7\x97\xe1\xe6\x11PP\xec3l>J\xca\xf62\t\xbf\xc2^s\x11Z\x8d\xc2\x0b\xd4\x94\xfav\xd4(5\x81;\xbd\xa3\x11\x8c\x7f\xb1G}<\xd2.\x1f\n\x02\x1e\x01!`\x11\x8c\xc7k\x8e$~\xe3\xa3\x16\x07W\xacM\x02\x0c\x11\xbb\xff7\x03\x12\x0b\xc90\x8c\xfd\xd6\xbe\x11\xaf\xc8\x12\t\xa6\xfd\x1aI+e\xa0\r\xc9`X\xf8\x02\'\x12\x0f\xdf\xd3z\xc3\x8a\x0e,\xad\xac \x9b[di\x12\x1e\x86\xe1=J*\xb9\x9a[\xee\xc9\xcf\x9evh\x12)\xa6?7C\rBuA\x1e\xae\xc5\xf4\x00R\x12\x9e\xc6,r\x96m\xcay~\xc8\xd9\xad)n\x9a\x12\xa0\xf0&\x83\xfb\xc0\xdf\xaa\x15\xec=\xc6\xd4\x9b\x13\x12\xb9~\x98\xa0g)g\x152c\x1cb\x8b\xf5r\x12\xd3\xe3D\x81\xc1\xe0\xa8\x96zy\xeeC\xe8\x1f7\x12\xde\x06j\xab\x01\xc4\xc1\xa5\x89\x83\xbf H\xe3\xb6\x13\x07\xd0\x03\xd1\x95\x1b\x8a?\xe0x\x14\xf74\xe6\xd3\x13\n\xb1+\xf7\x7f$\xe5\xdf\x08\\`\x96\x18\xea\x02\x13\x11\xf2\xda\x08\x938\xf0,\xce\x03"e\xd9\x10\xdf\x13\x1cg\xee\xa5\xaf\x94\x1f\x86\x1a\x16>\x0c\xb7\xeaq\x13L\xddd\x1f\xa2\xac\xde\xf9&\xce\xf3\xed\xe0K\x1a\x13g\x1f\xe2\x1c\xeb3\x8e\xbd\xb9\xc1\x0c\xa4\xa8\xf6s\x13heV\x13\xa8o4\xa7\x91"F\xc9\xd7y\xa7\x13\xa4\xbd\x1a)\x81\x9d\x19\xe9\xf3\\0\x8d\xa3\x8d\xf1\x13\xd1\xa3]\x90g\xf3t\xcf\x88~\xb6\xadn\xb7"\x13\xd92\x00\x07*x\x9fS`\xffNv\xa3\xb8W\x13\xff*\xc9nX\xdd9\x90-+\x95\x84\xa8p\xaa\x14:\xa9\xd9A\x06$\xfb\x80\xe7\x87^4\x02\xc2\x93\x14d\xf3\xfa\xe6Q\xd5\x1b\'\xefz\xf9Ao\xf7\xe0\x14j0\xc6\x88\x95u\xd7\xe6\xb9M\x187%\x91\xe2\x14\x8b\xaa\xf5\xa7\xe6\xadj Z\xf6\xcc\xf0]\x00&\x14\xa3\x153\xa1R?C\xe0\xa4\xf7j\xb8\xed?x\x14\xd29\xed\xb6\xfe2\x9e\xfd\x1b\x80\xad\x9e\t\xae\x1e\x14\xd5\xd5\x8c\xe6\xe7\xfdo\xf4*\xdd\r\xddY\xb3\x17\x14\xe9\x7f%Z\xab\xe1R\xaeL\xea\xf4a,\xe1\x17\x14\xf4\x90\xcb\x9f7\xfa\xe7\x9eG#\xab\xa0\xd1u\x94\x14\xfe$\xa6\x9a[\xbf\x00\x96\xc6i\xbc\x1d\xbe9z\x14\xff,\xdc;I}\xd7d\x9e\xa6.X/\x83\xef\x15h\xf5%d\x12%\x89\xac+|h\xf8\x19X<\x15s\xb9\xeeh0\x97\x90!GI#\x90\x13M\xa8\x15\xb7\xeaF\x8d\xea\xb1\xf9\x99\xde"B\xd9\xed\x11\x9b\x16\x1a\xd8A\xe0RU\xbc\xdc\xe6{\r\xa7\x18 _\x16P\x9bi\x94t\xd4\xf8D\xad\x8e\xb7\x7fH(\n\x16m\xaf\x9f\x95&\xd2P\xa0\xdb!\xcdl_u\xb4\x16q\xfe\x024y@\xed\xdb\x88X\xbe|\x93\x93\xc0\x16s\xa5gI\x00\xeb\x13\xf7\xba\x1dgl\x87\xea\x08\x16\x83\x87\x93&\x8a\x08\x9c\xb1z\'\x85n\xd6A\x13\x16\xe0\xf9\x17-\t\xf5\xfb\xe9\x92\xc5\xad\xbeb\x05S\x16\xef>9\xa8\x82\xdea\x01j\xec\xa5R3\x05\xb5\x17\x05\xc1}\xeb\xe9:\x15kd\xebtl\xa9z\xd7\x17\x17}\x12\x93\x10\x1f\xf2\xf7z\xb3\x13\xe2\xcdt\xe2\x17DX\x03-\xd4\x14tDO\xdf\xa0\x8eP\xfa\xdc\x17N\x0b\xd9\xf7\xc0+?\xa8\x9e*\x1c\x9c|\x80d\x17R7#\xe4\xa0\xd3X\xdd\xec7\x03r\x7f\x98\n\x17f\xb6o=\x8e\xba\xe1\xe9pZ\xb4-\x17N7\x17w^\xeeq\x91\xa1\x7f7\xe0\xf9\xb2\xe6E\x99\xa0\x17\x8f\xcd)\xe8\xc7^&\x97\xdc\x1dX\xbc\xd0\x9f\x92\x17\xa7\x98\x17\x85m\x99\xe9\x9d\xc8\xc5e\xd7\xa5X\x95\x17\xb8\x85\xc0dr\xaf\x90\x8fk\xc0\xe3\xb3\xeb\xa9#\x17\xc8iU\x1d\xa8\x8c\x95\xf8\xa9\x11\n\x02\x92\x17S\x17\xc9q\x1a\x87\x1fd\x94\r\xb6q6\xfb\xf8G2\x17\xfb/\xa1X>\xa0P\xe1\xb2G\xd1\x0c>8\x00\x18\x01\xb3R\xb2\xc2\x03f*\xa7P\xa5\xe1\xb1A\x9b\x18\x062X\xd6\xce\xd5\xa3\x88G\x91\xa9\xf2\x1f\xdb\x8d\x18\x06<\xb52.\xab\xdc\xb5\x87\xe3GfDz\x0c\x18\x92g`\x90p\xf0\x9b\r\xe0\xa8_%Q\xc7-\x18\xa55\n\xde\x95\nv\x9c\x1d?S\xba\x11\xf1D\x18\xe5\xbd\t\x0e\x04hj_\x03\x01\xcb\x82\x19\xff\xd9\x19D\xa6\xc4\x11\xb6&\xec\x81\xab<fPC\x04\x1f\x19\x81\xde\x0f\'_\xa9\xe0jI\x16\xcf\x86\xc6\xdf{\x19\xa5\x99,\xdf\x1d:\xe8\x1e\x19UT\x0c\xb1\xaer\x19\xcb \xe5*P[R\xae\xbb\xa55\xa5^\xa8\r\x19\xd3.\x82\xf9\xafu\xee~4h:\xd2\xa6T\xaa\x19\xea\xe7\xee\x93:\xd4Ce\x9bb\xf3\xe2"?\x06\x19\xf2\xc4\x9eX3\x82Y\xb9\x19\xdb\xb4@\x07=\\\x1a&\xc8\x9e\xffs\xc8o51\xe1\x12\xa8W\xc9\x9b\x1aS-\x11y*\xe3\xd8\xfe\xf4\x16x\xbb\x87\xdb\x94\x1a\xaa\xc8 u\xf4&\x90Og^"\x01\xa7\x0fO\x1a\xb4=sp.\xdc\xb7\xcd\x98\xc8\xc9\xa0\x07\n2\x1a\xb4\xea= \t\xb8n\xb0\xc6x\x84\x85\xd4\x99\x89\x1a\xf7\x10\x89\xafs;J!\x1d\x95\x97J\xd3\xe2{\x1a\xff\xf3\x00\x12\xf2\x0fEUt2M3}vc\x1b\x18\xb4B\x15\xc7\xf2\x9e\xe8Pg\xacK\x8eGz\x1bY_\xfd\xc9!1^\xe5H\x8e<\xbd\x0e\x80\xef\x1bam\x95M\x19\xcd*Q@\t\xe4+\x06\xb2\xd8\x1bd\xad\xba\x84\x15\xf5\xd3\x84\x8e\x98\x1f\x05\xee\xe5\xc5\x1b\xd8r\xa2]\xb8{\xfd\xf7\xf1-\x94\x96\xa2/\xc4\x1c\x05%\x0e!\x85\xc9\xbc\xe1.\xbf\x96\xb7,\xaf^\x1c<\x97ue\xdc\x98L\x95.\xb1\x9fdh\x8c\x1a\x1cF\x99\x1a\x1a\xe8b\x9b~\x96cSC\x84L\xf7\x1cV~YMU\xa6`/\xcao-\xf0\xb7\'\x9c\x1c[\xe9\xd9\x97\xd4\x05\x9e\xfd\x97l71\xc35U\x1c\x84\xe3G\xe9\xf6<\x19M\xe8\xdd\xc1\xe3\x83\xbe\xbc\x1c\x8d\xe6\xcc\xb9\xf1\xf7\xb9\x1d\xd2\x92v\x14n\x07]\x1c\x8fa\xea\xbez\xd8\x9d\xfa\xb6P/g\xafYg\x1c\x9e#G\xca\xbcj\x9d\xcc\xf6m\xd8\xb4\xc0r\x8f\x1c\xaf\xfcg\x06:\x15a\x89\n\x0ea^v\xb0\x06\x1c\xb6h\x8e\t\xb6\xcf\xbe(\x01\x9b\x8d\x90\xa4\r`\x1c\xb8\x1c\xad~\xcb\xeb\xa6\x81\xed#\'\x94\xaab\xc1\x1c\xc4x>\xe3>J5N\xda\xb07h\x0e\x0fj\x1c\xdem\x11"d\xffK\xcf\x01\nd\x07n?\x1b\x1c\xf0\xa8o\x18\x00\xd7\xd2r\x06\xd2p\x00\x0f\x90\xc7\x1d:\xad\x98kFP#\x83d\xb5x^\r=\x86\x1dG++2\xeeD\xf1\xfad\xefT7\x00\xe8q\x1dY^t\xca\x81q\xf2\xf0\xe3@G\xa7\xce\xf9\x10\x1df)F\x16\x0e1\xcfPu\xccv\xf6\x16:\xf9\x1d\x9dc\xd5\xc6O\x7f5\x90#b\x907\xabx\xc7\x1d\xa9\xf8\xf8~v\xced\xe5\xc2\x11\xd1\xc3\x08w\x86\x1d\xbf\xca7o?\x1e\xbf\xb6}\x15\xac\x9a\x86Z\xe4\x1d\xc1\xfdC\xb0%i\xf2\xd7"4\xa6\x86\x84\xabZ\x1e\x1c\x85^?\xb8]w`\xfc\x9b\xff\x1b5j\xa8\x1e?C\xfc\xcd\xd4\xcf\x9cG\xc1\xfe\x19\x1f\x07\x18\xf3\x1eN\xf9ICzzc\x01\x89zO\x8f\x96\xac)\x1ey*8\x99\xcez\xb4\xbb,\xbe\x1c\xb92w\xb9\x1e\x89\x19-\xe2\xef\xa0L3+SP_\x1ape\x1e\x95\x8d\xc6uQ\xcd\x9bf\xfcbv5R]:\x1e\xe2E\x06\x9b(\x14\xcd\xd0\xcbR\xb0\xf7\xeb\xf4\xab\x1f\x0c\xa6\x01\x98\xeb\xa0\xa4\xebSk\xf8\xa1\x0f\xe4\x8c\x1f4S\x08m\x04\x07I\xc46\x8b\xc0:\x9a\\A\x1fA\xacr\xa7\xb4\xe1\xbb-\x8c\x8dynKy1\x1flk\xc4\x12(A\x0c\x9a\x05D\x0b.6~\xd5\x1fp\x82\x08\xad\xadYF\xd8(\xbcB\x9d\x03\x0c\x8d\x1f\x828\xaf\xc6\xc1\x11\xf3\x10]\x14\xf8 \xcc\x0fr\x1f\x82\xa6\x8d\xae\xa0\xe37\x7f\xed\xf5\x81\xe6\xe8\xdf\x89\x1f\xb2GG\xd1$\x9b3]w\xc4\xae\xd9\x99\x1a\x17 \r\xacX\xc9\xcbN@A44\x0e\xf0\x9cah \x1b\xd6,B\x07\xbd8\xd0_\x803\xed\x18\xe4\x98 66\xcb\xf9w\xe1W\x9e\xcf\x1fN\xd9X/\x82 M\x1d\x9cR\xe1\xaa<\xa7\xd9\xa9\xc4.\xac6N ec\xd6\x9a\x07\x0e\xb5w0\xaa\x05\xcb\xdc\xae3 s-\xfdq+R\xf3z\x12Z1\xd23H\x10 |\x8a\x86\xaaG\xc2>\x86\x96M\xc2VWO\x84 \xaeT\x84T\x92]\x12\xaek\x1d\xefe8\xc6L \xae\xc9\x88\xdf\n,\x0c\xc1\xeap\x88|\x8b<\xbe \xbc\xff\x98\xbd\xd0\x0c\xa7%\xa8\x87\xb0\x13#\xd4R \xe4\x00\xcbq\x85\xc9\x18\x88%\x1c=Q\x00\xac\xde!\x16F\x94;\xf4\t\x04\xb5c\x95|\x85\t\xc4\x8e!`\xd7\x92\xb3\x10\xf3\x17\xd6\xc2[\x12y\x9d7$!q\x99\x061v?\xdaSm\xf1\x01\xb0\x96\xe4\x93!\xc6\xf6+U\xa7\x94\xf3\xff\xb5{\x8e\xc7O\x84[!\xcc\xae&\xc3!\xcb\x96\xee<J\xed\xc4\x90U\xfe!\xd7Z\xf0\x84\xe6\x9e\x17\xae\xc6 N\x106\xda\xc9!\xdf\xd5\x93\xfdf\xd9g\xe2\xb3\xf7P\xdcu;\xc9!\xf0\x99\xe2\xb47\x96J\x7fn\x87\x9ac\x85\x07\xc6!\xf7\xed\xb2\xbc\xba\x8dV\xf2\xeb\'s\x9eD\x12\xc2",\xdd\x06\x97\xf5\x10\x9b|\x95()h\xcbi\x7f"w\xb4Q\xcagH\xbd\xb8\x0e\x92\xb8\x03\x17.\xa8"\x84\x08\xda\xb6\xa0\xbf\xc2\x9c\xe6\xca\x100\xed\xd3\xb1"\x94q\xacx[\xea\xef\xc9\x0e`BT\xc2|\xe9"\xa5\xae\xfa]2\xdaC\x87os\xf5\x03\xbd\xfd\x07"\xd6\x9d\xeb$\xf4;<-C\xc6\x89\xdd\x05w\xc0"\xfb\xcdI\xa6\x04\xdf\x93\xc3l\xe9\xaf\x01\x03P8#P\x98\x7f\xd5\xad\'\xa0\xd6\xbf\x1a\xab\xdf1g\xcf#m\xa19\x13\xa0M\xcaB\'-\x84_\xa6\x93W#\x8b:\x06\xdc\x83\x0c6\xc1\xe5\x08m-\xc2H\xc4#\xc9+q\xf0(0]\xe1\x1d\x0eP\xf2V/j#\xdf\x87CM\x93\r\x8d\xd0\x80\x92\xde\xa7\xca\x1e\xcd$0>\x83*\xae_)c\x83\xd4\x87\xd8Z\xcey$0F[+C%\x01\x03A\x18t.\x06\x7f\x92$`\xc4:\x9exs3\xf9[\xf3\x8c\xf4\x85\xa4B$\x99\xe1\xfb\xb0\xfeU} d\xb2\xebY\xe8\xc2\x8f$\xd4-vW\x19H\x82\xba=\x8ds\x0c4\x04A%2\xae\xa3\x19?\x0ff\xdcx\xf3?\x99\xab\x18J%6\x88\x8d\x01\xe7U\xc7>\xb5\xe4yf\x19H\xb4%\x8d\xb5\xc6\xb5X*\\\x0b\xf6E\xdb\x12\xc4|j%\xb98\xc8jI\xae<\x04N-\xc5\x01\xf8n\x8e%\xe9\xa3\xb2\xfe\x0f\xa2\xb5f\xd7\xf0\x08P\x10\x8bx&9Z\x9d\x0f=\x02\x08\x0b\x1b\x17\xf9\xcb\xae\xad\x97&=\'D+\x93)\xa9\x9b\x0fgp4\xb8Tx&Pw%\x1bD.\x89\xc5wr\xe3fB\x91\xf6&Un\xc1\xdf9\x0e\x16\x99q+\xfc\xce\x03a\x9c&\x80,U;\x0e\xcb\x1fV\xe7\x97h\x81K\xc9A&\xc1\xe7\x9e(e\xc1\xf2\xc7\xabz\xec\xbd\xb2\x8a\xcd&\xd9\xb2\x88\xe6\x84\x17\xbd\xefQ\xe8j\xcd<\x89\xd0\'\x02\x9c\xf1\x14F\xb4\xc1H\x8f}\xd2\xb7\xcd\x01A\'.\xf2\x92c\xd8q\xaa\xc4\x16\x97\x07b\x88Q\xcc\'/(\x93O]\n\x1b\xd1\x16\x0c\xf2\xd285y\'1\xdf\x8d\xc84\xba\x84\r\xf1\xba\xc8\x8fi\xb4x\'S\x1f\x81\xbf\xbb\xcb\x9b\x19j"D"\xa3]\xd9\'m\xaf\xb2\x8f:`U)\xde\xfc\x80\x912z~\'\x7f\x1a\xf2\xd7\xb9\x86X2\xdc\\\t\x1c\xa2\xafW\'\x81\x9c\x97\x1b\x06`rW\xd3\x19JB\xf5\x1b\xe7\'\xae\x83\xc4\xeb\xa1\xc0\xc4\x14\xe2/D\n\x01\x05\xb0\'\xbe\xb40\x8c\x00\x07?\x9a\xdbnO4\xca\xe3\x95\'\xef\xa5L\xc0M\x9f\x85\xba\xaa\xf6h\x8e\x83\x08{(\x00GJ\xf2\x83\xcf\x8c\x02~xV\x16\x9c\t\xd4(\n\x03\xdc%\xfb\xac\xec\xfa~\xbd@\xad$\x96W(`g\x18\x95]\xc5q\xa3\x87v\x9a\x13!\x8b9(\x97H\x01NG\x98\xbc\xe1\xbcIQt\xed\xec\'(\xb1m"\x9e\x1d3\xe4\x90\x18Au\x11\xe5m\xb3(\xc4IGm\x01?+\r\x01z\x88p4B\x1d(\xc5\xbc\x95Z\xa0\x05o\xe7\x0e\xe5\xb4\xf9\xb5\x80@(\xd6\x14KR%\xf0\xef\x8d(\xf7>Ok\xa4\xe9(\xf8\xcc.\x1f\xea\x8b\x93\xe2V\x1e6U\xb1\xb7Q)\x00A\x85\x81#\x9c\xeb\x9d\xbb\x7f4\x16\xa8F\xf1)\x15\x88\xb3\x97o\x97d\x01@C\n\xac\xe5\xb7\xbf)&\xee\xa9\x0f\xd3\xcc,\x9c\xb6\xbf\x03i\xef\xea\x9c)=\xe6z\x1d\xf6S\xa4\x88i\x85\xe5"{\x8ad)vV\xe9\xa5\xbf\xcc\xd7\x8a&<\x1fFu\x88\xb5)w\x10\xbd\x00\xd7\x10\x14%\xa9\xa3\x87\xdc\xd6\xe3\x0e)\xd0B\xf9\xf6[\xbd\x9a9Z\x0e\xef \x98\xf3\xea)\xfcE~n94\xedd/\xa6t\x9d3\xd3`*\x00\x8d\x85\xe7\xdb\xc6\xdd$\xc9\x1d\xd9%\xd0\x9c\x92*p*\n\x9e4\xae6\x00\x0e\xc3\xfb\xb7\xa79\x80*\xc2\xdd\xa1y\xf1\xadhH!d\x89\xae8f\x0b*\xc7\xf3S\x04\xddt\xc0OK\xe7[Na_\x88*\xd5;v\xb1\xcd\xba\t\x85\r\xe4LA=\xe1\xa6*\xf2R\x0c\xff\xf4!\xafB(a\x8c\x07(b +!U\xb3:\n\xc2\x80\x0baP\x9eR\x10\xf3\x13+5y\xc2\x94#\xee\xc4YMs\xa1IA_\xb1+br\xb7\xc2K+\xc9\xbe\x0e\x9f\x05\xfb\x8c\x88D+f\x98\x8c\x04\x03\xbe\xbb\xaa\xa3\x8a\xc5\xb4\x96\x07\xa1+qS\xee\x81\xc7\x86\x99SA\x99\xe1%\x92*\xca+u\xd4 ]\xa9\xe4\x9bwd\xdb\x08\x0bJ\xaa\x11+\xb8m0\x8f\xb5\x10\xed\xa3\xf5\x0ex\x1b\x89?\xa1+\xcc\xb05\x9b\xe2\x08M\x0e\xb8%Z@\x95Yu,K\xcc\x8c\xcf4\x8c2\x88\xb0\xb7\xcf\xe6\xd0\xeb\x97,\xe7\xcbF\x80\xc7P\xec\xeetj\xfe\x84\x91Ye,\xef\x9b\x94w\x06\xa5\x95\x10\x11Np\xa8\xdf\xae\xe4,\xf6\x7f\x05\x9cU\xc5pim\x1d=eV\xef\xb3-\x13\x16)(4\xa2I}?\xa3\x05=g\xfb\xad-L9\xfc\xb5\xca\xa2\xe4\xb2\x0f\xefM\x84\xe2\xd5}-\x892\xfcvu\xbf#d\x9d\xd2\x80q\x0f\xff\xb1-\x93m\x16@\xd3\xb14\x9fV-|\xc5ky#-\xaa\x7f%\xafx\x0fs\xf4\x9b\xcaa\x8f\xcb\xa5J-\xad\x10]\x02\xcak\x93f\xf2\xfe\xf5\x11\x03\x0c\xa3-\xc6\n\x9d;O\x81\xf5\xd2\x82C\x91#\x05\x87\xd7-\xe5\xb0\x8e\x8f\xcd\xd0\x1c|\xa4"\x03\xc7\xb2V6-\xfa\x9f\xf0\xd9\xd5\xc9%}G0;\x89q\xfcw.AB\xaaDx\xc8\xd0\xad\x87\xfd\x08\x98\xf8\xb9\xd5.F\xb1"$Z\x84\xc8\xcf\x1f\'\x96\xb8\xf3\x05a.LC\xc9F\x84\xae@5\xfaq5\xc1\x0ei\x07.Z\x9d\xe1\x96dk\x0fK\x1c<\xa82^r/.a\xfahv\xf7~\x18{o\xc3\x81g\xa6\x88\x1f.\x9c\xf0^\x1c\xf5\xd2\xa7G\xa8\xa0\xba\x7f\xcdAD.\xc8\xbc\x00\xd5=\x1a\x04X\xf6@\t\xa7Z\xf0\xef.\xf3\x99\xa8\xcfT\xdd\xc2\xbdWZ\xf4\xe7\xfe%\xaf.\xf5\x81[+K7\x18\x91\xe8\xb1\xe7l\xd8\xe1\\/\t#\xbc&\xa8\x05k\xdf\xa2\x83{\xa5/\xeb_/h\r\xfcX\xc3\xb8\xa7\xe9ZS\xbd9X\xa9\xc8/\x7f\x9f\xd9\x94\x90a\xc5 \xae\xeeD\x1c\xa1~v/\x8a\xee\x98\x8e\xbcI\xc3\xf7\xeb\xbe\xfd\x93\xd5\x8d\xf3/\x8e\x15@<\xd2\x89\xf1\xc5\x97\nt\x07W:E/\x95\x96&\x07\x08\xdc\xec\xc2*\xa3\x08\x85x\xa6\xae/\xc5\xd8\xa3?a\x1f\x96\xf6\xa2\xe1*S\xb2\x0e\x9d/\xceh(>\x0c\xc4\xaab=\xcc\xc2]\xaeFO0\x01=\xd6!\xa4N\xf0n\xac\x01D\x1c6J\xc30$\x1e\x0b~{\x05\xaa\xeeoY8\x8d\xa6\xa0\xdc0(za\x98\xa2\x1a\x03W3\xeema\xc9r&0QT\x8dfw\x1b\xc0!_<\xdfo\x9a\x1b\xcc0kV\xa0\xf1\xaa\xb3qi\xc9\xe2m1\x1d\xdc\xfd0t\xe0!\x03\xad%9\x8bj\x80m:\xa7\xaa>0\x83\x1a_\xdb\xacE\xc9\xce\xb2\x99\xb1\x03\xca\xcdh0\x9b\xed\xe0\x95u\x1au\xa4Z\x12\xf0\xdeb\xe0v0\xcfgw\x89S\tlV0\x93\xf9s\xd8ER1\x04\xfbB\xa1j\x07V@\xde%\xb4\x0b\xdb\x04y1\x19Z\xcf\xbfB\x12\xf6\x891\xb2j\x83\t\x16\xde12\xf4x\x99R\x8d\x80t@E\xca\xa3\x08\xd8j1Y\xda\xf8\xba\x17\x16\xdb\xf6\nW\xc0{5XA1b\xff\xe6\x87\xf2\xd8g\x8f\x93#\xe8\xa0\x86\x83\xc01\x8e\xc9~#o\xca\x12\x94\xc4\xc5\x0bz\x931\xcd1\xe3\\C\xfc\xf1\xc7\x922\xe8\x8e\x86&\xf1a(1\xfd\x04\r-E702PV4\xfdJ\xdb\x0c2\x07L\xf5\x05\x04\x08\x08\xad\xde\xbb\xb2\n\x17\xf5C2\x10?\xa4\x8b\x84\xa6Q\x07e\xcc\xe9\x826\r\x122*\xf7\xa8\xd1\xbedh\xfe\x8d\xd5K`\xd9\x06}2+\xf8\xb0\xae;*\xc9~3k\x8a\xb9\xff\xabe2-}\xa6\x9a\x01\xa1^\xc1\xaa\xa8?\x82\xdcus2e\xaez\xb8\xba\x10U!\xd8\x81\xb3u\xf6<22\x96\xf3\xfb\x1eTV\xd5\x1c\xb7\xf7\x8do;z\xc03\x0f\x11r\xdb\x92d\xacE\x00\xafi\x13Z\x1f 3Ej{e\xef\xd3\xdeGR\x8e\xe4\xbd\xed1\x073d\xf1\xd7\xa9\xd5p5@\xe53\x11\xc06\xb3\x183\xaa\xdb\xef\xeb\xf5&\t\xd3\x80\x89\xa1H^\xe9\x114\x0c\xcc\x86\xd4<\xc1\x0cw\x05\x11\xd0\x11JT\x8b4\x19\x15\xc9;}M&\xca\xad<\xaf\xc2\x17"\xeb4D\x1c@\xfb\x91P8\x80f\xbe\x9fs\x95\xa9\xcb4u\x9cRr?4[\x01\xfe\xce=\xed\x94d\x924\xa5\xdd8m\x19gaB\x16\xb9\xc8\xf8\xca_\t4\xbe\xd1\xe8\xae\xb1\x872\xc9N\n\xd6\xe3\x8bv\x105\x0f70+\xb9\xa9\xcc\xda*\x92\x81\xf8\xcdz\xb15\x1a\xf8\xacA&\xd4z\x9e\xc1\xe9Y^\xb3\xe4\xd15X.b2\xbdW\x9b\xc2\x92_\x9a\xd7~\x97\xf05a\xc8\xceo\xb1\xf3\x7f\xda%\xd4\xbc\x06\x98\x9c\xcf5lhR\xd3M\x0cl\xd6\x9f\xf3\x01{5\xf6L5\x8b?YY1.";\xb9\xad\xea\x13\xc3`\xae5\x8d\xb08\x8f)\xbe\xfb\x97\xb9\'js{\x8ab5\x97\x069cO\xfe)K$DZ\')\xf9P5\xbe\xe1\x0c\xd3\xa0\xb7\x19\x1c\xae\x97Pk\xd5uV5\xceq?r\x19\x83\x14b\xef\xab\xdcs\xb4\xda\x965\xdd<\x04\xb8\x0e\x00\x86d[V#0\xc9L:5\xdf=\x96%\xf4\xf9,\xc3\x16 \xb6\xc0_\x1c\xfc5\xe02f\x0e\xdb\x92\x1c\x0c\x0c\xe5\x9b\xfa(\x9d\xc55\xeb\xe8H\x94\x95\xda\x99\xcf\x04\xd8\xe4e\r"G6\x11V\xae\xbc\xa2^f$"\xa0\x9dN\x12\x06\x1662}\xf3\xb5\xe8\xc0\xfcs\xcd\xfd\x82\x11%\x14\xd36=\x9f/<\x8b\xf6\xd9\xa2\x8b\xab#R\xaa\xbd*6Oj\xe5c| \x9d\x8bM\x83+\xe6\xea\x1e&6a\xa3\x14\x8b\xb4|\xa6\x12\xd4\xfc\xc6%\xc2\xd4:6f=,\xce\r\xda~\xad\xa0`\xe8\x99?\xe0\x856\x91\\\x10Q\x92\xa3pY\xfc]\xc3\x01\x9be\xf76\xa4\xa2\x17\xe0\x15\x98\xe9X\x9b7\x0f>4\xd2\x166\xa7\xe5\x08\xc6Y\t\xc2\xf1\xd1\xac\x068\xben\x077\'q{\xbe\xf4\xf0\xe6\x8b5\xcc\xd71Y\x91\xe97@KG\\\x06\x89\x91\x06\xa7\x98\xa1g$P\xe37f\xa9\x04K\x0cuM\x84~?$\xdf\xa6r\x0e7{m\x00K\t^X\x7f2\xbf$\xa80\xc6\xd07\x9e\xf0\xb8\x86z\xb5\x84\\\xa07%\xab\x18\x9e\xd37\xba\x13Q.^k\x92\xa9M\xe4\xf4\x11Qa}7\xda9\x19p\xb6SUt\xde\x9a\xb8\xc1\x94\xd2\x0f8\x07\x87y?\x8d.\x1c\x0f\xe3\x8b\x0f&v\x11\xf68\x11\x1b\xae\xc3<\xf8\xb6\x0b\xd0\tk\n \xb2\x1d8\x1f\xe0\x95)\xbdBDQ\xaa\xeeD04\xcf\xf38,T\xab\xe1yM\xab!\xd3jE\xccd\x0bj8N<\xe27\xfa\xcc\xb7V]\x1c_\xc2\xc6_\xc68x\xae\x8e$\x92(\xa9\xa3\x99h\xaa\x15,\xb3\xc48\x9c\xd8k\x7fn\xf03\xc8\xe8\x1b\xc7\x1b\xbd\x05\x1e8\xabu.\xc0\x83\xe8\xd5\xb0\x12qX\xf9\x88\xe7"8\xcc\x01\xe2;\xd7Q5\x91\xb6/\x05\x106\xc889\x0b\xa6\x9b\x8d\x15\xbbm"\xa5\x84\xe8Yl\xf3\x8b97\x83\x15(\\f\x81\xfc\x132\x0b\xb5\xcf\'\x919E\xb0V\xd7\xa5\x1bS\x94LT\xeb\x94\xe1u\t9\x86\x03\x97<\xbeZ)\xd0\xb1\xc3\xb5\r\x85\xaf\xc49\xb9"\xdc-\xe9\x80\xce\x9a\xf8w\x8a\x93$\x18\x899\xf1\xb5z1B$w:\xb4\xe9Eb\xd0\x11F9\xf51\x87)fT&\xbb\xdd&g-\x8c7\x1b9\xf9\xfd7\xcd\x1b \xe6N\xfd\x08U\xd7_\xd5Q:\x05s3b\xcdT\xbe\x0e\xa9\xf1=^ \x90\xba:SDp\x06\xd7\xa94\xde\xe7\xefk\'\xae\xae\xfe:\x93i\\9\xb8\xb9\x8a$]\xde\xd1\xa0\xe5\xa9\xd8:\xa8\xc5\x1f\x04\xbd\xab\x95\x83?\xe8G\xef\x10>(:\xb6\xb87\xd26\xc6\xf2`\xeebk\xbe9\x97>:\xde\xcf\x08Ysr\xeb\xa6\x17\x8cL\xf7UA\x02;\x1fb~\xcd\xabw\xb4\xbfeT@m\\\xb5\xfe;_M\xb0\xc5\x1c\xe2\xc3\x816\x06\\\xb4\xd6of;\xd8\xa2\t\xc4\x92\xc7\xb3\xa6\xc9\xb5\x19F\xd8+\xdd;\xf5\x01\xf0\x10\xa3\x92)\x1a\xbd\xf84\x7f\xcc\xe8h;\xf9\xf0\x8dk\x11l\xc8\x9bR\xf3\x10a\x8eHm;\xfe\xb2\xa1p\x9d\x8dm\x9b\x92\x10\x0f\x98\xeb\xe1x<\tq\xbc\x05\x1a\xcf\xd5\xf3\xb2:<\xf1\x87z\xa5<\x0e3\xb1>$8\xaa\x17\x82\xc6V\xd1\xf6\xe8K< \xdc\xf5\xc6^\'A\xc6\xfe!f\xc7>\x89y<2\xb26\x9c\x16&\xbe\xec\xd5\x9d\x03\xf0}\xb6\xe0<T\xe7\x1d\x00\xd6\xa4G\x08a\xe5*~\xa9\xe9L<d\xe5\xfa\xd6\xed\x0e{\x0f\xdb\xa2]W\xa1;\xbb<\x8bdBz\x81\xe0)U(\xa2\x1f\x04\x1c.\x96<\x96\x8bD\xbe\xbc\xa2\xea\x92\xcbJ\n|\xd1\xba\x93<\xbf\x90^9\xc20{\xe9\x86\xed\x08DJ\xe5\xce=#\xa2\x15\xeb\nQ+0\x15\xde]\xde\x1e\x02u=/+\x9fUQ\x8b\xc0\xf6!x\x86\x03\xfe3d=I\xcd\x17?\xe3\xfb\xc8\xb6\x90\xe6\xc5\xfc\x80\x05\xa5=|\x0c\xbf2\x02[\x16v\xc8g\xb85\x90p\x1f=\x93\xc3\xb8\xb8n\xdf\x8e<\x9a\x18i\x1ew \x80>\x16\x959$\xee#\xde\xe5U\xfb\xdf\xfa\xd8[\x14>3aX\xeaO7\xd0MW.\xce\x9b\xa8n\x9a>b\x95T\x96\xea L\x1cX3\x99\xc2\x18p1>xO\xf3\xbd\xb4\x96\xf4\xf1\xa6h\x909\xbf\x9f]>\xd3\xba6\x87T8\x0f{\'V\xd4\xd9<0\xa2>\xe0\xe0\xe4R\xa0\x04m\xe0\x8d\\\xf8\xbf\xfd\x06\xff>\xe6\\\xe8\x87\xdbZ\x8a>\x10PHN\x88]/?\x07\xb2\xae\xaf\x9d\x16\xcf2~\xc3q\x97\xb4\xeb\x13?(\xc5\xd2\x04\x04\xb9\xd5~\xe3\xdby\x7f\x8a\xeb\x84?<\x84\x97K\xa1\xa3\x95\xad\xcb%\x8fYm\xfb\xe1?=\xea\x88J\x8c\xf1\x80O\x82\x92\xae\x0b\x93\xeb9?E\x88#\xb6<^\x9ac\x8b\xd1\x0c8\xc8\xa9c?K\xd2\xeb\xe9\xe5G\xbc\x15f\x85j,\x89^\x12?S\x0b\xac\x0b\xfeK\xc3\x06)\x89R\x1f\x10\x0b\xb4?\\UH\xe3\xf5m\x10f\xb1\xf0\x80\xa5~\x95\xe7?an<\xb1\xfd\x89S\x83\xe3Dz\xdd\xba\x06j?d\x8b\x98\xfa\xa16\xca\xa4*\x19\x86\x87\xa4\x00\x04?p\xcc\x0e\x0c/\xdb\x88\xfc\x9c\xd4\xa8\xbd1\x8a\x8a?\xa4Md\x8e*\x8aN\xa1\xa3\xcf\x00\n\x97\x86\x88?\xa9\'\xf4\xad8\x9a$\x03\x97\xdd\xe0^\x01T\x11?\xbc9\r#\xaf&\xe7@\xe0P\x80ekg\xac?\xfa\x1c`\r!\x99\xf9\x14,\xad\x95B\x15\x0f\xd1@BF:\x08D:\xdb\xdb\xdd\xac\xa37?X\n@vI\xfcX"u\x8f\x84BHE\x84\xba\xbfS@\x8f\xc5y\xe4w\nXZW\x9a}k\xbb~7@\x93\x1c\xe0\x06\x89\xfb\x14;9\xac\xbb\x9c\xe5\xeb\xde@\xb9\xfc\x93we\x86\xea5\xf5\xa8\x86b\xe8\xd3+@\xbf\x07\x03\xae\xefJ~\xbe\xcdo\xa2\x02\xc3d9@\xf8vf\xc9\xbb\x0b\x000\x03\xafl8R\x1f\x1bA\x04\xd5\x82\xca\xd6\xa4\x91\xf1\x847L\x87\xccr=A/\xb2}\xd3\x99l\xa7DZ\xc1f\xc8-X5ABs~\x87\x0f\x03\x84?/\xb6\xd5\xf0\x9c\x87AA~\x879F\xd4\xc0(i\x18_G\xe9Si\xc6A\xab\x1e\xfe\x87\xe2f\x1at\x7f\x82HB\x11\x18KBW\xf2g<\x01\t\xc3\x81K\x98\x16<\xb2\x9a\xf5B^\xd5\xc9\xc3f\x16\xa7\x02\x8fpl\xcfL\xd5\x97B`\xb7\xd3\xde&\x17V\xf0\x9b2h\xe3\x83E\xafB{4;\x99\xf7w\xa7\xd7\xe8\x96\xb1\x9d]*\x1fB\xae\x17\xa8[\x18\xa8\xb5\x8d\xca\x16\xdf\x9f&d\xc3B\xc1\xc5\xda\x81\xff[\x8d\xa5\xc3\x10\x08v\x93\xe9\xbbC\x17$\x05\x85\x1fB\xb0\xc3\x91\x05\x8f \xa6=\xe3Cv}\xc1]\xd8-\x13\xf70n\x11\xa2X\xaa\xe5C\xc1M\xad\xe4L\x9c\xfd\xd0X\x1f\x95xp(IC\xfe\x08\x95&[A\xcdM\xdc\xd3\xe0\xffj\xae\xd3D\x106J\xff\nK\xa1\xc7\x9fO_I}\xba\xa9D!\xb53d\xfd\xecN\x8cOB\xeb\x0e\x94\x81BD#\xfe7\xceF\xe4\x81\xd2H\xa5\xa8\xdd\xef\x17|DK\xf6\r8\x8d\x8d7.\xf7\xee\xfc\xe2\x01U\xedDw{\xb2-\xc6\x8e\x0b\xb2\xe7\xbc-An\xf4\xd7D|\xed\x03\x9d\xb8\x1e\xc5\x9e\xe9\xc3\xc0\x18SG\xa1D\xbd\xb81m\x03\xc8\xa4\xd6c>I\xb0DE\x1aD\xc3\xb2\xd9i\xb1\xaf|\xfbV\xd9%\xd4f\'\xd8D\xe6\x89\xbf\xddw^\xa9T\xda\x93?}\x9c\xebbD\xf1\x95k\x9a\xbc\xact\xd6\x89\xb6\xc3\xca6u3D\xfbWU\xda\xa9\x87\x87u\x9c\xb7,\xbc\x1d\xec\x87ES\xfat\x8eR\x08\xea\xf0W\x8en\xb5\xfdH\xd1Er\x82?\x8f\xe2(h,q,\xbb4#\x83ZE\x9bv\x9c\xcd\xcd\x9dJ\xee\x11\xfbo\xe1<\xfc<E\xaf`\xab\xa4\xdfR\xa1\xaa4\xdd\x8e\x856\x16\xc6E\xb9\xa1\xd1f,\xc8\x18\xd5\xc1\xe8\x14*`\xa18E\xe5\x9d\x96\xe9\x93t\xbb\xb9\xa4q\x9d\xf4\x8c\x89\x1eE\xe8f8]\xf4d\xc8\x94\xb6 \xfa\x94\xa5\xefUE\xf4\x07v\xff\x9d\xb0a%\xc9\xf0z\x80\xe8\xc8\xa8FM\xfa\xe4\xaf7\xc5\x88>\xee\x8e\x82`D\xacKF\xd9\xae\xfbX\x87\x7f\x03~!\xa1 \x8bo]VG&\xe1\x08\xed\xe4\x06\xa6\x9a\xabQ\x92+\xcePxG_\x8d\xe1\xcc(W\xb5\x14$\xf4\x1c\x08\x06\xad\xcdGk\xc0we\x08\x9d\x97Ii\xe5\xb4\xf8l/\x80G\x8a\xc4\xbd\xfaP\x0c\x1b\xd7U\xfa\x90\x93\xfb$gG\x91:kV\x1e\xd6\x80r\xb2f\x14/\x8a\x12\x87G\x9d\xdb\xa8q\xf7\x996\xfaS\xde\x8d.k\xea\x05G\xad\x10c\xb2\x08LH\xf4\xb6\xc2,\x1e:\x15\x8aG\xb0Qi(\t)W\x0b\xda5\xe5\x90\x90\x1eQG\xc1\xc0\x95z\x8a\x05\xdc\x06G\xd0\x8d\xa7U\xc1\xd7G\xcc\xcc\x9e0/L\xb4^\\4\xeec,\x0cUG\xf0\xdb\x9c\x93\x84=}l\xcdz\xaaA\x03%vH\x11\x1a\x0f\xd0\x86\xab\xc3\xaa\xba\x9f^\xf4\xce\xbf&Hf\xb6V\x8e\xc9\x12\x17\x99\xbd\xec\x0e5\\\x08\xf6H{\xe5\xc2\x8d\xbe\x83F\xc3\xef\x01\xe8\xb1\xda\xab\x15H\x9d2\xa1\xa97\x84>\xb9\x9e\xfa\x88\xb7S\xc1\x04H\xa7\xac\xbf\xe8\x93\x0f\x90\x17\xb5\x03\x01A\xbc?wH\xaex\xbf\xa5s\x0e\x01r\x9a\x87\xd6\x89\xe3\xebTH\xbf\xac\xb2=\xf93\xcd\xfdc\\c\xbf0\x86AIT\xd3c\xe8|\xa7\x0b\xce\xdb\xb7\xe0\xf0\x02\x1a+Iu\xca\xd3#\xd1m\xe9\'$\xca\xf5zQ\x8d\xaaI\xa0\xdfL\xd9\xc2\xcb\r\x98Z\xf4>_\x06\x80\xabI\xe7\xc7\x85\xdb\xc8E-\x95TN\x84\x97\x14\xe7\xceJ\x19\xf8\xdd\xa1\x9a\xe1\xb1\xfb\xb6\xe4\xaaF\x06\t*JS\xd2\xe2\xaci$\xa5\xddJx\x02\xd4NS\xeeJr\x1f\xd5k\xe0\x8b{\xc2\\Q\xe0-\xb5\xdb\xe1J\x8b.\x1e~i\x9b\x96]\xe4\xee\xabG\xa1K\x10Kp\x9b3\xbaR\n\xb4RY\x80\x92&\xa0^\xfaKq\xfe\x17\xc2r\x7f\x9c;\x15\x00\x19\xbd(\\\xb5K\x98\xc5Xp\xd0C\xaeo\x0f\x94\xe1\\G\\\xbaK\xad\xf3D\xdeE\'^7\x86\x08H\x06\x11\xc2\x03K\xae\x0c`\xba_\x00\xa75\xfeZhC\xec(\xf5K\xb3\x14\x06\x89\xcf\xbfF\x97\x9bE{\xc5\xb9\xb5iK\xc7\xf9\xd6\xc6\x97\xcc%\xff\x90d\xecQ\xea\x82\x0cK\xc9*;\x85\xcc\x8c\x04?|\xea(Q\x86\x0e,L?\xb0\xcc\x9e\xabL\xab\xd4\x14\xd9\xa1\xe9Ri[LFzE\x13\xcc\xdc\xb1\x1b@\xf2>P.?pLhwS\xdf\x03\xe4\xf8\x1d\xe8`\x88\xcd\x0e\xaaRLzY\xbf\x17\x97\xe6@h\xfa\r\xc6\xe3\xb1\xa2\xcdL\x84\xb4\xc1\xe8\x1dG@\xf4(\xd4\x1f\x8d\x03^\'L\xde\x99d\xb0\xa2\xf0\x03~\xc4(#\xda\xa0\xd2$M\x1e\xce\xab+\n\xe7\'\'\xac\x81\x90\xbe\xd2\x85iMS\xa6U\xda\xb5V"\x08\xa6l\x9a_\xb7./M\x85G\x06U\xb2p\xdd\x86\x80\x01\xaa\xf1\xc2\xff\x06M\x92\xb0+\x8e\x99=\xbe\\\xfc\x97\xa7\xb3\x1a\xf73M\x9a<jX\xefmH\'\x98\xd2+\xa9\xde\xbf\xabM\xb2\xcd>Z\xb0\xa4ka\xc5};L\xdc\x98\x1cM\xbe\xf2N\xca\x01\xa4\x97\xfd ^\x17S\xa6#\x99M\xe06\x82#\xca>N{\xac\x13J\x0e-\x16yN\x0f\xd2*\x95\x08\xa5\r\x02\xb5\xbfkN\x8f\xcc\x10N2\x85`\xf1\xba@\xb6\x90"\xd6|<V\xfe\x91NIj\xbf\xf3\xbc\xee{[I\x14\xe6\xe5\xac\xa0bNb?wE\xadEX\xd3\xdd\xb7o\x12\xff\xff\xcdN\x7f\xd4\xa1\xb4\x01&aW[\xfd\xa5\xe9\x91\xb6hN\xc1\x08m\x0c6\xab\xeful\x96*\x1b\xa26>N\xd0\xf2\xa2W\xef\xc5~\xde\xf0AEsuVxN\xd7{{\x81\xeb^\xc4\xda-\xcc\x197\xeb0\x89N\xfd\x16_\xf4r\xb3q\xae*q.v(\x10;Ok8\xbf\xdecX5;\xf8V\xea\x0c\x8f\x1c?O\xf7<\xd4\xdf;"I\x90\xbcU\xed\x10d\x1b\xf0P\x11_la\x9b\x90I\x1b\x9d\x8eG\x05|<%P\x11\xf0\x8c\xf4C\x19\x01\x12`_\x14=\xbe\xb1\x90P@\x9ex\x10\xa1$"\xa6\xaec\x19b[\xfcmPz\x18\xe6\x9e\x13\xa4Q\xa7|\x89$\xe0\xd9\xa1\xabP\x98\xe4\xc3\xdd\xeaR\x91m6xLqT\t\x95P\xb8\x96\x8c\xfe\xdaP\xd6\xcb\xc5@g"\xc7\xb3\x1aP\xbb\x10<\x8e\r5"\x14\xf0f\xa7\xe2\r\x1e&P\xc2s\xda&<OMIH\xa8\x04\x19h\x95\xa7P\xcd\xa9es\x8c<\x07b\xed\x95\xae\x86\xfff\xb3Q\x0c\x86\x82?\x14>,\xf4\xde\xb3U\xdcYDtQ\x1bIa\x1f\xb0\xc9\xdcv\xf39\x94\xe3;\xa3\xe0Q\x93\x87\x81a\xdb\xa2\x10F>5\x0ef\x7f\xcd\xbeQ\x94U\xd6}\xc7\x83\xd3\x88\x83\xe9\x10\x12y\xc9\xd2Q\xd1\xf5\x10\xf8O\x10\x90\xffBVc\x83y\x07YQ\xe4\x92\xe32Vi4z\xc0\xe3\xe89\x81}\x06Q\xf3\x87C\x94\x89\xf3p~\xc8\x88\xbb<\x1e7\x88R\x0e\x12\x14\x87c\xffp#O\x1a\xccX\x84\xee\xdcR"\xe2a"\xc1\x93\x12\x13\xeb\xab\x9c\x06\xf81\x0fR.\xaeX\xc0\xd1\x87\x13\xb94v%\xd5\xaa\xc7~R5$\xd3\xe0\xd6\x94z\xf2\xe7F\x03\x0f\xec\xbaoR@\x02)2\xde\x992\xf9\xb8%\x02A\xf10\xb1R\xad\xc9\xde\x9e\xab\xe6,\xc9\xc2\xec\xb8\xce\x80\x18\xa0R\xd8\x9c\xc2C\x06Dv\xa5_tA\xc6\xb2\xdb\x9dS\x12\x88\x86\x14\x12\xb8\x8f~\xd6\xe5\xbbE\xa0\xed\x92S \xb8\n\xff\x8a\x18\xdc\x7f>\xe5\xb2\xaf-\xc3\x83S9c\xb3\xac\xfb\x08\xe3\x17\x8fS\x90p[@8S@\xbf]K\x03\xd3=\xbc\x95w\x00\x05\xb0^\xb4Sj\x8d7\xd0\xc6mw\x1bN\xa0d\xff\xa2\xa8FS\x9c\xc3I\xaf\xc4\xba\n\x9c\xda\x98\xa8k\xf4\x80\xb4S\xa4\xc4\x8c,\xbd\xaaFU:\xa4\xfb\x88\xaf+\xfaS\xb2\x87\xc7\x88\x18ZE\x881\xb6T\xa0\xaf\x00\xf5TQ\xbc$p\\\xb4\x15V\xfc\x17\xde\x0f#\xcf`TY\xdadCN\n9\x04\x9dLQ@"Z{Tf\xf6\\\xd5\x93\x01\xce{\xea\x82\xe1\xcb\xe2M\xcbTiF<\xd3P\xd8\x98\x9e\xfd\xe5\xbd\x883\xe8nTps\xf5g\xc4]\xf9\xbbubw\xe1^~)T\xd1a\x16P\x161\xa7\xe8\xc4<W\x81\x91\xff\x1fT\xd4\xc7\x1f\x85\x17\xc8\xbb\xfev\xeeU\xd5H\x95\xc5T\xf2\x07}\x1c\xb6\xfc\n_\xe7\xe3\xbeG\xb6.0U8\x03\xa5YO\xb5\xaa\x1eAzD7\xdf*9U:a\\\xfc\x02\xbe\xe8\x1b\x82\xe4\x9ct\xf2\xb6+UM(\x14\n\x98\x87kB\xf7\xce\xfd\xf0Jl\xaeU\xa9\xfd\xc6\xccH2KdP\x97\xc2\xedR*8U\xb4j\x84O\x0c\xec\xbfp\xbb\xfd\xa0\r\x90z\xffU\xc8\x1f6\x17o\x12\xc7\xdb\xf8\xfaA(\xb2 5U\xf9&Z=\xca\x9f\xaa\x8e\x7f\x13i\xc7~\x0c\x8cV\x07\xe0\x1f\x10\xa5F:\x96\xfd\xdfj\x89_y\xf9V\t\xeeP\x01\xe8\x91\xd7\x93\x19x\x83\xf4\xe7\xa7iV$\x87s\xbd\xda>I\x1b\xde\x9b\xd9\xc5\x19_\x9fV%^`\x08G\xbaW\xb6\xc6\xf5Ync\xc0hV&\xc7\x9c\xd9x[MX\xa2\xac{\x960\x00\\V(\x18\xda\xbf\x9a\x07\x1d\xa8@\x9eL\xe6\x8b\xae\xc8VlY\x80#\x8b\xd8\xfd\x01B\x06\x034\xb5\x8a\x18V\x93\xeb\xb5\\>\xd6\x1b\xd7#\xba\xceS\xb2\xbf\x8bV\x95\xb3\xec\xa9\x8eRe\x99Sp\x10\xcc\xa4}\xb8V\x9f.a\xfd\xfaM.x\xd7\x9cj\x93Y\x11\xf7V\xf1\xa3\xa6j\x05\xb4\xbd\xde\xbc\xd6ZDS\x88\xa9W\t\x82\xa7\x9ct)\x9a\\\x12\xbc\xf7+\x05\xf03W\x1fYVE\xe8\x14\x97EO\xe0\x0b\xfe"16WK\xe7\xa7\x11\xd8(\xce6\xcd\xa3h\x89\x08+\xf5WQlt\x0f\x08\xe8iH[o6&\x05G\xedWh\xb4\xa9F\xb1\x0c\xc5\xbd\xd9L\xa6o~\xf0eWs+U\x12\xb2\x8b\x8c\x107}\xd5\xd0\x98)\xb0Wx\xd5\xae\x9aX\xcfQ\xcf\xb2\xba\xe8\xb0\x97\xc52W\x7f\xec,\x833u\x9f\xf7\xee\xee\x8b\x92*\xc2\xc3W\x85\xb2\xe7\xca\t\x1eJK\x97E\x1b\xbf\xc0\xfb\xedW\x8e\x96C\xf2\xbf\xb7\x06\xa6\x90\xca\xccJ\x91\x9fCX\x05\xd6\xfdh\xbb\xb3\xb79\xe9\x895Bf\xb9\xa1Xv\xa2\xe4#\xf6\x94f;A\x83\xf8w\\T\x8aX\x87G\x08*>\x1dYA?\xbd\xd1\xeb\x8bB1X\x94\x95ke\xd4\xeab-P\x8b\xd3\xd8;\x8evX\x98a\xc5a\xd7d\xa5\xbf\x1b\xcd\xd0\xe3\xa0\xe6eX\xbf\x87D\xbeg\x8a\xbd\x8d\xff4\x8c\xc8M\xe3\x05X\xd50>P\x86\x92\xe9\xcb\x13e\x9bn\xb0\xb4<X\xd7)\xc5\x7f\xc5\xe5\x1dgd\x99x\x9czg\x0cX\xe6d\xb9\xb8\x1d\xba\xda\';\xa4A\xa8z\xf6\x89Y%\x8b\x9bWw\x018\x8dp\xefe\xb5tE\x90Y*6\xf4\x03+$\xc0\x1f\xcd\x1c\xf7\x9f\xda\xc1\x17Y\x8c\x80\xd0\xe1F\xd9\xc7\x1bO\xf1\xbe\xbcw\xf1OY\x8d9\x1a\xde~+\x94\xe4\xc1\xd7j\x9c/0\x07Y\xd50\xd2\xc0s-?\xdc\x13\x1a\xdd\x16K\xeb\x1fZ\x7f!vY#H#_(\xfc)O\xae4\xa4Z\x9d\xf7\xa785\x00$8\xc1/1\xffY[\x86Z\xae\x03\xbc\xf6\xa3#+\x93\xda\xe3\x16\xa5\xda\xe8\xe9Z\xc9\x84fE\xfc\x90S\xb6H^"\xc7\xe1z:Z\xe7/\xe8\xc4\xee\xe7\x95\x07\xaa\x10\x12D\xf8\xe3\t[NViZT\xff\xe4\x80n3\xf9q\xab\xa8\x05[](\x14!\xd9H&r\xac\xc6^\x05\x1e\x05L[{\xc0\x9b?\x03\xa5\xd1\x98\xc6\x99\xe74\x1f\xe50[\x8aB!\xd4\x8fh!\x88\x84\xd0\xae,\xdd\x19\xab[\x92U\x88\xf3\xad\xcf!gP\xd4\xd3\xe9C\x9f\xa7[\x93vG\x16\x8e\xc9\x8f\x1a/n\xa4v"\xb5\x8c[\xb9\x1d\xeb!\xe1\xab\xb2\x88\x96MU\xc1\x81\x98\xad\\\x12\xdbq\x95\x16\xe1\xb8\x11\xf1\xed\xc0B\xc4"X\\i\xb1\x9b\xdcu\xe0\xa0\xbf\x02\xacA\x00\\\xb8\xe0\\pP\xbc\xabB\xa7r\xa3\x0e\xba>dH\x08R\\t\x1eU\xa4\xdc\xfff\xaf2\'\x862\xbbA\xd6\\u\xe0\xdb\xe1vs\x07\xa6\xfbh%\xd5\xfb\x80\x9a\\\x82\xb7\xfc(x\xb0\xdf\x06\xfe\xa9\x14\'K\xe2\xdc\\\x8f1\xec\xc5fxa\x8b\xe1\xfd\xb4>\xaf\x15\xb7\\\xc3Op\xa7\xf9UdJ\xdd\xc6\x00\xd2(\xe0\xc9\\\xc9\x90\xfb\xb7FJ\xe3\xe2\x12\xa0\xf1\xf1\xf3u\xe9\\\xd6\x92\x04\xcf\xaeZ"\t\x92\xae\xd9TV\xf2(\\\xf7r\xe1\x0f\xc5\xd01R\r\xa6Q\xda\xc3A\xb2]"Z\x86\xf3\x13\x1e\xb7\xa2\xfa\xd7\xcd8\x01(\xb7]5\x85\x10#\x14\x92\xbc_\xd1W4cH\x036]bn\xb9-\xa2\xf4\x93%4\xd36\xfe,1@]n\xc2-\xc1wyZ\x1e\xfai\xb2R\xfe.A]y-\xadt\x84\x85\xbc\x18n5\xa9\x14\xc4 \x94]\xb1\xebr3C\xf7\x9bS\xea\xd0\x85\xf2\xb9\x03l]\xc4\xae\xca\x04\\\x0c\xf8p\x90|\xdeF\xb6\x84q^IW\xca+\x10\x91\xb2\xaa\xda\x96\xff\x04^\x90\x14^^C\xf3\xc7\xa1\xa80\x95o\xa6\xf5P\xf9\x13#^n\xb7i\x94\x83\x17[\xa4e\x89\x1a\x8e\xaf\xf1\xde^\x8dC\xf0@\xbf\x01\xffd\xfeH/\x17\xe6\x84E^\xa1\xfb\x12\xaea\xfe\x08\x15\xa5a\xb7!\x86\x19\xb1^\xc7\x91\xc3\xc6\xef8\xa0S\x96>@\xeb\x1d\xa0\x0c^\xd9\xe6\xca\xc1\xa7\xe5\xd03\xc9@,\x0e\x9a\x04\x01^\xfb\xd5\x00\xd7\xe94\xe14\x0b\x14\xa9\x1e2c\x1e_\x1f\x84\xa2\xaeF\xf2\xe7\xe7\xab\x86-\\Z\xf9h_M\x9fN\x16\xf5R\x9dHi\x9a\xc0\xa9\xddIi_O\x18\\\xb51\xb4\x8b\xc9\xaf\xc6~\x98\x8d\xce:_gC\x1e\xe2\x17tC/\xfb\x7f\x16\xa6*\xc4P_\x81\x0b\xac\xf6\xf0qIF\xce\x00\xc7J+@\xaf_\x8d4\xe1\xe8\x11\x8a\xf7\xdb\xccg\x85E\xeaO\xf5_\x8e5\x9ew\x8d\xf8\x0b\xb8\x08db\x97\xe23\xd5_\x95\xec\xbfv\xc8\xfb\xb7\x931I&\xa7\xeaS\x0b_\xa0\x17T\xf4*I\xcbV\x06\x8ah\xb7\xc4\xbf(`\x15\xbc\xfd\x1f}R\xf0@\x90\x88)\x82\xad\xab\x7f`4\xc13\xe2P\\}\x1cz&\xe4Xo[\xab`5\x06\x00\xb2\xfbJ\\`\x12v\xec\xcb\xc3\x95G`Oi@\x8d\xf8\xbc1\x03\xbc\xb5-\xee\xa1\xc7\xff`[\xaaz\xa5\xd5K8\x90\xabA\xf6\xa5\xc8Xm`c\xf8J\x84w\x8a\xec\x8d\xc3\xf0\x86\xcf(\x8by`f\xf8\xc5c\xe3\xfa\xf6RLp\xbfz\x85x8`\x98[c\xc8\xbe\xf8\xb4C\xbag\xa5\xe33\xb3k`\xb6\xabZ \x1f\xc6\x86uss\xf3\x03\x00V;`\xe8\x9cZ\xe7N\x8a\x06C<\x8e\xc8,D;\r`\xf6\x82E\xad\xa7\xc2\xb5\xb9\xebt\xe8\xb3w\x1e\xfe`\xf8\xeb<\xb0\rrS\xcdF6\xf6=\xd8C\xaba\x11N\x95\x1c\x7f\xab\xc6\x07\xf3\x90 \n\x11\'\xd7a/\x94]o)\xaa\xf9\x93\x1f\xed\xd6\xc0\xd9\xe5\xcaaHG\x1e\x89a\xd6\x05\xa2\xccY\'\xff\xb9\xf6\xc5aJ\xe8W\x93^\x00en\x95\xe4\x9c0\x9a\xfb\x86aM\x9f\x08\x89\x83\x90\xdaT\xd1\x8d\x1e\x9e\x1aU2ai\xd5&\xa8\x1cQ\x94\x17E\x80\xc3]hH\x0ba}\x05\xc5R\xc4\x0f\x19D\xf2\xb2FV\x8c\xf7\x14a\xd8\x90\x83\xebt\x1faF\xc0K\xc6\xf5\x11\xa9\x16a\xde\x17\xf0\xf7\x15\'*D\xbbW\xda\x19w\xa6\xb9a\xf0\x19o\x8e0**[\x8cX\x01\xe0l0rb\x07p\xdc=J\xb9\x19}\x17\xdf\xfbK\xf2\x0f\xd8b\x1b\xeeG\x94\xe3\xa4\nu\x90\x12\x92\xe2T\x80\xcab$zy7u\x19\x93\xd6\x81\x9f\x8863\xe4\xb8b2\x8c\xf76W\xbf\x1d\xfdg:\xbb\xd0\xfd\xc5;bFi\xe7\x84\xe8\x9a\xbd\xdb\xeb\xfe\r\xb4\x1eUObf\tg\x11\xb2vHR\xabBd\x1e\x84=\xd6bv\xd4\xb6\n\x04\x9d\'\xc5\xe9\xa3\x93\x8e\x95\xf9Nb|a-%\xd4\xc8\xeb\xcf\xbe<\xa2r\x9a\xe0\xa9b\x9aH|;\xae]\xbc`\x97\x90\xe9\x8d\x0e\x154b\xbaD\xd6*v\xaf7q\xfdh\x8a7\xc7\xf5\x9ab\xc7+\xb2\xf5\xee\x08\x8b\xff\xe0\x8c1\xadx\xa3\xc4b\xd0\xa7\xda\x17l-\xb2?j\x87G\xdd\xc1c\x84c\x19\x966\x99\xb5FD\x86?\xbe\x81\x94\xa8\xbc.c\x19\xb1\x9dvD\x9a\xbb4\x0bI38\x9f\xceicD\x00,\x1e\x16\x8a\xf8\xedK\xbd!\xcc\xb4v#c\x83J\xbf\x02p=f?\x00\xfe\xcb\xe4_`Zc\x8ck\x1bk\xcba\x85~e\x85=\xba\xb7\xbfPc\x98#GzK\x845\x92\xc0\xc1\xc3q\xf0\xd3Kc\xb8\xcf\xcd\xc8~\'U\x06\xaa\x1c=\xaa\xff\x06\xd1c\xc8\xe0\x06\x84\xae\xa9\x0fd\xb7Te^}\xa9\x82c\xde\xae\x1d\x07%\xe8L~\x9c\xcc\xe35\x8f\xd4[d,\\[\xe2\x12\xcb\x02l\x8d\x19(\x97\xc9<Id9\x94S\x81&X\x99\xb9\x80\xee\xbaie\x99&d\x85H~\x8ceW\x86\xb1\xd5\xd0F\xbe\x08\xfa\xdad\x8e\xa7\xa8\x01\xbf\xbdh\xdf=~F\xf6\xd9 \x06d\xa7@,k6\x89II$L\x80\x0f\xb5\xec<d\xbb)xBw\xe7Fe\x1b\x8ej\x01\x10\xaegd\xd2\xd1O\x82\x00\xc2\x05W\x86\x15\xd71\x10=cd\xdfR\xe5\xaa\xb9\x87\r3\xf3\x95J\xba)\x00Jd\xf5\x042: \x17\xfc\x05Tw\xdd\xc7\xbbv\xc0e\t][`\x11c{@\xc6Ek\x978\xc6ie\x0e\x15C\xeb\xe5\xd8\xe0\x14:\xb6\xe7\xf9\xc1\x11@eKh\xb0}k\x9178\x8cB\xb3\xf7\xf2*\xebe]<\x9b\x99=\x95\xb8q}sS\xc1\x89\xe4xe\x99M\xf0\\[o\xef\xdd\xd9\xc3\x02\xf2/]\x7fe\x9dP\xf0\xe8\x0c\xb7A\x95\x8f\x81\x1eL\x9e\xe7\xdde\x9e\xa7\x07BYw\xa2@\xd0\xdc\x8b\xc4\xca\n\xf9e\xa6\xb2a\xfby\xd4U\xc1\xcf\xe1\x97\xc1+\x05\xf7e\xb3\xc5\x1a\xe8\xd3\xb2\xca\xdaK\x8eP\x01\x1c\x0e\xbde\xfb&\xddC\xcb\xdf\x05\xc4\xf1Z\xd3\xea[\x8f\x0ce\xff\x8d}\xa8\xed\xa2r\xdb\xa9\x10=\xf8\xe4\xfc\x9ef\x13E\x17\xd9\xb3\xc7\x9f\x89R\xda\xe59\x85\xd9\xeff\'\xa95\xdb\xe2\xdf\x1cw\x183\xb3\xc9\xebD\xdbfoZD\x95\x1f\x19l\xb4\x7f$\t\xf0\xb0\xfb\xf1f\x91\xbb5\x7f\xcf2[_\xeb\x1aN\xd2X\x91\xb7f\x99\x93v\x86pcZs\'\xe1\xcd\xa7J\xe8\x86f\xa3\t-\x16\x9bw\x97\xe5\x81\xf1\xda\xeb\xf3jHf\xb9;RrE\x17\x1d\x8a\x1c\xecy\xd6\xa2\x9c\xe8g\x04U\x0cV\xf15\x06\xad;\x04\x114\x9f\xa0\xccgzA\x0ck9\xc40\x10\xd77\xc6\x88\xaf\xac\x8cg\x92\x14\x92}\x81\x9a5\xfc=\xf1n\'>}Yg\xb7\xba\xfb\x8b\xab\xec\xf5\xe0\x98\xae\x0c\xe8\xe6\x96\xaeg\xc8v[\x99\xa0Y\xa6N\xa0\xd7B\x15y;\x04g\xcf2\xc1+\x11\xe8{\xeao&\xa0\xf5#\xe8\x86h\x12!\x100\x14\x80\xf4\x14,\xc7\xc0=\t\xf4\x9bh0\x9a\xa1\xc0\x92\xa4\xcc\xdd\x86\x88G"\x97\x93\x89hxs\x08\x17!\x12gl\xea\xb4>\x00\x18\xae^h~\x930\xab\x16\x9c\x19\xc5\x10-(\x89\xd7\x93Kh\x82\xd3SL\xfdm\x0b\xc3\x91\x01\xcew\xc6ath\x8b\xf7Rj*+\x99\xd0\x80\xe6\x8d\xab\xf5\x88Kh\x8d*/Po\xc6\xeaMg\x88\xf4J\x8a \xb4h\xe1)A\x8d\xe5R\x99V\xef\xbfx;\x89gDh\xe7\xe7\x01\xe27Cb\x1a\xb5\xe4\x04\xd4\xd1\xb1\xb8h\xeb\x85H\x9a\\V\xe5#\x1f@\xe9\x17c{lh\xfe\xe9\x94z\xe5Kx.\x8fg;}#F\x13i\x12/\x0b\xd7D:8\xc1\xc1\xde\xd7(,\xf5\x1ei^\xf50q\xb9L\x81ql_\xbeN\x90\x9c\x9fi{h\x1ff2\xa4\x18\xf1\x80\xd0\xa0\xc5\xc8b\xc8i}\xac\'\xcc2\x93\xce\xef=\xf9+h\xad\xf1\x9ei\x94\x02\x994\xda\xbb[\xfd\xa2\'\xa7\xc9N\x15\xa9i\xc4\xed=\xed\x01\xa6\x9a\xa5\xb1\xfb\x9ax=\x98ei\xc5\xfb\xedSZ\xfe\xafJ\x94\x0eu4"l\x7fi\xf4\x1d\x94\x8e\xc50\xde\x05\xa6\xe0\xa3\xba$\x9bJj\x04.\x89(\xd6\xfc\xbe}=\xabR\xbdY\xa0\x85j(\x0c\x1b\xc8\xbdm\xbf\t\xd3\xa2\xc1\xc8Gf\x05jT\x15\xcd\xdb\xbd\xeb\xefR\'\xf2f\xe0\xf6\x88(jv\t}\xc3\xa3J\xa3\x108\x10\xc0\xd5\xbe\xcftjzy\xcf\xaf\x01\xdf\x98\xea\xdd\x18Q\x13\xbc\x7f\xacj\xb4=y\x1cPo\x9a\xce\x96\x8eIO\x8d/\xf5kY\xe4J=\xe4&\x13\x92m\x0cj\xba5\x84\xd6k\xf4$\xd1\x96\xf3\xd2\x1a2\t\x89Av`.\x0ck\xf6\xc6\x99<ev\xac\x0b\xd4\xccZ)\xfcm\xd5l\n\x92\xf0\xae\x8b\xb5\xd2$\x8d\x80K\xd7O\xb3\xe6l\x1a\xe3"\xfa%\x1e(\xecV\x05\xa3\xad!f\x0bl\x1e\xbd~\xf0x\xe4\x89\xc1x\x06Bc\x86\xe5\xd3l?\xdb\xc3\xb2U\xa4\xdeb0\x99\xd1,>\x00PlAC\xa7v&`\x92\x8c\xef\x15\xd1\x7f\x0f\x17\xealY\x8dwA\xbb*!Q\x14\xffa\xbe\xee\x11gla\xb7\x81\x8b\xf0\r\x14\xb8\xbd2\xea\x06\xe3\xb7\x18lz\x8fJZ\x16\xc9v_`\x97\xb0)\x9b\n\xa0l\xa1;>\xc0\xfd\x08\xcc\xce:\xd4\x84JY\xe4\x86mF\x1e\xd7\x8e\xce\xe4\xb0%Ve\x18y\xa9\x94\xfamQL\x0f"tVdv1S\x11=\x1c\xe6@mS\xf9\x87La\xfe\x8cQ\xdc\xcb\x12\x1c\xfa\xae\x02ma\x98\x95x\xf5\x0c\x83M\xea1\xbf\xbb\xa7V\x99msm\x86(\xd4\xf6\xa2\xa3#\x832\xfa\xeb\xa9hm\x81\xad\x1d\xac\xfd\xf3\x1a\x18\xc4H\xc37\x1f\xa2\xc7m\x84\xd4B\xcc\xf9~\xc4\xee\xa7\xb1\xb9$L\xe3\xc0m\xb1 Lbj,\xbf\x11\xd9\xceJ\x96YU\xd6m\xf2\x00\xe4\xc2\xf8\xaf\x15)\xeal\xd0q\xa6\xe1\xfem\xffX\xdb-"\x1a\xef\x08\x89z\x99\xca1\x1c\x82n\x0b\xdbA 6\xfb\xec\x81\xb6U\xe4\x1d\xef\x83\xbbn?m\xbfG\rqm\x99_\xf8\x894t\xcb\xfan\x87o24%\xcd4\xfc\xf2\x8c\x8a\xd0t\x90\xe0n\x8d\x99\x17\xa8T\xf4\xc7O\xc6Z\x1f\xde\xe6$>n\xba\x08\xa2\xc2\x9d\xb1o\xf0I\x95\xfeB\xf8\x0c\xdfn\xce\xfd\n\xef\xf8\x86\x91\xa5\x95\x08N\x82\xaco\xa7n\xf2\x91\xc2mL\x14\xe4c\xf6\xe3\x8a\xa9\xcew\xd6n\xfa\xcbMcc\x9ag\xdd\xd0\xa8%~&K\xe5o\x10j\xc9\xbcy\x01\x99\nZU\xed\xeaO\x01\x07oF)bf\xae\x11\xfe\xb9\xdf\xd39&O]\'oKd\x14O\xe4M\xbeC\x0bK.\xbd\xb1^8o\xc4\xfa\xc06\xb8\x14\xa8^"V\xe2eM\xe9-p\x05\x07y\x0e C\x00\xe7gG\xc0\xfb\xd2whpO^\xac\x972\xf0\x16\xd7\x15:\xa8[_\xc7\x91pP\x9fy\xd5\xc0\xeb\xcf\x8cn\xfb\x12c\xbaUXp\x95!O\x17V:\t\x00\x99\xfe\xa0\xe6[3Ip\xa5\xc5\xe8\xdc>\x0f\xad2\xd5|\xde\xc3\x06\x97\x80p\xaa\x1e\x18a\x85\x0f\xc0%x5\xa5|\x98[\x1ep\xafs\xffI\xcd-\xab@\x12\xf6c\x87. \xa5p\xbb\xda95\xe1Q\xff4:=d6\xd3\xf5np\xfb#\x96\xe4so\xf0\x00u\xed\x18\x9e\xf4\xf07q\x08L\xe0`\xdf\xa3qU\xaef\xc9\xa0\x8dbKq\x17\xea\x10\x98t\xfd\xa6y\xcc\xe9\x9cp!Euq!\xfb\xf6\x16\x0c\xf4\x996\xd5:\x9d\xed@\xd9\xa2qR\x01\x1av\xb0\xc3M\x18%\x920\xcfxM\xd4qXkE\xed\xab\xd9/6\x88\x8b\xbd\x93\xf9\x1a\xebqi}\xa5\x83\xce,\xd5R?\x11\xb4AN*\x05q\x86\xc3g\xd6\xe7\xb0\xdc\x17\xf5\xae\x80\xc8_cMq\x8bIG\xac\xc4Q\xc3\x03\x00~+\x85\xcb\xbe\xaeq\xb3q\xd0\xc5Cd\xd1UN\xde\xa2\xe6k\xb1\xa9q\xd3A\x10\x9c\xd0\xe9p\x95\xe3\x8au\xc3\xf1ihq\xee\xe7\xf0\xb6!\xbb8jHo\xfaJ\x8au\xf7q\xf0\xcf\xfa\x84X\x07\x9a}\xd0uh\x92\xa0\xcfGr\x00\x18\x8a\xc5}\xfb7\tZ\x91\xdd\xbd\x06\x8d*r\x14\xd3\x00\xdc\xae\x15a\x18T\x1cv\xc4\xcb\x8a\x03r-\xca\x1b\xdd\xe8\xf2C\xfc\xbb\xe1\x00\xc1],\xb5r@o\xe7\xdf\xd0\x07\xe4T\x1b\xede/\xdbFgrM\xf16\xe7\xe8\xc6K\xf8\xe0\x91\xd7|\x94@urR\xef%\x81gx[\x1b\x8c\xed\xa7~\x8e=]ra\xf5\xacQL\xa5\x87\x93\x08\xce\xfe@m\xbc\x11rc@\x82\\\x9d\xe2\xee\xf86n[\xbe\x00#\xcdr\x7fB\xc3\xb7\xa0\xe3\rR\x051@\x0f7\x88Hr\x96"\x8d\x1a\x8f\xc2\xda\xdc\x01\x7foC\x7f\xf0\'r\xb9N\x9a#\x8f|A/\x9e\x96\xe4\x96\xa4\x87\xc5r\xcb;\xba\x8e\t9\xc4\x814|+\x91n\xbd\x07r\xd6\xe2Pk\x02L\x84\xb3\x9d2\x8e\x1f\x10x\xc7r\xe6\\\x8d\xce\xcc%\xcc\x1d\xfa?esM\x1atr\xf2%s\xc1\x7fU0q\x9f3\x87`Bz\xc6r\xfaUr\xea\xb3\x9ec{%H\x98$\x1f/\x85s\x11t|\xea\xfc\xbeO\x05\xe1Zr\xf0dd\xe2sE\xd6\xa9\x9av\xe3V\xc0kE\xfa>\x87\x1e\x12sQ>\xb0\xb8Y\xd1pS\xed>3\x8c\xdfE\xb9s{|\xebGZ\xe0\xd4h\xce8&a\x05\xa5.s\x85*5\xa9P\xb4\x99\xab\xc5i\xd0\xec.Ags\xb5\x1d\x13wh\xa09\xbb\xb2\xf7\xff?"Jus\xe8\xc5\xe8\xd6\xb5\xae\x92r\xb4Ri\x1c+\xaets\xfa\xa1\xa1`\x82a\xcc\xa56\x93\xd8\xaa\xb4\xcc\xc9t\x0ckJw\xcfkC#\x8b\xaa^\xc0\x16H\xe6t:\\\xf0\xfdl\xbe&\x92roR\xf9\xad\xbe\xb3to\'\xc2-_B\xb5\x8b\x9f\x9d\x99\xfc\xa9\x080t\x9aM5\xf2\xf6\xde\xdfE\xce\xf4\\\x8a\x00\xb7\x85t\xa9R\xf1\x08\x8c%RD\xafP\xb9\xebPE\xcbt\xcf\xc1\x11TZ\x16t$z\xca\xa0\x17`\xda\xa5t\xf4O\xdc\x07+\xd0s\t~\xe4\xe6_Y\xc7\x97u\x0e\x1f\x96eJ\xecP);\xa2\xba\x92\x10\x88\xdduu\x17m\x0ei|\xd0\xdb\xe2\xd2ieh-Du\xa4;\xc0\xa2.\xfaN\xc2\xe8\x85a\xc0\xa8k\xf7u\xf5,\x17\xd1\xab\xee[n\xb8z\x84`\xd2g\xf5u\xfeb\xfdGLEm\x9a\x05\x8f\xd5$\x18\n\xfbvRD\x00ktLN\x1c\x89\xae\x03\xe3\xe6a/vs\x1e\x93\x00\xb0\xf5\x08\xa0a^\xf8\xb3\xa4Q\x17v\x83]\x1a6\x80!Az\xd6q\x92\x15\xd2@\x1bv\x90\x03\x9b\xe3\xbc\xc8\xa6A\xd2\xd5>\x01\x16I\\v\x9c\xf7\xc0\x80\xe0qW\xdcgQp0\xcb\x8f\x9cv\x9f\x95\xe9\xa6T~\x06\xcc+uT\xdd\x86\x10\x9av\xab?\xbe|\xb3\'\xb0\xb3\xf7\x0e\xbe\xb1\x86\x0fev\xadEV\x8e\x81\x97Yo\x86d;4\x99L\xc7v\xb2\xbc\x90\x1f\x8c\xe7-\t\x91\tDK\x96\xe6\xadv\xb7\xdc\xb4<\x94\x85\xb9\xa7Ov\nI\xdd\xc9\xbbv\xbf\x02\x05[\xdb\xe2\xd5&ti\xde\xa3Z[\xd5wI\xc2e}\xfc\x1eM\xa5\xac\xb1,k\x9e\xc3\x8cwg>\xd0\xaf\xb8S\xc6a_\xd7E)e\x96Bwp%.\xf2\xa3\x97\xfc\xd0z\xc0\xf5\xca\xfd\xce\x8dw\x93h\xc6\x9547<YU\x98m\x88B\xd7dw\xa0\x9a\xabE>\xf0\x89<L;\x96\xa5\x82\xb2\xffw\xbc\xa30\xcf\x11\xc84gh\xfa\xf2\xa4\xed\xf3\x81w\xdb\xaf\xcd}\x03\x05b\x8e\x06\x86<\x7f\xfa9)xC\x18\xe6\xc3:\x96\xa2\xcd\x17\x80\x90\x7fp*3xQ\x14\x8f\x19b\xb8\xf1\x94\x12\xd7f[m\xbe\xb4xR=l?\x0f\xb0;\x10\\=\'\x19r\x8bwxX\x063\x87%yM\xbb\x7f\xae4k\xf0\n\xd7xX\x8c.\xc8s\x0c\x82\xf5X\x9d\xe6\xf9f\xad\x03xyg\xb2\xcfV~\xf0\xde\n\xf2\x81\xba\x9b@\xbbx\x89\x8f\x05\xc4,;\xad&\rp\x1e5\xa2\x8e\x99x\xc4\t\xa0\xc8\x10*\xb0X\xda\x8d\xc4MF\xa3\xe6x\xc5\x9d<<r\xcf@\xb7T.\xd2\xa2!\x06\xaex\xfct\x8fW\xf4\xb7\xdaJ6\xcb\xf9\x0f\xbb \xd3y6\x08Bf\xdc\xc5\x9b\x0b\x15DR\xd5\x17\x87\xddy9N54\xb2n\xfb\x95\xaf\xfd}\xda\xe5\x1efyX\xa3\xacj\xdfQ\xac\xf5\x81=\x89\x19\xf2!Byr\x95\xb1O\x1047\xb6\xd7\x8c\x9b\xde\x9d\xff\xe2y\x81\x01J\x80:5\xe9l\xd7.Bj:.\x8ey\xa6\xd0\x9b\x99\x94\xafj\xe9\xbd\xbc\x93\xe5\x12\x1d+y\xc3\xe42J{\xa9c\x19\xc7\x1e\x15o\xe12\xfdy\xdc\xaf\xc2\xee\xde\xda\x94e\xdb=\x9a\xdd0\xb1Ly\xfb\x949t\x12\\Sy\xc4;?\xf3R\xd4\x86z.|\xe8\xfa\xca\x7f\x05\x02\x9d\xb8\xf7PuD\xdbzR\xa64\xe4r[\xb4\xc4\x12Oy\xf6\x8f\x08\xdbz_\xbbT*}V\x01\xb6\xcb\x8e:\x8a\xad\xfdQza\xc100\xfeI+\x95]\x8d \xd8\x91\xb6<z\xa2k\x03\xc2\x90qd\x83?>\xe1\x13\xd8\x0e9z\xb9\xc5\xd9(\x1cq\x11\xec\xe5\xd8\\2}C@z\xbbe\x83\r\xf6l\xf4\x85.\x15`R(g\x05z\xd1\xda\xfbg\xb7\x13\xccL\xfa\x10Y\xc7\xee9yz\xf0\xb3\xbf\xa0p1\xb34ol\xa1\xb5\x84\xb4\xca{\x18\xe2\x13bW\x9b\x96R+r\x1e\x02\x92\x83u{%\xa3\x07\x88T\xc0\xd0\x94\xd0\x1c\x15Q<b\r{A4\xd1&\x97\x9bp\x8f\xe2<i\xf2\x11\xdaj{x\xcd\n\xbb\'\xf5\xb8\xc3\xe6S\xbf\x829\xea\xb7{\x93\x86x\x8aJr\x02f\xe81or$\xbf\x04{\xb6X\xf5\re\x8c\xe2\xadE#\x1c\x11,\xf7D{\xc1*V\xe6X-\xc3\x13\x99\xa0\xb1i\xc1/\xc0|\x03\xb8Bl\xf4<\x9e\x07e\xb2:\xd5\xf7;\x08|\x12A\xf59(\x9a\xd6l\xdd\xc5u\xf1/\xee\xe5|%\x06\xae\x9e<^/\xb3\xee\xees\x1f\x90\xe8o|/{\xff\x9f\xe4\n\xd0\x93\xd2e\x03\xb1\xbc\xee\xbd|A\xb5?h-\xb1\xf6\xb5\x80\x15\x9c\x0e\x0e\xa5\x18|D\xb1\x9a\xfb\x0e\xa5\x18\xc7\xd3c\x01\x81^oB|V\x8d\x97\xb4\x03\xb3Z`#aO\xa5\xed\xd8\xb1|Z$,\xc8\xfc\xce\x95\xdd\xce\x11_\r\xc11\xbc|o\xaes\'\xcc\x97\x9c\x1c\x19\xc5!:t\xfc\xb0|\xa5V)\xe5\x0e_\xa0\xed\xd2\xb1\xcbJ\x07\x98\xd2|\xcdh\xf1\xcd\xce$\xd4Do<\x83\x0c\\V"|\xdaN\xe1(\xaa\xb9\x80\x06\xb9L\x1c\x87\x98E\xd7|\xff\x9e\xe1\xed\x15\xa4\xd5\x97z\r\x9e\nj\xc0N}\x14\xea\x14\xb1nw>DY\x9e\xba\x89\xea\x95]}Xg\xfc\x03\xf8\xf9\xfb\x07\x18`\x8c\x9f<\xf9\x9a}b\xceS\xda<\r+Q\x16Db\x11\x8c\xae-}m\xa5,l\xaa\xf8\x8d\x80\x9d\xfd\x1d\x12*\xdf\x95}\x7f0`By\xcb\xb1\x8e\xe4}\xfd-\xe5\xe9v}\x99\x1b61\x10\xc0\xe2!\xe5\r\xee\x87"\xeb\xc7}\xb3)d=\xc8\xf6\x05\xa9\xd6\xb1\xa5\x1a\n\x98j~\x04\x0f,6:\xda!\xf6`\x83\xf1\x86<\xd2\x94~\x1c\xbd.\xd6\xff~t!\xedG\xdc\xbd\x14\x03M~m\xd4\r\x10\x15\x86\xa0f\xd4\x08\\\xff\xa9/t~s\x18#\x06\x82e\xb4\xee\xce\xbe\xe2m\x9f4\xd3~\x9fdM\x90d\xd4\xfa\xc1\x1dA\x85\xec( \xe4~\xa6\x16\xb8\x10\x19\xa4\x88\xb2\x1ds\xc3\xe18`4\x7f\x02\xf2,\xf7\x90\xbb\x9a\xe32\xf4U\x1d\x87*[\x7f\x0bZ<\x86\xb3 @\x8cl\xcf>\xa0\x14y8\x7f\x10Xkf\xaf\xb3\x8f\n\xc4\xd0\xe5}!\x8b}\x7f0\xbce\x9b\xef\xe6\xbc\xb8\x160\x0f\xbd\xdf\xe2\x8e\x7fB\xea\xb2\x9a@ \x82~\xa8\xfdC\x17\x8d\xc9\xbe\x7f\x9ak|{\xf5<\xe9\xcf\xc0\x85\x07+\xa9\xf2^\x7f\xeb\xfa\x07\xee\x8c,m\xf4@o\xd8\xf2\x1e\x80\xde\x80\x1c(o0\xcau\x07\\\x9e\xd1\x1d\xe1~\xa2\xf9\x80"\xa4z|N?\xf1\xf7\x04\x91U\x9b\nD\xdb\x80h\xd3\x9f\x93\x95\xdd\xd6\xdaU\xac\xb4zo\xceh\x80\xb2*&\x8f\xc3>\x9e\x0eg\x80}\x80"W\x8f\x80\xfaC O\x85\xe7\x0fc\x89\xf9\xaaK\x0c\xe5~\x81T\rs\xd1&-\xb3\xfd\x89\x04\xb8\xc6\xfd\x99\xb4\x81\xa3\xd5\xfd\xb2l\xac*\xb6@\x99\xf3l?\xed>\x81\xc7\xbc\x7f\xc8#\x84\xfd]\xedMW\xf8H\xaf\x1c\x81\xd8\xb71\x01\xd7a4\x7f\xa1\x19\xd0\x8b\xce\x00\xff\x82"J\xfa\xe0\xb9f\xba{\xf9,L5\xae\x0b\x0b\x82#<\xb7\xa0$\xa1\xa5\xb2\x83-\r\xa4<d\xbe\x820k\nG\xfb~\xaa>\x94*\xfe\r\xc5\xe5P\x82\xa4\xb0\xe2\xc0\x13CM\x05\x1c\xfc\xe2m\xa8\x92Y\x82\xa5p\xd0\xb1Y\x0co\xa0$\xc6[\x8a\x83\xc0\xef\x82\xec\x8fsOJ\xd2I\xfbKd-<%z\x96\x83\x171lY\x9c\x92xl\xff\xbd\xa8\xafS\xec\xc3\x83a|\xab\x8b\n\xe1\xe2\x06p\xc4YC\xcb\xb8\x0e\x83m4S\x88\x01tOoK\xdc\xc8\xe82\x18d\x83\xa7SQ=v\xceA_v\xc4*\x13\xfbFQ\x83\xb2\x05\xddz\xae\xccq\xae.\xdc\x99\x07\x9c\xe8\x12\x83\xfd\xc5\x9a1h\xdeG\xecrB\x89\xc9\xd4\xa5m\x84*h\xd8\xa2v~\xef\xb6\x04\xdb5\x01\x98(Q\x84<\x1e\xfb;S\x96\xe5\xff\xfe\x85Y\x7f\xc3[g\x84=\x8c\x01H\x84\x1bD\xb1h+\xaf\x92&-\xac\x84O(u\xd0\xeb\x00e\x94\'\xf1\xce{r\xe0\xca\x84P\x8c\xc1\xa4\x16j\x1a\xe2\xc2[\x92P\xb9\xa6\x08\x84_U\x85\xc4\xd8\x8a\x1c=5\x13\xe2\xea\x01w\xb2\x84\x8fX<\x0b\x1a\xc9k\x07\xe0\xa2!(\x84\xd7`\x84\xa2O:\x1d#\x8b\xd1\xe1\xb0\xc4\xec\\\xc1\xb7\xe7\x84\xd3\xdd\xefn\xf6\xca\x85\xb73\xee\x19\xef:\x00\xe5\x84\xed \xe0l]f\x0b\xbf\x0cn\xcb\xe6\xd6i\xae\x84\xfd\x9e\xa6\xc1\xa1\x9d\x9d\xb8k\xf3\x89\x15\x11O\x13\x84\xff\xdf\x1d\xd5\xad\\\x0c\xc6\x8d\xeb\x13\x86\x94\xb1\xf5\x85\x04\n\xe1\xaa\xd9\xce4\xa0T\x84z\xd1`YC\x850\xe8P\xf6<>@\x1f\x04\xbe\xedf\xa4\x9bb\x85e@\xfb8\xf1\x84\xca\xbc\x04\xaa\n \xf6\xb7I\x85oO&\xad2\xd2R\xf5\x831\x90\xe8\xf9\x06U\x85\xd0\xfei\xd0O\x9aGg\xd7\xcf!\xe2`Iz\x85\xf8Ph\xbd\xa1\xbe\x19\xbc\x9f\x8c)X\x0c*\xcd\x86\x0e/\x8e\xf6\x1f9\x0f%\xb15M[\x1aa\t\x86:U\xa9|\xc5\x94\xb4\\1\xba\xea!9$\xd3\x86L0\xfa\xb2q\xae\xe5\x93\xe9\xdf\xa5\n\x88\x98\xec\x86c\xd3\xd5{\x18G\rT\xa8\xf9W\xb6\xd2\x8c[\x86\x85m\x9d\\G\x95\x03`ma>:z\xe8\xca\x87+\xd1X\xd6H\xa1\x1a\xdbZ\xd6A)\xbbY\xd3\x87t\x1d\xfe\xe4\x8aW\xb6\x8b\xe0\x90$\x1a\xfbx\xa7\x87\x86\x8d\x13\x1f\xcaa3{\x9a\x82\xc9\x1aD\x1f+\x87\x95n\xaa(8\x08\x90\xe7\xda\xd8\xfc\x84\xa4\xa9\xc8\x87\xa1J5\xba\xe1\r\xaf\xedF\xfd\x8a\xc0\xe6\x89,\x87\xaf"9\xfc\xf7\x9f/#D\xa7\xce\xcf\xc7oe\x87\xbe&s\xd2K\xc6\x80\x8ci\xfa%?F`%\x87\xdd\x03\xb6\x05\xd7\xbbGi\xeb\xa5\x82&\xbb\xea\xbf\x88\x01U\x90m\xd47e\xe630K\xd4q\x9c\xa2\x88GK\xf6\xb7\xc1R\x92\xb5yTfu1\xd4\xf6\x88Q\n\xc2\xb2\xaa2\'\xc0p\xdb3\xfc\x0f\xe2\xff\x88U\xa1r\xa5\x1f\x96\x87\xc4@\x0e\x1fO2yi\x88\xc5 U\xc5\xc9\xceO\\\x0b /\xe8M\xe2\x82\x88\xe2\xe7\xebV"\x0bnx\xb4\xd5\x1c\xd2D\xc6+\x89\x0e\x06\xd2n@g\x1e\xb9\x83\\\x03\xf4\xa3R\xa6\x89"\x9eEEJ\x9d{\x10\x10\xef+v\xfa\x81h\x89*y\xe3\xe7\r\x16\xc8#[\x01&\xf5\x06/\xee\x89HL\x13\xban\xdf7O\xe6S\xcdN\x031\x1d\x89gM\xdc\xb4\xef\xb6\xcb:\xcef<$\x96\xf3\xc6\x89q\xb0\r\x1bc\x9c\xb2\x1a\xb0\xc4\x17\n\xd1rt\x89\xb2\xbal\x91\x8a_R\xf8\xf0\xa8\xe4\xba\xa9:\x92\x89\xc58P\xe6\x9f\x9d\x17\xc2\x10`\xf6:\xa0x{\x89\xdf\xafO\x1dc\x86\xc9=gf\xd6\xaf\x93\x93\xbb\x8a6\\d+\xdc\xef\x1b\x90\xf6G=# \xdc\xe7\x8aWXdx\x9a\xe5\x1e.y\x98\xd7\x963D=\x8abl\x19?\x19D\xd4\xc1\xd6\xb4\x0f\t\xe5O\xf4\x8a\x96\x8d\xa6I9\xffmN3\x90\xd3\x19\xfb\r\x02\x8a\xb8g\x17\xfc=\xe1\xa0|\xbf\xb1\xf0p\xe7\x08\xe3\x8a\xc4\xd5_\x96\xd8j\x92\xba\xe0\xbb\x19\xf0\x80\xf9\x1a\x8b\x05\x8e\xb5M\x11=)\xf9\xd3?\xce \x91\xb8\x0f\x8b)t\x03\xe6\x0f\xcf\xd2<\xa2\xbd/G\x84\xdd\xc7\x8bQ\x96mbZ\xe8\xdc\xc4\xa2\x80\xc3\xbe\xa42\xf4\x8bX\x18u[e\xc9\xa9\xf2\x18\x15e\x98\xbd\xf2\xf6\x8btwTz\xf1\xd9\x99\x8b\x0e\x1d\xb8\xa9~>\xe4\x8bz\x7fD\xb2ZR\xea\xf7\xdf\xe09\xa7IS\x01\x8b\x81\xc1\xc8\x11\xda\xb5G\xb3\xff{\xa1\xfdbd\xaa\x8b\xc5<4\x12\xccFr\x18i\xd1.J:\xea\xdb\x8b\xd8O\xf69GZ}\xab\xf5x\xd8.#3u\x8b\xe5\xee\x95\xd7!F\xad\xd5\xf0\x17\xa1(q\x81r\x8c\x14\x9aT$\xbev\x8b\xef\xf5\xa39\xb5\xec\x14\xe3\x8c!d\xb3\x93jh\xafT\xa4\x18\xaa\xd5\x01\xf9\xf3\x8c&!\x0bo\x0b\xc6\xf4\x92\x1e\x99\xa9\xc4\'\xa3\xd5\x8cfM\xf9(\xec\xf4B\xb6\xe2\xaa\n\xe2\xc5\xb0\xf9\x8c\xc0\x00Z\xde)0\x96\xd6v\x83\x05\x05\xa2\xaar\x8c\xc7\x1c\xb9p\x9a.\xb0o\xf8\xd5\xd9\xbc"\xbe\xc1\x8c\xd3\x19k\x7f\xb9\x7f&|\x13}`E=\xf3\xcb\x8d#\xf4\x9b\x81\xa2\x04\x9e~b/q\x95\x7f\x86\xc8\x8d,\xd3\x19~q\xa1\xf7\x8c\x89\n\xd15\x11\xc8\xfa\x8dE\xe8<q\x1dP%v\xf0\x18` A\x0c\xe4\x8dYl\xd1\x83\xad\xbcE\x1d\x86oK\xf2\xe0\x0e\x07\x8dnY\xbb\xec\xe6\xe0\xe1+\xc9\xcb7\xad\x8a\xd8\xcc\x8d\x8b\x990b\xe3{\xdc/\x8dV\xd2Z]\xbc\xb8\x8d\x9dJ\xec\x93\xc0\x0edW\xf0\\\x8a4\x96\xac\xe8\x8d\xe9{\x0cIln\xc2\xcdp)\'\xa5\xca\xf3\xe3\x8d\xf3\xcb\xeb!"\xd0\x9c\r\xae\xdam\x974 w\x8e\x07\xa1>\xdc\xc2\x9clv`\xb0\xb1\xb2\xf8\x86\x80\x8e\n\x8d\xf6<\tRq;\xb4\x82\xd5F\xc1@\xd9\x8eG\xd9*\x90\x89\x19\x05\xa4y3\xd4\xf3\x01\x84\xfc\x8ec\xb8\xf5\x8a\x1c\x1d\x8a\xc7\x9a*2&\x9fm\xf1\x8e\xdf\xdc\x9fF\xb6\xb0u\xb2\xebB\xa2\xa3\x87\x13\xd5\x8e\xe8\xf0\xbd\x0e\xd0?S\xe8\xb7g\xb4/\xaff\x89\x8e\xed\x9e\xba\x0e\x9a\xce\xb3\xa0\xf6t\xd5\xd6\xd0\xb5\x9f\x8f3/\xee\xfc)l\xe1\xdf\xd8\xd3\xe8\x9au\\\x02\x8f6\xa0y$\xbb\x15\x0e\xa3\xc4\xd2P\xc7\x16r\xfc\x8fI|\xa0\xe1\x10\xc8\xdf\xad\xce\x9f\xa5!g\x99\xbe\x8fN\x94\xcc|\xbe\x86\x8d;\xd2\xa6\xd5\xde\x18\xfdA\x8fR*5)\xf4)\xfeP\xd2z\xcd\x8c\xda]h\x8f\x8a\xe1\x17\xbc\xd0\xfb\xaf\x870\x81g\xd5\xc2r\x8b\x8f\x8cg\x12\xc1+CC\x1e\xc5\xff\x04t@\x8d)\x8f\xfc\xd5\x88\x80\xaa\xf3R}\xd6\x96\xe7~\x81\x90-\x90\x13\xff_\xe2\xb4\x924\x03\xd4\xfd\x96[\xc9q\x15\x90\x1c/\xe0\xc3\x05\x85&\x15\xe2\xe8.V\xea\x07o\x90/\xce=B+\xfd\x0bn\xb5id\xfe\xf2p\x03\x90c\xeb6\xcc|\xb3y\xda\xdd\x84AP4\xaf+\x90q;\xd6\x18\xff\xb0\xf9\t(\xb3\xf4\xdd\x8beh\x90\x99\xd9\x9dg\xfb\x0fd$\xb1\xb3\x8b\xa8@\x9c\x19\x90\xba\xc8m\xa8\x8b\x89\x1b<1\xa3P\xb5\xc3\xcaS\x91\x16\x97\x82L~\xb2TO\xf8\xf7\xf8\xc2\x03\x80X\x91\x17\xb4\xe4\x881\xf1\xbc\x10g4\xfbh\x1a\xa3a\x91\\\x99\x92\xf0\xd68\xa8\x0b\x96#\xbb\xa5/\xa0\xa8\x91\xb5Ns(\x9e\xad\x8b\x99}\x9f{l`Hz\x91\xdc\x98\x877T\xb8\xc4#\\\xb8\x90\x16\n-e\x91\xe0\xaay\x85*\x05\xa2\xf3\x9d\xc9\xa2\x0c%\x1c\xc1\x91\xfc|\x12\x0c\x0f\x01\xbc\xb2\xe4\x8cN(\x1f9\xab\x92\x18+\xbcQJ\x0b\r0\xfe\xd1\x8e\xa0%\x8b=\x92)\x0e\xbfvl\xcc \xef\xb4\x0fQ\x92\xd93\xdc\x92@m@\xea\x1c\x8f\xbc\x04\x97\x1eU\xd6\xfa\x90K\x92I\xd3\xcf 3Yg\xba\xc0\t[Ua\xe1\xaf\x92\x86M\xd9\x13]\xac\xbeQKB\xd5\'\xafAO\x92\xad.\xf7\xda\xef6\x19)h\x8fu\x8dA \x85\x93\x06\x98\x070!\xce\xe7\x08\x9e>\xe2\xa0/\x0f@\x93\x0e\xe3M#>-\xf2\x8a\xe7\x94\xb4\xced\x9c\x9d\x93\x14 &\xf4\x86\xfa\xef\xc8\xb4\x8a\xf5s\x8aW"\x93R\x1a\x8ba\xbbLFb\xe7\xa3G\x92\xc0\xd3\xfc\x93j\x1fGC\xb7\x1c\x8d\x93\xba\xfd\x9e\x1dNc\xab\x93~\r\xe8o\x7f2\xce!f\xf3\xd8s\x03|\xd0\x93\xb9\xbaS\xc7\xf3\xf9l\xd1\x7f\xc0;\xe3\x8dw\xbd\x93\xe5\xfcw\x06\xb4\xbc\x02\xe8\x99\xc1\xee<\xcd\xde\xb3\x93\xeffj=\xb2F\x1d{\xc6A\xf5\x1c\xee\x9eI\x94ef\xc8\x1a\xe4\xc4\xd9\xab>\xcb\x7f\xe1!w\xea\x94r\xb8\xd6\xdb\xf5v9I\xe1\xb3\t\xe5\xdb\x15W\x94\x9eAP;\xa9\x82\x81Yz\xb3\xae\x00\x05\x16P\x94\xb0%\x8ekG\x18>\x838\x9f\xe1#\x94\'#\x94\xbeu\x0b\x96$y\n\xd1\xe1w\xe5w\xdeS\x7f\x957\xec0\x10<\xcd^<|NW4M\xb6J\x95C\xf6a\x88\xd9\xe6\x83Y\xe81\xdc\x9f\x9cN\'\x95S\xfc\xc5B\xc3\x9b\'\xc90=\xc4\x00\x18\x88\x00\x95\x8a\xe0?\xdd\x1a%\xbc\xe62\xafS\'_8q\x95\x8d\x1f\x1c\xe4\xceK\x14\xf1yr\x18\x06\xb9\xdd\xc6\x95\xb9\xbd\r\x8a\xd8\x9e\xb5\x0fBa+\xc6\xa6\x8a\x11\x95\xc0\x0fS\xd8\x9c\xd55L\x06\xb8\xa3\xca\x0c3\xca\x95\xc8\xe7\x00\xe1A\x99)\x95\xd6\xd1_\x02W\x8b\x86\x95\xd0\x05y\xc53\xd7\x8d\xff\x0b\xae-n\xd3\x8eh\x95\xd1\xa7\x19\xc3\xf8\x10s\x85\xfc$t+\xad\x11e\x95\xed\x0b\x1b\xcf\xb3w\x109\xb3\xb3VQ\xa0pY\x96\x10\x10q\x1e&\xb5h\xd0\xf1\t\x93d\x11\x01D\x96.\x84\xe9\xd7\xdb\xc3\x92\x141\x95\x84\xa8pjx\x960W\xa4\x8c\x1f\xd0\n\x91!\x9fd\x0e\xba\x80\xba\x96[\xe7*\x01\xe2\x08\xf3\xc6\x1d.\xf4\x99B\xb6\x7f\x96d\xbf\xaco\xe0\x99\x8ft\x9f\xb7"b\x1bh\x86\x96\x8c]\xd5,ren\xacF\xaf3\x88\xd5\xc7J\x96\xf8}\x14\xc5\x00\nT\x97b\xf1v\xbb\x1bm(\x97\x16\xa0\xe7e\xb7N\xc0\xbe,\x92\xc1=\xb1\xa9\xc1\x97\x18\xe2\x88\xc2\xf3O\xde\x87,>\x9c;\xc6\xff\x0e\x97:w\xe91\xec\x98\x83\xfe\xb0$\'\xceS]\xbf\x97C\x9a\xa9?\x88\'\x84w\x85\\0$\x81d\xc9\x97G\\\xab\x0bw\xe0|VoR\x99\xe1\xb6\xfd\xc0\x97\x87\x8fl(\xaa]L\x04\xc7@\x84T\xef\xc4\x7f\x97\x92a[\x0f\x91\xe8(I\x83\xb6\x81\x97\xc6\x80\xdd\x97\x9d]\xea\xc1\xd20\xea\x01\xad\xbd\xa5\x0bmI\x87\x97\xa2\x084\x9cG\xeb0\xe3\xe7\xd1\xb6\x1d\xb1V\x96\x97\xd6&\xc7Czj2\xcbk\x93n\xcd\xa2_\x14\x98\x1a\xcc\x0f"\x13t}\x0b\x9b\x1f\x1b\x97t\x88\x01\x98G\x9c*\xb3.\xdd&\nijs\x949\x0f\xe2\x98\x7f\x03\x8e\xd0\xff8\x95\xa8qs\xbf\xdd\xe0M\x96\x98\x9f\xe5c\xea\xb2\xec6\xea\xbd\x95\\\xb5\'\xb5f\x98\xa5_C\xedc\xa3w0\x9c\xaa\xc8\xf9\xb3\xdf\xc2\x98\xd7\x17.\xd7;V\xeb\xb1@\xf8\x9b\x05\xfd^\x8b\x98\xe2KQ\xd6\xd9\x88\x1b\x08\xfe\xd9\x1c\xc8\xe5;\xac\x98\xff\xb8f\n\x83\x8fLB\x0e9\xa29\xf331\x99\x0f0\xeeb\xe0p\x83\xac\xf1E\xf0\xa7\xb0\xf8\x81\x99\x0f\xed_R\x05\x1ah\x81\x0f\xab\xdecTP(\x99\x10\x87\xd7\xdc\xd2<\x19c\x97x`&\xa9\x93\xbe\x99VH\xa3\xa5\r\xd1\x81\xe0\x89\x17@T!\xf2\xa0\x99h\x04\x06C\x88m4\xe0\x853mL\xd7Z\xcf\x99k\xd3~t\x1c\x1bq\xb2\xe8\x9d\x95\xb2\xb3\x16}\x9a\x03n\xe3\x95p\xc58H\xc6\x9av\xb7d\x9d\xde\x9aY$\xe8\xe9\xe8\xaf\xdc\xe8\x873\xdc\xd9\x9f?q\x9aY\x7f\xf6 aU\x81;\x94\xde\x13x\x1c\x120\x9a`\x85\xf6\xa2\xc9\xb9\x94\x9b\x82\xd7\xda\x9d\xbb\x1a\xf0\x9a\x9e\x10:\xaa%8\x89\x9b\xbd\\\xd5S\xddr\xb7\x9a\x9f\xbb\x8do\x1f\x08\xf9&0\x15\xe7Y8r\x0e\x9a\xa9\xd4Yji[\xa6JR\xf1G\xc2i\x87\x99\x9a\xd0\xd2!\xa3\xa0\xa0H\x06\xa1do\xda\x84R;\x9a\xd3\x83\x1c\x99\x19\xf1\xdf\x81\x8f\xe9\x1c;\xc3\xda\xae\x9b\x01LeU{\xe9\x8e07\xac\xads\xe9\x0e\xd1\x9b\x0e\x18[\xb4\xfc\x1b\x9a\xc4L\x8a,\xed\xe4w\xee\x9bA\x92\xd9\\\x9a\x94\xf6\xd3\xbb\x84WzT\xbc\x11\x9b\\\xfb\xe4\xd9\rI\xd98\xd4]\xeba\xcf;F\x9b\xa3\x17\xb8m\xed\xc2\x1b\xfa\x0b"\xa1?Xw)\x9b\xa3x\xcc\x02\x9f\xa7\x9f\xee7\xbc\x99P\xb1\xf5\xe6\x9b\xe0\x03\xb0R\xe6s\x81\x1b\xad\xeai\xcaU\x17\xa1\x9b\xe6#\xe3s\x03\xd5\x941\x82\x9a\x98@\xf3\xfa\xf5\x9c\x0644\x0bT\x07\xa5\xef\xaf\xff\xf5\xa5\x92\x82\xc0\x9c\x08\x9e\xed\xee\xc9\xff\xfeLx\xf4\xce\xbc\x17E\x15\x9c\x908c[\xd1\xa5\x13\xe1\xc3*\xbd\x93m\x18;\x9c\x94\xed\x00\xffh\xfc3\xa0\xf6\x82\xb7A\x18\x97b\x9d*`\x8b<\xf5\xe4!0\x93\x0f\xa4\xe4\xcc\xc9\xad\x9d/\x03\xa1\x93}\xce\x01c\xcf\xe5\x90\x06\xc8n\x06\x9dVJ\xc1\xc2\xa8\n\x15\xaa%\xc9F\xd6\xbb\xf7\xc8\x9d]\xf2w\xd8\xfc"@\xd8Z\xb51\x8b\x87\x80.\x9d\x94\x01\xe1P:]?\xc8\xbdYNH#\xb0m\x9d\xa6.\x8b\xf4\x1c\xe5\x1f%@\xbe\xdeQ\xff\xc2\x9f\x9d\xbb\r\xe0\x0e\xc5?]C\xac\xbc\xb9\xf0m8)\x9d\xbf\x92\xbf\x8c\x9b$^\xcfQ\x1d\xb4R))b\x9d\xd9\xcc<a\xe3Z\xe8\xb9:\x95\xab\x91\'c\x89\x9d\xf2\x05\x9a\xa3e/=\xdcc\x05\xed\x9f\x81\xd7\x94\x9d\xfd\xa5wy\xfbf\x1a\xb7\xf2\xbe\x02\\\xa0N\x06\x9e\x13\x07\x0f\xfa\xf7\x06.\xf8\xddL\xf2$\xff\xb6F\x9e3qsL\xc7\x90\n\xce\xb1\xea\x19\xa2\xb60\x1e\x9e7\xa5Y\xf3\x93\xa0X`\x8c\xb7\x88\x89\x11\x9dU\x9e]\xb8k\x1b\xfd\x9cY\x87\xec\xfa!\xaf1\x90/\x9e\x8d\xa6\x0b\t\xd3<^\xc0\x7f\x908\xff\xa6\x9e\x92\x9e\xab\x97y\xd8\xce\xef\xe7{d\xcc]\xf7\xb3t\xad\x9e\xb1\xb9\xa1@\x1cau\x9f\x91\xb8\xaeq;\x92\r\x9e\xb8\xf95\x9b\x9a\xff\xbc\xccL\xd99@\x89\xff\xff\x9e\xce\xbe\xd5\t \xc2<4E\xcf1\xc2\xed\xd5\x89\x9e\xdb\x02\x84\xc8Z#$5\xdd\xd46\xf8\xdc>\xe4\x9e\xfd\x87\x91\x02l\x99\x12u\x11[\xba\x13a\xa7[\x9fLl\xa8vF\x9f\x18\x1e8\t\xa9\xda\x12\x96V\x9fc4^3,\x19\x92\x0ceeIK\xa3Z\x92\x9f\xc6\r8\x17\x8d\xa9Z\x18\xd4\xe0\xa5\xddI\x91;\xa0\x17\xb9\x98L\xd3+\x08\x95F\xba\x93\xef~\xe5\x18\xa0\x17\xd1D\x93\x1c\xf1\xb89r\xe5\'\xd0^F\xfa\xa0A\xa6\tT\xd3\x8b(Y9\x97E_2\x88\xa4\xa0a\x06\xb9\xbf4T\x9e\xa8{3\x97SK\x89*\xa0q[\x0fR\xfb>0,\xb4/\xa1\xdf\xed\xfc\xd6\xa0\x93^\xc4\x1cI}=\x0c\x16\x1d>\xcc\x1c\x15\x0b\xa0\xa7\xdeq\xb1P\xa9\xb7\x1e\x1b\xf6S\xdc\xe5<d\xa0\xbb$\xf4\xdc\xd4\x97\xdd\xf7]\x99F\\z\xc7\x92\xa0\xcc\x9d#\xbe\xd2`\\\xa2\x14\x94\x84cCK\xb8\xa0\xe3YD\x91\x93\x8e\xd3\xf7\x0c\xe6\xb3nU\xa82\xa0\xf1\xa9\xf8\xca\xf56\xa4\xb4\xadu\x91J\xc1\x9a\xe1\xa0\xf8\x05~\x97\x11c\xc3\xd4HS\n\'\x91?\x9e\xa1\x03\xd6\xf6\x1d\x99[\x98\xe7\xda\x05.fl<f\xa1\x18q\x9d\xd6\xea\xb5\xd3\x9a\x12Z\xf0\x9dX\xcb\xdc\xa1N\x99\xda\xc0K\xe4_\xea\x1bw\x9a\x9fVz\xa0\xa1U\xbc\x14(\xe8\x12\xf1#\xcbmP\x14\x8a\x89\x99\xa1g\xab\xaeG\xc3\x03\x94\x93HW\xdd\xb8:\xeb\xd5\xa1\x99\xee\x97\x8bL\xcb\xd2\xdf5f\xfd\x1ee\xd7\xbe\xa1\xb35\xca\x9f\x18P\xb3P\xd32X\xb2\x965\x93\xa1\xbb7G\x8d3&6@\x026\x7f(\xb06/\xa1\xc7\x8amV\x9a\xc5|\xc4q\xe54Y\x9fq\xb3\xa1\xde$\xcb\xea(.\xe2\xb0\x88}\xbd\xf2\xf7\xcc\xd3\xa1\xe7\xdc\x91\x87g\xf0oh\r\x86\xc9W&\xcb\xb6\xa27Zc\xcd"){;\xaa\xbeB\xa1\n\xc7M\xa2\x80\x19\xc57\xa5\xe8\xdf\xd7:)\x08\xb2\x10=V\xa2\xad\xe6R\xefj\xb0\xdc\xf7\x86\x1a\xeb\\\xe4i\x11\xa2\xf2O\x02!\xc1*\xebY\x8e\n\x02p\xac\xca\xf3\xa3\x1f\x7fF\x07\xac\xc3\xf8\r9I\x93\x85\x96\xde\xf7\xa3X\xbal\x9e|\x98\x18\x1eoYu7b=\xc4\xa3Y\xf32g]H\xb9X\xda\xcf\x82\xdf\x9b\xd6%\xa3l \xb4\xec][\xdf\xfc\x14\xce\xcd\xf7\x7f\xd4\xb2\xa3\x93\x80\xcd\x9f\n\xd7\x98h\x9e\x1f6\x9a\r\x00\xb6\xa3\xa4I\xcb\xf282\x89IL\x8a\xa0Q\xe1p\x98\xa3\xb14:tIf\xc2vw\xbb\x10\xda\xd6\xa98\xa3\xb2\x9a\xe6\xe2\xd4B\xbb\xfdj\x13\xb4\x8e\xb6\x18)\xa3\xe1p.\xf6\x83\\\x00\xd8\xbd\xbe\x9f{|\x83\xa3\xa4\x17w\xd0a\xa2 ]\xf7\xd8\x1d\xf5s@\xd9\xe6\xa4&S\xda!\nT\xb6\x87O7\xf0\xd4\xa1-\xa5\xa4n\xaf\xa3\x11\xc8&\xb9o\xe1\x18fU\xf4\xbeL\xa4\x89z\xbc\x84\xec4\x94\x83\xbb\xc3\x10\xd3\xa4\xe3b\xa4\x94\x8ex\xc0/\xf6(\xe1\xf2-\xffx\x8a\xe2&\xa4\xac\x0fQ\xb8\xfd\x9e/\xc7\x1f\x99\x9aB\x8em\xd2\xa4\xf7"\xbcL\xaf\xd6\xf2\x03\x85\xf3\xed!\xf6@\xfb\xa5!\x94fE\xbc}\xd1\\\x13[\x8bk\x11 \x10\xa5q;\xe4\x00\xc1<\xb4\xf1;\xbc\xdb\x0c\x05\x93\xd2\xa5\xab\xb1I\xd16\xff\xa1\xf1p\xac\x08\x9c;\x1fL\xa5\xb1\x9f({s)\x15\xbc\x96\xcdv\xdc\x87\xf5\xa8\xa5\xbd\x1f\xf3\xc9-\x1a\x9em\xdd\xcdON\xe8\n\xc6\xa6\x13{\xc7\x85~\xcf\xa6\xb6\x11\xc3\xca\xe8v6\xfa\xa6 \xba\xac\x99\x0c\xd9\xf1u8D\x85\xa7P0\xf9\xa6&\xe8\xf3\x19\x91Fq\xf2<\xdc\x1e\x8e0\xc3\xd5\xa6H\xf3^\x19.\xac\xd3\x87<\x9d\xee\xe1K\x08\xe3\xa6p\xa8M\x04\x10\x99\xa2\xa68j\xbbz\x81\xabY\xa6{\xe1J\xc8LB\x12]\xca/0F\xe6#\\\xa6\xb8t\x1e\xbf\x8f\xa9/\x14\xed\xd5t\x19\x01~/\xa6\xbd\x88\x17fy\xa0\x81<O\x8c\xbc\x18\xb58\xd8\xa7"\xa4\xb0\xc7G\x89\xb8\x1a\xd8D\x9f\xe9\x8c\x8ff\xa7\x95\xdd~\xe7-\x86\xaf<\xbeO\xf5\x067\x8b\xec\xa7\xbc\x9aR\xe1\x16J\xd7\xbbG\x8c\xae\x07W\xfc&\xa7\xe4^\xd1K\xb9\x12\xee\xf5\xea!\xce\xd8\xad@T\xa8\x0fq\x9d\xae#9\xd8!\xa57H\xf9~\xe0a\xa8\x1e\xe0Y#QE\xc8H\x99\xb1\xf8\xf1h|\xd3\xa8P\x80\xb9=\xec\xa2\x87`y\xbd\xf8J\x18\x8f\x8b\xa8\x84\xf3q\x04XNb\x0c\xff\xa9\x14\xe1\x93\xc2:\xa8\xc5G\xae\xfd\xe8\xae\x80\xad\xeb\x91\x17\x19\x07\x15\xe3\xa8\xeb\xda\xea\xc1\xcc\x1b\x9f\xd0\x9e\xcb4\x85lQ\x11\xa9*\x8a5R\xf9\xd0\x83K&\x02\x92\x9b\x84\x96\xa7\xa9mv\xec/\xc4\x80/C^8\xb5\xdb\x8e\x98]\xa9v\xdez\xe2\x11\xfeR\xe7\xd6\xeb\xab\xd4\xb9\x9a\x9d\xa9\x85n \x19\xf4\xd90y\xf3\x18+b\xc8\xec\xe7\xa9\x933\x8d^\xfd\x10\xb4\xcd\x94\xa5\xa7\xd3|%\x85\xaaL_\xeb\xf5\x96\xbe\xb6\x1aVW\x98<i\x81m\xaay\xdb\xbe\x0e\xe2\xe0;\xacB\xa1\x8e\xfc=v5\xaa\xbeP\xc0\xe0\x13/\xcd)3\xa8\xcb\xb3/\xd1\x13\xaa\xfbi{4\x93\xfdC\\\x84\x1f\xbc\xdf\x92O\xee\xab\x00oIp\x110\xcb\xc9\xfa\x947\xf2\x9f:F\xab4\x0b\xfb\xc7\x1fON\x1b\x9a\x01\xdax\xf9\xb2\x98\xabB\x90bd$\xacq\xb5\x946B\xac\x82WT\xab\xd8\x8c\x05V\x0cVE\xb8z\xb0n\x83f\xf5J\xab\xe1\x05\x1a4\x83\',\xf0\x1ar)\xba\xab\x0e\xd8\xab\xe8\x7ff\x1f\xf8\x06\xb7\xcef\n\xe2\x8c\x18d\xbf\xac>a\x9f\'\xbc\xff\xc2j\x0f\x17x(p\xeb6\xac@YX~n\xb9\xa8\x98X\xdf\x85Dv\xf6\xcd\xac\xa90{\xdd*\xaa"\x8b\x18\xbb\xc7_\xf9\xc2\xbc\xac\xb9\xfbY#98\xe1\xc4\x19\xdc\x83\xb4\xf9\xfb\xed\xad\t\xcf7\xf6\x07\x85i\xa7k"\xbf\x91\xae\x95\xf3\xad\x1f\n\xf6\x9d7 .J\xff\xa0C\xa0/\x0b\xe0\xad-\xbe:h\xc0\xbfD\xdd;rQ+99\xb2\xadH\x9d\xd3\xa9r\xfc\x93n\xc0\x18R\xd4\xbe\xdb\x7f\xadbf\xe2\xb77\xb2\xa9F#\xf9i{\xe3\xb8|\xad\xef\x04\xbd\xd1)ph\x02\x80\x92\xdd\xcf\xd9\xfe\x18\xaeD\x05\'\xe0u\xec\xbc\xcd\xbc]\xa9\x18\xd9\x0b3\xaea\xa2\xa7\x1ate\xdb~\xfb\x9b\xe2c\xd7E&\xaej_\xbd\xab\xcdC\xffG\xcad\xff>\xa7v\xbb\xaewT\xd4\xc1UM$\xaa\xd7-\xa2x\xe1\xf0l\xae\x90\x01\xd3UE\xee)l]N%<\xd6\xf5C\xae\xc0\xb6\xbf\xb4\xa8zi\x99\xc1\xefn\xdb\x8f{q\xae\xc3],\x95\xcc\xfb\x95\xf9A\x1d\xcdt\x05G\xe5\xae\xdeV\nq\xf8\xc1]\xa8\x9e\xad\xc9\x9df\xe5_\xae\xe0T\xc3!\xe5\xb5h\xd67+\x85}\xb5BI\xaf1\x13|\xf6\x01\x1e\x19\x7f\x9eW\x9a\xf9r\r\xcb\xafq\xa3\x14\x19$\xbf\xda\xcag\x83\xccip\xd8\xba\xaf{\xba\xdc\x00\xfd$\xe3\xd4G\xf86\xc2[(N\xaf\x90 \xd7\xf6\xae\x05x\xf8)5\x00E\xb9\x8e\xea\xaf\xb6\x91G\x0f\x86_\x9d\xfe.\xbbsRz\xc9\x97\xaf\xc1\xad\xe5H1\x89\n\xc8\xd5T\xea\xe3\x16\r\x99\xaf\xcf\x9dH\x0c\xb4\x8d\xcd\x1f~\xd2\xd3\\\xc2\xfb\xfd\xaf\xd4\x17m\xc6t#\x8a\n-<\xcc\x8aL\x9c\x9d\xaf\xe6?m3\xb3\x82\xa3\x02\xf80\xcam7Us\xb0\x07\x03\xc5{\xe0G,\xe0\xc9J\x06\xb9N\xa4]\xb0.\xff\xc0L\xca\xdd\xef\x1d\\\x19\xf7\n\xf4*w\xb0z\x19\xb6\x83\xf7\x97o(\x7f\x01\xfaDc\xaf\xb6\xb0|\xcc]\x1b\'\x1cj\x1a\xe6\xfd\xcc\xed\xc9\xbe\xf9\xb0\xc8\xff\xa7j\xff\x9fY;\xce\xf9\xfe\xafg\xff\x90\xb0\xcb\x83\xa7\xa5\x1b\xff\x8eZp+[\x1b4G6\xb0\xde\xd7a\x99\x8dR\xcb\x9aX_\x17\xb0e>y\xb1\x19\xf9Y\x00iD\nc?\xc8>Q\x1d\xff\x86\xb1m\x07n\xe2\x10j\xffQ\xf3\x84CNDl\xd2\xb1}\xbe\xb6\xc1Pl<W\xc3\xae\xb0\x17-\xcc\x07\xb1~[7\x93\x06\xdb\x0b\x1b\xe6J#\xc7t\x85\xe9\xb1\xb2\xa3G\xf8sL\x9a\x86\x82\x92z\x9b\xdc\xdeb\xb2>\x81g{V\xed\xce-\xb3\x0ecX\xca\x1e\x10\xb2Z\x84\x8b\x84\x08\xabu\x7f\x81\xd3\xdc\xd1]<\x06\xb2\x8f\x18\xa6\xc3)\x0e##`\x83\x15\xd4\xdf<\xd2\xb2\x97\xff\xb0Y\xd6\x11\xbe\xe2U\xf8\xbb\x1d\xa9\xec\xe0\xb2\xea!s\xfb{C#\x16\xe1\xb5}o\xa7\x02.\xb2\xee\xfbg~X\x88\x1aw\xda\xb0\xa0\xeeS^\xea\xb3\x1b8,\x95\xa0\x98\xa5e\xca\xa2T\xbeG\xf8\x04\xb3+\xec\xcf\x05-+\xb5R\x90\x1d\x02\x85\xb5\x8eq\xb30\x8eF`\xa2U\xc9"[\x81\xa9\x85S5\xb9\xb33\xd7pC\xc9\x80\xc8\x96\xa8Q46b\r\xb8\xb3F\xe5\xc7W\x86uFG[\xb3"\x9e\x82\xd4\xfd\xb3G\xfb2\xdd\xf8d\x19#\x887&\xa5(\x88@\xb3e\x7fD\x9e\x9du\xd4\xd6\x13%\xf8\xe3\\M\xa9\xb3~bN\x17o\xa5F\x93\re\xb9p\x16K\x8a\xb3\x8f\xbf\x93\xa5_k\x07\xf4\xa7\xb0\x08\xf4\x11A\xb8\xb4\'\xe5\xc6`\x89\x00@\x07+\xb1&g\\\xb4\x08\xb4\x9c\x8f\xb5\xfa\xc4\xe0\x0f\x8d\xd3#\x82\xbe]\xb8\xcf\xb4\xa7\xdaP\x118\xf7\'R\xca\xbf\x1f\x83\xd1\xf4\xf1\xb4\xab$\xc2\xde\x15}\x16\xf8Mur1]\xba\x8a\xb4\xbc^3\x04\xe7\xed\x10\x00\x94\xd5C\xdf\xc9\xb0=\xb5(\x8a\xda\x19W\xc6\x07t\x1e\xb8\xbc^\x06:\xb9\xb5=v\xf1\xdf^\xd7%i\x1a\x8eq\x85\xd8B9\xb5D?\xfc\x0b\x81\x0e\x89B\xad9`5\x1b\x08b\xb5H=\xc6j\x023\xb4\x00\xb8\xb1\xc0\xed?\xf73\xb5JT\x06\xb7\x1b\xdf\xd1_\x83\x85\xe9\x02&\xb2\xfd\xb5g\xdf\x07\x97\xfcp2\xe0>\xac\xff\xec\xf1C\xa7\xb5\xb4\xe5f\x15\n\x1a\x0e\x92\xb7\'\x94\xe9\xe9\xd3\x9f\xb5\xf8<D)\xc1\xb0\xff\x9aP\x802\xa9^\xc8\xfa\xb6\x1f\xd3\x06\xb0\xf0\xf3\x04\xa1{\x83\xc4\xb2#z\x90\xb6G\x94~\xeb\xf4\x1a\x1c\xaf\x03>9\xa2\x8c\n\x99\xb6\xb8v\xe0\xd3\x1d^\xff\xd0\xf1\xf6\xcb;\xaap\xdf\xb6\xc2-\x0b\x8e\xa3G\xbb>\x91\xde\xcd)"\xc2\xda\xb6\xcc\xc30\xc3hA\x00@7Tao7\xc3\x87\xb6\xe4\x98\x1e\x9c\xdbUD\xb7\xc6+\x8b\xdb\xa6\xcf\xfc\xb6\xe5^~\xc66\xa7\x10\x0f\xe7\xbff\x8f\x1f\xe7b\xb7\x1eD\xec:y\\\n\xf3 \x0e\xd1\x8f\xef\xc5L\xb75i\x86l\x87\xa5\xfa\\\xbc\xa2\xb5\xac\xfcF+\xb7:\xd6\x1e=\xdbG\xc9[\xd8l\xb9\xcfm\xb5\x1b\xb7Ni\'N\x1f0\x0f\xb3T\x88\xf3\x03\x971q\xb7OE>\xf4\xd3}\xe4\x1bP\xe3\xa5\x08\x89\xd6M\xb7~\xeb\xa6\x05u\xe3\x0b\x07\xe5\xab\xec5\x98\xd00\xb7\x7f\xb0\xe5\xd9\x0f\x08\x037\xf7\xaf\xad~\xa88\xad\xb7\x81\x93\xe6\x8c\x10\xed\xb2\xfa6\xf0\xe3\xbf\xe3\xd6t\xb7\x8d\xf1d\xed\xac$<\x7f}\xbd\t3\x04bM\xb7\xce\xf2\x82\xbeD=\xcc$\xef\xae\xa8\xb1\nMo\xb7\xd9^Kl\x9e\xf2\xd1_\xe6o09\x8a\x01\xdb\xb7\xf0\xd9\x8a\xa4E\xe1_4\xf9|ed\xd8\xe6\x16\xb8LE\x08\x0b\xbaY\xee\xee\xf1 I\x03|R\x91\xb8~\xadA\xa2\xd79\x0c\x87\xde\xf4\xaf8\x04\x9b\xa7\xb8\x93\x19\x87\xbe\xa3\x1d\x1eU\x0b~\xd5\xe9\x81\x94\x11\xb8\x97\xe2$)y\x9f\x83X\xcd\x97\x92\xd5\x0e=\xc7\xb8\x9b\x87<\x83\xa5\xc1\x14\n\x9b@\x93\xcb;\xeb\x19\xb8\xa25\xffB\x87\x928\x8d|[\t\x00\xe3\x14\xe9\xb8\xdd\x0e\xd5.ZD\xe9{{\xeb\x14\xf1\xcf\xc3\x9d\xb8\xf2\x85y\x98\xf5\xcd2D \x15J=d\x12L\xb8\xff\x9dmX_\xc0h\xa1\x8c\xbaU\xe6\n\xd8\xe5\xb9\n\x12\xbcU\xd4p\xa3\x0c\xe5c\xddCWD\xfb\xb9\x1c\x12{\x0c\x07\x18\x9dDM\xd9\xa3\x9d\x06}2\xb9\x1f<\xc1@w\xe4;\x99\xdaA\x11s$]+\xb94v:Uu\xe8\x9e\xccoV&\x0b#d\xdb\xb9I\x1f\xec\x11 \x1f\x9c\x19\n\x90\x937\x84\xee\xdd\xb9k\xf8\x89\x95\x00\x9eb\xa8\x12*!\xd5\xcb[\x1e\xb9n\xe9\x12\xb0\x00|\xe8o\x1f}\xe6\x07w\xacd\xb9sS\xd4\xfc\xe3\x01V\xae\xf1\xbe4\xd8\xe3\x00 \xb9|\xa1\x07k\xe6\xb8PD\xaf\xe7?\xca\xe0\xf5\x05\xb9\xa1\x84\t\xa6\xda\x94<\x15\x91\x9a.\x98\x94\x80\t\xb9\xa6k\xba\xe4\xfdH-\x9d\xe1\x1c-\x12\x1a =\xb9\xba\xca-\xdc\xa7\xadJO\x84\xe9H\xbf;\x84L\xb9\xdbl\xa3\xbf\xe9,\xab\xd7\x97\xc3H\xe0\xd94\xde\xb9\xf1\x95m\xd3\xb9\xd1\x0f\x00\xaa7X\xfe\x1e\xab\xbf\xba\x08~\xeb\x86\x8e\x8a\x14\x08\x05\x9a\x15\x11~\xeap\xba\x11\xb4f\xb6\xdc/KW\x9e!\xa3\xcb#&\xfc\xba=\xf6\x87\xc0\xe3\xbf!\x06\x0b\xf0s\xb2\x813z\xba=\xf6\xab\xb8f\x02@\xe2F\xb4,B\xf1A)\xba?\x95\xf4{\x1a\xb4\x08\xffL\x9d\xdc\x14.\xb1\x8f\xbaJ\x11a\x06\xfc\xbe\xa1I\xb6\x12\xf1j\xfc\x01#\xba\xbc>0\xa3\x02\xac\xc7h\xe6\xa4vEI\x99I\xba\xbf"\x8f0rM%\x91\xc7du\xbf\x86\n\x02\xba\xc2\xcf\x99\x89y\x1f\xea\\\xb5Z\xa6\xd8\xf0\xd6\x11\xba\xc4{r\n\xee@v\x84\xbepG#v\xf3\x89\xba\xe0\xd3\xc4\x82t\x86M\xb9\n\x16y\x1f\xd7\x06\xda\xba\xe6\x0b\x08\x8b\x13\x0c\xc6Dn\x97\xa2MO\xa56\xba\xed\xf3\xfb\x8b\xf4\\\x07>]<$\xd8\x04u\xec\xbb<\x12\xa3\xff\xe2\xa9\x95\x97\xf0\x11}\xe3\xe6\xe6(\xbbE\x07\x95=s\xa9fv\xaa\xfek\x9ds3#\xbb\x8e\xe4\x02\x11\x85)mX~A\r\xfbC\xee\x8e\xbb\x94\xae\x9c\x0f\xd1!Cg~\x88\xe1\x15\xa3\x1b\x10\xbb\xcb\x9cf\xcc6\xb0:\xbd\xeb\xa7=\xf2\xd3#\x86\xbb\xd6d\xba\x9eb\xe8\x87\xab\xe2VQ\xf8d\x98\xfe\xbc\x05\xf4~\xbd\x13xSK+*\xfahc\x95\x0f\xbc=\xc1\xa5g\xd2\xed\xe5.\x81\xc8;\xe5\x99/\'\xbc[s\xfa\xc9w\xa1*\nJ\xa8\x92\'[\xca#\xbc\x9a\x8f+o\xff\xd5\x85q\xe1\x88\xbb\x11\x05E\xf8\xbc\xafn/\x0b\x86\xea\xa8d\xd3~\x8095\x13\xd7\xbc\xdb\x11U}/W4\xc3\xef0\xc4\x9b\xd8\x07\x03\xbd\x0b\xa8df\'\xe5\xff\xd2\x184&\x92\xf5\xfd\r\xbd\x1d\xd7\xe6t\x14\x06\xc8\x0c\x8f\x8es\x1c\x04\xdf\xfa\xbd \x8a\xcb\x8d\x13\x95:\x1a\xda_\x9c~;\x81\xb0\xbd)\xe6\xaf\x90\xbb\xd1_h\xa9\x01\xabk\xa8p\xf5\xbdB5\x1b{\x82\xb51\x10\xca\x8b\xcd+\xb0\x1a,\xbdi\x81\xf3wZr\xc4\xe8~@\x12\x96q:\xa5\xbdn\x1e\x04\xf5\xf9\xc0\x96\xfb\xa1Fs\x96\xec\xb3W\xbd\x8chd\xab\xc0\xa4\xd0qF\xcd3\xed*2M\xbd\xc0\xc5\x90V,\x80\xdehF\x9c\xd3B\x7f\x1dm\xbd\xd2d\xf0\xd6\xcf\xf9\x07\x02\xab\x15b\xa3\xe0\xf8\xc0\xbd\xdby}Y\x84\x9a]\x8c\xb25\xd8e&q\xf2\xbe\x01R\x8b\x1a\xa2"7`\xb8!>?%\xa0\xab\xbe\x08\xc8\x9d\xf1\x9c\xd0U\x99`\xe3\xfee\x87\'\x85\xbe"\xe3.\xccM\xcdFA=9\xc5\x86\xd99S\xbe\x84\xa9\xcd\xd7`\\+\xa2\x9f\xb0NJ\xc3\r\x06\xbe\x8e\xb82F\xe9\x96}\x02+\xfa\xb3\x98\xe5\x88\\\xbe\xa0\xd2\xc7\xae{ S\xaf\xd7>\x9d\xb7p.\x92\xbe\xb0\xbc\xeb\x0bF\xd6[\xb1ID\x86-@P\xd2\xbe\xcb3\xb7\xab\xc1\xa8\xb0g@c\x1bac\x0f\x89\xbe\xd2g\xe4\xa9m\x8d\'\x05L\x9f}\x14\xf2 \x7f\xbe\xe1m\x16\x16E}\x1f\x12"We@.ai\xbe\xf2\x8c\xab\xea\xa9\xedN\xfc8\xb7\xed\x16@&G\xbe\xf9b\xfb]\x04\xde<@_\x84Z\xf7\xdd\xef\x04\xbf\x02gf\xd5XTR\xd3?\xe3.\xf6|gT\xbf9WP\xc18\xa3\xd3b\'\xa8\xa7J1>$\xbfL}\x07\x85\x86\x00N\xefs\xa2\xb2\x8c\x88\xac\xc9\xbf\\xH\x122\xe4\xf4\xf3-\x9e\x13p\xc4\x99\xe6\xbf_\x98\x9b\xcd\x99\xec\xe4\x99T\xf9Z\xa4D\x9a@\xbf\x8e\xe5\xf8\x9a\xbb`7\xe45\xef\x9cTx\x87\xdd\xbf\x95\x7f+o\x80t4\xe7\xd8\xfaX\xcb\x90\x08\xdc\xbf\x9d\xc6\xa6\x04\xce\x81\n\xcd\x06\x9fG)\xe7@u\xbf\xa8"\xe6o\x9f\xb5\xc5\xac\x94\x80\xd1\xdca5Y\xbf\xb5wO\xd9\xe0\xb5\x9d\x90"\xdf\xb1\x99\xc7\x12s\xbf\xba\xc5\x9bFMx\x03\xd2\x9a\xe6\xbc\xd6\xc1\xbb\x03\xbf\xbee\x85\xb6\x0e\xbe\xbe\xae#\x1f\x9f\xa1s\x99\xda\xbf\xca\x13v\xbf\'\xbe\xb7\xae\x1c\xe3\xc5Id\xf2N\xbf\xf4\x04\xa2\xd0_\nVCZ\xca\xf5\xe5\x06\xae"\xc0\'\xbfY\xab\t\x99"\xe7\xf2c\xbd\xed\x89\xd5C\xc0*\x92\xd6\xadX\xfc\xa3\x8d\xf2\x03m\xc0\x9b\x82U\xc0@\x1f\xd2U\xf9\x9d\x92\xc1\x08\xcd\xbf\x9cz\xd2p\xc0\x8c-\xc5v\xc9\xe1G0\xfd>\xe0\xca\x97\xb4t\xc0\xb6\x1d</\xf3\xec\xcb\x9fN\xdd\xf0_Z\x00\x88\xc0\xe3\xaf\xa1\x89\x05\xcb\xf0\xb3\xe0&\xd8/\xe4t\xc3\xc0\xe3\xbdVf\x0bkd\x8f\x044\xc9Qr5\xce\xc0\xf4\xde_\xf6\xf1K\x10c\x9a\xfd\xef$\x18\xef\xd5\xc1\x10\x17\xceb\xd5\xe2\xc7)\xcd;\xb3v\xa9*o\xc1&\xf5r\xe6\xbe\xe9\x17\xd1\x03\xf0z\x10\xf3\x0b!\xc14\x17}\xb3\x176\xdaicH\xfc\xc0\xf9\n\xdb\xc1D\x05#\xfe)\\\xbf!\x8exf\x0c\x15gE\xc1Z\xdbe\x91H\xcc\x1a:\xf4\xce|*\x1d\xb0\x19\xc1\x9cy\xb1A\xc8T\x95\x10\xc4b\x0f\xdc\x08Dl\xc1\xdb\xe0\x15\xebXB\x04\xe3\xdf\x0cA\xe5\xd3\x1c\x14\xc2\x12\x94)\xa4{\xebr\xbcm\xdc\x8d\x91\xf9\x040\xc2.\xc2\x86r+\xc5\x83\x1f\x91\x93\xf5kv\x00h\xc25\x88\x03\x80/#&b\xcf\x89h\xe1\x03Hr\xc2:\x0b,\x9f\xfd\xc0?HW\xfdZ\x90\xa72\x10\xc2?\xbeG{\xab\x0c\xee\x89\xe5Att\xea\xa1F\xc2r\x0b\xfcA\xa9\x14o\xb2]#{rf\x85=\xc2y\x80\x90e\xb1!G\x18\xdd\x1b\x9c\x8b\x85\x11\xde\xc2\x82\x18%T\xecj.\xedG\x06\x07\xab\x92>\x03\xc2\xa6\xe6\x0e-\x12~\xfcK\xd6\xe8\x94\'\xe0\x08=\xc2\xc3\xa8\xee\xd7\xd8\x81\x955\xf3\x9b\xcf`M\xa3\r\xc2\xcc\x02\xab\xb9\x00\xed\x15lK\xa5h* .\xb6\xc3\x05\xeflG\xa4I\xa0\xdf\x0b\xdf}\xd9\x1f;\xf0\xc3\x10g^\x02\x82\xf23\xb2\xb6\xe6\xe6#\xb0\xbc)\xc3\x1dHu\xa5\xa6j\xd4n\x9a\x1a\xfd\xc2\xbf\x9cI\xc3G\xcd\xd7\xca\xfa\x10\xc8\xe5+c1[\xbde\xa5\xc3b\xdd\xb84\xbc\xe4\xc7\xb0\xf3\x98\xbd\xe0\x16XQ\xc3\x85\x98\x80\x84\xbbW\x10m\xbb\\\x10=O`-\xc3\xb8^\xd5\x9a;fe\xb2\x94\xa8\xff\x07\xc0\xa2\x03\xc3\xfft[L%\xb7\xf8\xf0\xfb?\xa6p\xb0\xaf\xf0\xc4\x14\x0b\x0e\xee\xd2\x88\xe4\x9a\xff\x1d\x7f\xfa\x95}\xb0\xc4\x1e\x85,k8\xb6\xf0\x0c\xa2$\x8f\xd6\xbf\xf5\x0b\xc4@\xd5q\x17\xb5\x1d\xfa\xd4\xb5\xd0\\\x03S\r\xeb\xc4B\xb9\x07\xe3w\xda1\x8c\xa7\x1a7\x89\x85\xea>\xc4Z\x94(]\xae\x89\xe3U#D*\x9f\xa4\\\xe8\xc4o\xac\x14\x00\xfe\xe7J^#"\x03\x1e\x89\xe9\x82\xc4\x93\xa9\xf5\xb5\x0e(w\xa9=\xbbP\xe5\x19^I\xc4\xa1\xc3I\xd3\x0c/;C\xbd\xf2\xf2\x00\xc5L/\xc4\xeb\x1b\xcff\xf8&\xef\x86O.\xc9\x11\xff\x1c\x16\xc5\x00\x074<\x17\x1c\xa1\xc4QH\x89ms\x10\x9d\xc5O\x150"\xf7\xf2H\x1c\xca\x1b\xb7\x05\x86\x7f\x8b\xc5\x7fh\x11`\x8dh1\x1f\x90\xc7x26\xfct\xc5\x9cK\xc0@\xa2\xfdY\x8d\xf3\x97Y\x93\x9c\x862\xc5\xe1)\xf4-\xe6\x7f\xee\xe2\x0e\x1eKZ\xc8\xb2s\xc5\xfb\xbanV\x02\xd2/\xa9\xb1R\xa9\x8b1\xc3:\xc6=\x86\x9dP\xa5\xbf{\xab\x01wy\xa2\xfa\xdc2\xc6\xa2c\xd9#\x96Z\xc6\xe0\xef\r\xeaOg\x86r\xc6\xab\x97\x1a\\`TZ?{\x0e\x897\xa3\xfc\xc9\xc6\xb56\x85\xcc\x99\x1ed\x82bH\x92\xd6\x12w$\xc6\xbc\xca\x8fm\xc5\xe3!\xca\xe3\xd3\xff"\xf4Ti\xc6\xce\x82\xe2\xb3\xbc;X\xaeO\x80 \xbf\xe5\xd0\xf9\xc6\xf0\xa6\xe6\xd1\x9ebD\xb5\x13V\xcfLl\xaee\xc7 i\xf1\xe0\xb2h\x07\xcd\xe6N\x8f\x8e\x9f\xe1\xa1\xc7HW\xc8>\xf9\x81\x9aJ)\xd1\x15\x146\x97\xff\xc7[f\xa0\x9b\xe1O\xdd\x04\x19\x98nY=C\r\xc7w\x8e\xf2tX\x03\x97V"1\'\xc2\x13\xf9D\xc7\xa2\xda0\xd4\x7fX\xf3k*\xd9\x92\xdf\x00I\xdd\xc7\xa3\x83\xcc\xb1\x98\xf4\xe3\x93[{qCd\xc2\xf8\xc7\xda\xbc\xe4}}\xbbR>\xae\x82\xf4\x8du\xab\t\xc8\x06\xf9f\r\x17.\xe8\xbdc\x87S\x81\xef\x89\x8c\xc8/\xfd?\xe1>\xd1\xe9;\xe2\xd3\xb0A\xa0\xf0\x82\xc8eh\x95\xb2\'\x82p0\xd7\xf1\x08\xb9\x114\xd5\xc8vT\xfd3d\x1de\xd5\xc6\xbf4\x1b\xe3}\xea\xc8\x86\x8a\x82\xd3h\xdd\xc0*\xc8\xf9:\xf4\xea\x95\xaa\xc8\x94i\x17\xcd\xd0\xe2\xc6b=\xaf#t\x7f\xdf6\xc8\xd5\n\xfd\xed\xa3\xc3\xfbkMsi1\xbe\x8c)\xc9\tp}\xbb/\xa9/\x10\x9b\xf6\xe8e\xf1\xef\xf5\xc9H\xde\xe8Gg\x15\x0b\x18\xb9\x15\xef\x0b\xb1\x1f\xdf\xc9U\xe9\xa7\'\xf2\xf8\xa0I*d@e\xe9\x98\x9b\xc9\x8b\x9a\xaes^h\xda\xbc[`g\xa0e\x95y\xc9\xd0\x8e\x86!V\xf4@`\x1aM\x01\xa4iCm\xc9\xdf%\x8c6H`(\x1f-;c\xa1\x9f\x1a\xc8\xca!w2\x17\x8d\xf42\xf0\x95\x00\xfc\x04<\xe7*\xca)O\x8a\xf7X)\xc8\x03\x8c\x887\'~\xe2q\xca/\xee\xb3\x10\x80\x14shj%V\x93*!\xf3\xca\xb5\xd4\x9a,`\x1bW\x8c\x9e\xedUA\x7f\xae\xf2\xca\xc3\x10\xa1\xb1\xe7>4\x177y\x1b\xff\x15\xa0\x1c\xca\xee\xce\xb5"}\xb13\xae\xb4`\x1f\xe6\x0b\xc7\xac\xcb\x00\xab\xa0\xa9Mc\xdf\x83\xf0\xff\n\xfa\xb1\xf2\xd5\xcb\x0fv\xa0q;` \xcb\xdd\xc6Z\xa87\xcc\x83\xcbq$\xc7Z\xf9\x1c\xa0\x0f\xf6a\xeeh\xb6\xb1\xcc\xcb{w.^\xba\xb9\xef\x93o\xd7\x86\x91$b(\xcb\x89\x08U\t\xfa\x05h\x16\xca\xc5\xf4Yg\x9d_\xcb\x8c\xf2\xd5\xa4r\x16\xda\xc8\x83\x03C{\xf6"\x0f\xcb\x9bW"t\xed\xc4\xd2\xfe\xe7\x9f\x1d\xba+\xf0\x91\xcb\xb7\x8e\x02\xb0\x01\x1c\x92?;\t\xd6|;*`\xcb\xc7A\xa5\x10\xd7\x91\xb3\xad\xb7e\xfa\xc0\x84\xba(\xcb\xc7\x9b\xa3&\xbe\xac\xffF5\xbb?z\x8e6\x8c\xcb\xe09J\x85F\xefq\x19\xc0\x89\x90\xaa\xdf\xd8\xdd\xcb\xe5\x82"8\xf9\xf9PW\x19Cv\n\x10\x92\xb9\xcb\xf8:\xdb\x1b\xb7$g\x13\xfe\xeeQ\x95gKz\xcc\x02&\xacu\xae\xf8js\x87\xe8\xabQ\xbcwL\xcc\n{2\xfe\x9bl\x80\x1f\r\\\xe3\xee\xe1\x91\x89\xcc6\xe2;>\x9d0\xc9\xd2\x95\xf1\xf4\xc7\x059;\xccL9\x04\x17\xe7\x0bs\xdb\xafBC\x08b.\xec\xccon8C\x98\xd8M\xea\x07l$\x86J\x86\xfe\xcc\xb6\x8d\xb93\xe3\x18\x9a<\x8c\x1bQ8\x08~\xd8\xcc\xed\x9c\xa1\x81\x0boi<ZdU\xeb\xcd+?\xcd%\xbf?\\\x14/\xea\xb3\xeetc\x85\x84!\xf3\xcd/&A.k\x94l\xc0\'\xee\xe2\xac\x0eB\x04\xcdj\xef\xa1\xa2\xb6\xd1\xc5\xc1\x84{-mY\xcc\x8d\xcdm\xe4\xb9\xa1\xa6p\xd9Q\xa4/|m\x8e\xab\x05\xcdp\xc5\x96\xf1e\xec\\1>\xcc\xe2;)\x05\xf0\xcd~$\x18\xb5U\xec\xd3\x04\x90/l\x9fb\xd3\xa1\xcd\xb9\x08\xadp\xcf\xccO;\x11\x15\xac\x1d\xbe\x06T\xcd\xc2F-qQ\x15+h\x88\xb4\x1fq\xb5\xd6\xa4\xcd\xd9\x12\xcb\xc4\xb0\x02x\xe0[\xc3\xaf\x1c\xdc[\xdf\xcd\xdfY\x95\xeb@\x93\xfev\xd0\xca\x1a\xea\xb5-k\xce\x14\xcf\xf6\x9e!\x8c\xd0\x96C\xec\x91\x01\xd5M~\xce\x8a\x87F\xfb\xbb\t\x90J\td\x90\x93l\xf5\x07\xce\x98K\xd8\xaar\xeb\xa5\x8d\x81y\xbe\xc94\x1fk\xce\xc98\xf7\xbd\xd15\xa78d\x9d\x05\x96\xa9?\x97\xce\xdc\xfez\xe3\x00w\x91v\x8c3i\r\xc7_\x08\xce\xe2\xce\xb0\xc8\xc3G\xcaD\xf3\xef5o\xa7_\xe9\xce\xfb\x19\x8c\xae\xd6\x1d-2\x02\xa4|\xa6=2\x9f\xcft\xd8t\xfa\x86\x8bP\xa552\x0e`\xd34m\xcf\x7f\xd1R\x9ePQ\xd3s0\xfc\xcb\xa3\xf3\x14,\xcf\xbe\xffk\xbf\xe7\xebR\xc9\xe6\x86Y\xc2$\x89\x83\xcf\xd5\x81.-\xccA?6\xcf\xfdE\x90\xbb\xb4\x81\xd0\x01\'\xc5\xdf&`\x7fG\xdaa;-\xd5O\xaa\xd0\x08\x9b=\xeb\xb6\x0f\xbe\x9eK\xef\xea\x89\x03S\xda\xd0\x93\xaa+)ZW?\t\xc1\xc259\xe7\xaf\xb5\xd0\xbd\xa1\xc7\xa8\xe1Ar,\x93\xc1/[\x82\xb9\xe4\xd0\xca\xe9\x19\xce\x03\xeb\xc8\xa3\xfe\xa6\xb7H\xfc\x07l\xd0\xd83@\xc1\xea\xfbf\xdcV\xf0\xf7j\xe5O\xad\xd0\xd8dJV\xa3#\xe2\x88\x8b\xfbh\xcdg\xe3/\xd0\xe3q[A\x1b w\xaa3W\xba\xc7\x83\xa4\xbc\xd0\xfe\xa5\xc7\xb6ka\xde\x12\x0f\x9fr\x83(^\xe1\xd1-\x984\xbd\xe1@a\x0foSO\xa0,\xf9\xc5\xd1_e\xc1\nN\x9b?\xf7\x8f\xe8:r#1\xf3\xd1tG\xef\xff\xcc\xdb\x11Otw\x86\xd8q\t\x0b\xd1\xa7\xea\x95S#)\xbet\xc3\xcd\xe3\xbe\xd83\x14\xd1\xd5 \xe5O\xb8l3F\x1c^\xe0\x0c>\x98\x17\xd2\x12\xf3\r\xa83\x94\x93%\r \xb5\xc1-\xf7\x0b\xd2\'\xb7\xb4\x96\x9bG\x1f\xedP\x95\x96\x9316\xe0\xd2\\\xa5\x0b#\x98\xb2\x17\xc5\xd8\xaa\xa3\x1c\x83\xbb\x98\xd2g{\xb1\xcd\xc7l\x1d\x9f|\xc7\x05vm\x1d/\xd2o>\xc3\xfdyL\x80%\x19\x00.\x86\n_\x1a\xd2\x8d>\xa3}\xa6\x1a\x158\x91\x1an6\xd6\xbcI\xd2\xa6\x06\x04\xcb\x95"i\xd7\xee\xdd\x83\x02\xe12\'\xd2\xbb)^\x91.`\xe5\x00\x91.5\xce|\x92I\xd2\xe0\xd9\x84\'\xca\x1f\xe8\xf9\x0e\x80\xf8\xfeo,f\xd3\x1eZ7\n\xc3\xbc\x17\xff\xc7Y\xd0\xd3|\xe2\xa8\xd3\x1f\xf63\xf8\xcb\xc5\xd8^9\xbd\x1c\x9c\xe2\xb0\'\xd3$\xe89\xbf\x17\x92\x06!\xaa\x854a\x18~3\xd3;\xda\xa7_\xb2\xcf\x9ala\xa5\xc7\x7f\x89\xfeq\xd3y\x1e\x8b\xd8\xd6\xfeR7n\xff8\x98\xaba\x80\xd3\xc7,F\xe0\xb7\x953[\xc8\xbb\x95\x1d\x9by)\xd3\xe1}\xef\xa9\xd8c\xbd\xed\xf4\xde\xa7A\x1f}H\xd3\xfe\x17\xa9V\xce\x82\xa1\xbe\xee\x89{\xba\xecu\x84\xd4\t\xfb\xcd\x83\n\xf6\x15\\\x80F\x00)d\xfc\xd4\xd4\x1c\xcbF\xf0\x81\xd6\xeb\xd5)$e\x8a#\xb0\xfa\xd4(\xe8\xbbs/\x8e\xb3\xb4\xd4W+\xea\x1a\x0c\xd0\xd4a\xec\x00@\xa9\x95\xdf\x0cL\xceC\x8di\xc3\x9a\xd4c,iD\x8f\xb4\xd9\x18\xfc-?\x16y+\x98\xd4\x85\xafc%\'\x1a\x00\xbb\nQ/\x19\xb5;\xb6\xd4\xa3\x19\x8a\xd90\xb3\x97\x89\xae2\xbcK\xc6\x19\x08\xd4\xb7\xb5wGS\x19\xc8x\x1f\x9a\xdc\x99\x7f\xf8\xfb\xd4\xbc\xa0k4s1)\xc8\xfd\xd19\xe4O"\x0e\xd4\xd7\xbe6\x7f\x1dR\xf8\x18+X\xaez0M\x10\xd4\xdai\x883(\xa7\x13\x83\xeb\x97{\x18\xbc%\x14\xd4\xf8\x97\x16 \x82\xc4\xb9\xb4Ne`\xb6\'\xf6Q\xd4\xf8\xdd\x9a\xe2\x16\xd1\xf5)\x18\xb3\xee\x90\x16\x92\xee\xd5\x0f\xb5\x9c\xc3\\eG\xaa\x84\xad\\$\xa0\n\xc8\xd5\x1b\x80\x1e\xd5\xa4(H#\x8b\xb4\xbc\x13\xe7\x80\x93\xd5p\xb6E\x02\xf9\xea\x98\x18\x1bX\xeeJ\x82\xf3@\xd5r"\xb9\x98\n\x87ku\xa5\x91\x19\xfaW\xdb\x80\xd5ws\x046=\xab\xa4\x90\x0bQFf\xbe\xb3\x8c\xd5\x83\xcc\x80\xca\xa1\x1f\x8d\x9a\t\xdaE\x9c~\x95\xa2\xd5\x96\xac~\x92I\x93\xca\x93\x01\x95Xtg\xca\x0f\xd5\x9e\x18%\xc7\xbd[~\x0bv\xf8LF\xbf,\xd9\xd5\xab\xb3a/\x8f\xaa\xfc\x88\xd0\x89\xf6\xfa\x89*\xfa\xd5\xe1\xeeD\x0c\xe5>\xe4\xc2\xd0\xc3\r_\xa2\xa1\xee\xd6\x0c\x85\x85\x95\xb3\xc3\x96k\xcd\xa61\xf2ZER\xd6E\x03B\x1d\xc2j>?x\x1akS\x1dX\xb0\xd6]\x9e\xee\x9dz\x12\xde!V4\x0fUo\xcf\xd4\xd6\x87\x80:\xe6\xb3F\xad\xe2\xa0as\x8c\xec\x89\x8f\xd6\x9aD\x12\xa7\xf8F\x08\xa0#\x9ey\xd1\xa1\xb1\xe6\xd6\xb3\xc6l\x96\x9d\xe9Kb6}\xe3\xaa\xd6o\xa6\xd6\xce\xd8r[\xa0\x06t\xbaY\xf3T*\xe1\r\xed\xd6\xe2P\xac\x0c\n\xf0\x9f\xa2\x1et9\x80\xab\xb4\x88\xd6\xe9N\x8d\xfb\xe5i\xfe@\xf0\xadA\xce\xe4\x02\x81\xd7\x01U~f\'h\x9eX\xae\x92\xfe\xe5/\x01T\xd7-\xab\xce_\x96\xf7\x17\x8d\xf6cO\x9f\x1b\xf5D\xd7\x9aL\xb3\x8b<i\xc8l\xfax\xc9\xe2\'\x9c\xbf\xd7\xd6\x98\xceL\x9a\x19N\x95\x8a\x00\x08\xce\xde#r\xd7\xe0fY\xcd\x00\x14\xc2\x95\x00\xab\xd0\xaa\xf3\xe9\xca\xd7\xfc\xbf\xaeq\x02\x82\xd9\x10\xf0\xf8\xdb 26J\xd8\x18-b:l\xd4H\x1aT\x8e{\xd6\x9ej\x9b\xd8\x1c\x83u\xf1\x1ft\xb0`4\x01\xf6\x1c\x7f\xe7\xbf\xd8\x9a\x05c\xa1\x00\x08\x0f\x02\x16<K\xa8\x1cA\x0f\xd8\x9c\x0e\xb6\x00%\xa0\x03\xc16\xa7\xa1\x93U\x1f\xff\xd8\x9c\xb5J\xe15\x1e2\xf5\xce$x\x15\xfe\x97l\xd8\xe1\xf9E\xf4`\xb7hAiL\xaa\xf5\xf2F}\xd8\xe5\x02r\xc1\xc69\x9ey\xa7\xde\xe8R\x0f\xc4~\xd9-\x162\x00\xa4v\xb1\xd6\xe0\xa3\xbeF\xd42\xb9\xd9J\xc1\xfb\x82v\xbem\xe4x\xbb\xd7\xf8?\xa2\xa8\xd9P\xda7C\xe0\xae\xf7A\x03\xcc/\xef\xaa\x80\xa1\xd9c\xa4>\x14\xefGz1 \xb7Cj\x0eO.\xd9\xc5a\x90*|\xb9\x90\x14\x80<2+\xd6:\x8c\xd9\xd5\x17\xfa~\xf7\xd1\x08\xaa3A\xcfN\xc7\x03\xdc\xd9\xe2\x7f\xc7i\xc9A\x85\x82\x93\x1d\xa0\xd9\x1c\xa8\xb7\xd9\xe2\xb5\xd7\x8e\xe2\xa3\x94\xf6\xad\xf4\xb3\x00\xe5T9\xda:\\B\xf0\x06`a\xe8\xba]\x0c\t/x \xda?\xea~\xf3\xa3\x8a=u\x00\xbb\x7f\xc1\nQ\x01\xdape\x92\xa6I\xc2\xc1\xa1\xf1\x95LN\xd4\xbdj\xda\xe9\xa2\xb6mX\xd5K"H\xa9\xcd\x05\xf2\x1c\x1b\xda\xf4<H}$=Y\xd8\xab;\xfbfEy\xec\xda\xf5\x1a\xf1uEU\x1e\xa0\xb3\xcd`6|\xd9\x9a\xdb)\x10:\xec\x1a\xe0\x03-\xf86\nsp\x8c\xfa\xdb)L~\xb5\xf5\xc5\xa8{\x95g\x80\xa0\xee\x17\xc7\xdb9m\xe7\xa4\x1d\xbd\xa7\x06\xa4\x08\xbb3\xee\xadX\xdbT\xb4\xaa!W\xd7\x81!\xc1\xf5\xca\\\xa5\x9e\x18\xdb\xa1Q\\\xd9\x82\xe9\xe0\x1a\xdd\x85CF\xa2\xde\xaf\xdb\xc3\x9f\xbe1G\x85\xe4\x8aP}\n/ye\xde\xdb\xe1+IZ\x9e=]\xb0\x00[\xb6\x97\x90\xbf\xa5\xdc\x03\xa7\xc6\n\x82\x986\xa6\xc8t\xe6\x039\r~\xdc\x1a\xf8#\x8fr\xca\xff\xebZ\xe8fa\nx\\\xdcLro0\x15\xac\xc7o\xfaEI\xcb\xee%b\xdc\x8d0]\xb9@\xc5\xf0\xd3f\xaa/eq\xd8]\xdc\xdf\x11\xec\x1d\xce \x8fn\xa6D\x1dJ\x8b\x80\xf1\xdc\xff\xa5\xe5\x84\x1c\x03\xcd\x06\xba\xa7\xbc\x87\n\xd5M\xdd\x1e\xb47,D\x96\x97\xca^>\xfb\x841Q\xd7\xdd\x1f\x0b\xea\xf5\x8f\x99>\xe9\xfa\xd7\x1e\x15\xaa\xb1~\xdd!^1q/~\x85\x08\xb8\xeb\xdc\xd4\x10\xc2/\xdd\'\x8fm\x15Kqt}@D \x15\xf0\xc66\xddXa\xeb\xde\x996\xe8\x12\xc5\xb7\xe7\xceO\xe2\xd6\xdd\x96\xd6\x10\x95.C\xd0W\xb7e-\x84\\\xcah\xdd\xb0\x06\x99\xdf\x9c\xaa\xaeh\x80\xd2\x85C\x81\x95\x1e\xdd\xd8\xaf[\xbf\xc68\xbb\xb0\xf7~\xf97G\x18\xab\xdd\xd9\xfdNw\xf65\n\x13\xc3\xa9\x92\xd6\xb0\xfbZ\xdd\xf1\x83\xea\x16 zFy\x8f\x1c\x06%\xbb\xf2\x92\xde\x023\x1a\nd\xdb\x9a\x8a\x1b\xbf\x0e\xf3z\xc8\xd6\xdek\xdcYD\x99Q4\xdd\xd3\x8aPm\xd0\x9b\xe5\xdeq-S\x83h\xaf\xbb\xc9)\x997\xbf\x82V\xe5\xde\xa9\x8f*\xa9{a\xbe^\xaemO\xa51\xf8q\xde\xab\xb1-\xc1\x97\x10\x0e\xba\x01Q\xea\x99\xe6\xf3\x98\xde\xb2\x8e\xe3\xfeLmLq\x104\x04\xa3j\x98/\xde\xcev%\x94\xd4@h\xac\xc0 6\xc6\xa9\xdc^\xde\xeb\xc0\x93@\x97\xa7\xc2b5B\x1f\x1c\xdfx\xe3\xdf\t^\xcb\xde/!\xac\x85/\xc1\x82\x83\x85C\xc4\xdf\x0e\x98\xba^\xc0\x84!/u\xf6m|C\xb0\x92\xdf\x138J\xc9\x80gk\x9c\xd5R\xad\xef\x1f5y\xdfBY\xcd\xca\x9e\xf8\xbf\xac\xda\xad\xd5\x1cE\xe1U\xdfl\xe2T\x8f0\x98\x0b`\xcaj\xaf\xba\xe6\xea\xee\xdf\x8c\xc81\xbda\xa1\xb2N\xaa*\xde\xd1K\x1d\xdb\xdf\xcf\x94\x01U\x05k<c\xa3\xed\xe4C\xa8\xde\xa1\xdf\xdf\'\xfd\x8a\xf7\xe4\x9c\x8et\xb5.\xca\x16\x8dN\xdf\xf3\xa7#qZ\x02\xef b\x92\x94G\x1aJ\x9a\xe0\x01\'x]Q\xe8;\x8a\xb7\x0bZ\xb6nn\x8a\xe00M\xc1\x89b\x12\xb7\x17\xcd]\xb3\xf8`l\x15\xe07Au#\x12ar\xcb6Y\n\xc7\xac\xf4\x01\xe0M\xc8\xc6\x19lv\x9do\xe7\x98N!\x83&\xf7\xe0O\x00\xf6\xbf\xc1\x0c\x08_W\x0f<\x1dmE\xee\xe0}\x9b\xf3wY52\xfcdFb\xea]V\x0c\xe0\x8bz\xf3:\xd3U,=a\x9b\xc7i\x8c\xf8p\xe0\x93\x07b\'\xf1\x9eT\xe2;[\xf5\xa7LL\x81\xe0\xe1/\x16\x93a\x1a\xdf+o\x8f\x08\xe8\xb5\xebn\xe1\x1b\x9bP\x93\xbf\xcf\x06\x80\x1b\xd10\xc6\xf99\xa7\xe1?2\xc1\xcc\x19t@\x87V\xf6\xe4OF\xd0)\xe1I\xc6t<*\x92\x17\xcc\xd0\xc9\x0c\x93B\xfe\xee\xe1n\xf3\xe3MR\xcaF\x95\xc2\x92\x1c{\x10<\x1b\xe1\x88\x8b\xd5\x0c\x02\xce\xe2\x1b\xb0\x92\xa3q!\x90\xdd\xe1\x99P\x18\x1a \x13\r\xf8\xc0\xe3Ex\xe3\xfbr\xe1\xa1\xfc\x8f\x81\xb4\xe3\x9e\x16!\xc5\xa5\x91\x8d\xd4\x01\xe1\xa9\x0fV\xf7\xcc%L\xb2Q\x96\x96`\xc7\x95\xcb\xe1\xde>=\x07"t\xf0\xe3\x90\xdf\xff\xf4a\xeb\xc0\xe2\x0fe:\xf0\xd1\xdfC\xa4\xfc\xb3\xc8\xc06\x83\x13\xe2\'z\xef\x92\x1b\x97b!\xaa\xbf\xc7zZ\xac\xd0\xe2D\xd2\x0bK\xd1\x1c\x01F\xcd\xfdy\x8e\xae\x02\'\xe2F\xfb\x8fs8\x15\xca\xfb\xd3\xec7hw\x8f\x9b\xe2g\xb01\x82\x97\xa2\xef\x1a\x9a\x88\x94@\xc8\xb0\x11\xe2\x97T\xf1\xcd*q\xa7\xe7\xa5\x85Fc~\xf4e\xe2\xb2\xa9\x05\xd2Ef\xeb\xa1\xe4=\x03\x02\xa2\x9a\x8e\xe2\xd8\x91,\xba@\xda\xf9Gw\x0eW1o\xc1\x10\xe2\xf5A\xde\x96+\xb5\x0e\xd9;\xa5]\x0e\x0e\xbb!\xe3\x1e\xf1o\x97\x14\xbf\x97`n$d\xf9\xae\x08\xa0\xe3\x90|\xdd-s\x81#`\xa2\x11\xaeWC&G\xe3\xa2+\x0fV\xdbZtX\r^\xdc6A\xea\x06\xe3\xb3\xf9\xacWR\x18R\xf3]\x99\x85Pl\x15\xae\xe3\xc05[k\xe35\x04\x13;e\x18\xff\xccc\xa1\xe3\xd8s\xf5\\\x02LU\xda_S\x0b\xae\x87Ts\xe4\x83/%X\xf6\x05p4\xdfU\xae\xdc\xd2\x7f\xc3\xe4\x87h\xb0\xceYV\x1e[\xc1A\xa5 a\xddE\xe4\x8c9l\xa2\x9dQ\xe7\xfd\x80\x0c\x87\xadw\x19?\xe4\x9e\xe5\x90\x1b#\xbbJ\x0c\x17UR`\xeddC\xe4\xa8\x14\x0c\x0b\x00\x05\xd9\x99\xb7\xf1\x92\xb2\xb5\xc3\xc6\xe4\xc1WR\xcc\xd4V\xdf\xee\xcd\xdb\xc7\xa5\xa8\x1a\x11\xe4\xc3Y\x80\x01S\xfc\x01jW\xaf\xd4\xa8\xd6\xeeD\xe5\x7f7\x11h:2\xb71\xc8\xd3I\xf0^\x8eD\xe5\x89\xce\xd2_.\xd4,\xa7qa,6\xf67\x81\xe5\xb8m\x17\x8f\xdc\x0f\xd0\xbf\x83\xe4\xb3\x02\x8f\xfc1\xe5\xde\x07\'\xfc\xc7I\x9c\xc2hr@,\xa53\x18\xe6\x11\xeb\xcb0\xb6*T\x03\\Z\xfe\x10\xb9n\x91\xe6\x16\x1eM\x10p\x90"\xb5\xab\xc1cE\xb9\xdeo\xe65\xc7P\xc5\x8e4\xce~\xe0\x99"\xee>\xe2i\xe6\x82\xe0\xee\r\xb0i\x01l+l\x9d\xaf\\\xeai\xe6\xbd;L3\xfdMi\xa3\xc9~\xba\xa4\xbfu=\xe7\x06\x80\xf7t\xa2P\x8e\xe2\x1b\x9c\x8bz\x16c\xbf\xe76\x91T\xfb\xdeK\xdad\x1d5#o\xf7\xb2`\xe7]\xb0j\xcc\x83\xebY\xcb"x\x15\x01\x9e\xe6\x88\xe7\x83\x87\x06\xc1\x13D\x0e\xb9\x87\xdaD\xde\xb9_ \xe7\x8e\x873\xc34Z\x9dV\x8f2\xb8\x1e\xa5N\x08\xe7\x92\xe3pq}]|\xf2_\x98`!\xe3\xe7\xc3\xe7\x9aXl\x1c\x8d\xd2\xc2\xce\r\xa1\x1bV\xab\xf3)\xe7\xd7\xa4\xd1\x81\x92\xd67^\x82\xcem)\xa4\xd7c\xe8\x02\x0f\xa3\xa3\x87\xf2\xbc\xf3\xb2J\x9do\xdf\x99y\xe8E\xbfn\xcb\xe3\xc9\xb3\x87\xed\x1e|f\x8f\xc6\xab\xe8X\xbe:zDq\x9f\xef\x02p\x86W\xa2\xebz\xe8zjx\xd8S\x1e\x8e\xbd\x8e\x0e=\x8d.\x12\xcd\xe8{\xfa\xf6\xed\xce\x9f\xe7\xbb\x197\xad\x82\xdb\x14D\xe8\x8d\xe8;\x1aY\x19g\x1c!^M\xb3\xed\xcb\x0e\xe8\xa3q\xde\x03\x87{\xc8\xa7\x17\xc0\xfb\xfa\x8c=G\xe8\xc2\xf1\xe7\xdb\x00ks%\xf7o\xff\xac\xbed\x9d\xe8\xc6y_\xbb\xa4+\\"T\xb5\x12\x11\xb1R\xf4\xe8\xc7\xb9\xfct~I(8FSKH5\x9d\x14\xe8\xca\x16\xdbl\x8c\xfd\xf2\x8a\x8d\x84Aq\xa8\x8a!\xe9\x1f\xfc\x1e\xd7s1\xce\xb3\x12\xb0g\x96\n\xe0\xd7\xe9\xc0\x12o\x0c\xda\x88\xb0\x85H\x9bK\x08\x08\x1dy\xe9\xfd\xd0\xbc\x8a\x82\x7f\x86\x8d\xbd\x12\xfet\xfe\xb4E\xea\x08\xc6\xcd\xf5I\xb2p\xbf\x9b\x9b\xc3\xfe\xfd\x01y\xea\x1d\xbe*\x16\xd2\xf3\xd9\xf5$\xd0\xd33\xb0!\'\xea.\xd5S\xf4\x85t_0\xaa\xf6_\xb5\xf9\x07\xa2\xeaG\xd5d\xf1\xac=3t\xc5\x94\xd5\x18y\xf7.\xea`G\x1b\x86%7[\xbe\x01{"\xfe\xa4\x0f\xaf\xeay#R\xb4\xf1\x95\xce\x89{\x8e1\xec\x83\xbcb\xea\xfc\x9e&(9\x8f\xccv\x8b\xbdu\x91\xe4b\xc3\xeb%\xd2\xd0\x1b\x16\x8e\xb8\xe2\x93\xafJ\xdf"]\x86\xebUy\x8c\xcd:\xa9\x01M\x9d*zz\xb2\xdds\xebU\xf5V\xed\xfe\xb1j\r\xc2\xca\xf7Y+9\x0c\xeb\x7fk\xe6\xcba\xc0_\xb2\xe4}\x8e\x99\x94%T\xeb\xa1\xf0x`\x7f\x07\xf3\xac\x9c\xef\xa1l!\xad\xa0\xeb\xa3\xb9e\x0flY\x87\x958D\xb4\x9b~\xaf\xfb\xeb\xad$\xbex\x06\x84\xe4~\xe6\x04\xe6\xf6i\xfb\xfe\xeb\xb9\x92/;U\xc5\xf8#z8\x96\xe0#\xe6\xa5\xeb\xbd\xe2\xf0\x10\xbf]\x81\xfcg\xado\x99\xbb\xce\xd3\xec\x0b\x8byT\x07\xdd\xec{\x96\x8f\xf3\xbd\xef\x9bs\xec\x12\xb7\xad\xfc\xbb\xd0\xdf\x84\x11\x04D?\xcey\xb3\xec3\xed\xe2q\xd4\xb2\xf1\xe6hl\x8a\x04\xda_\xe4\xec?\'<0"ND\x9f\x0bJ\xd7q5\x05\x10\xecI\x901\x06\x12@\xd3\xb4dk\xd6\x19\xae~<\xec_\xcb\x97\xa6C>6\xedg{\x8e\x16\x12re\xecc\x1d\x9f\xaa\xce\x17\xc9\x19@t*\x87\x13\xb8k\xecf5\xbe\x883A\x93j\x96\xfd\xcb\xc3)\xbd\x1f\xecn4\xc2@\xb6\x19\xed>\x92\x17\xcf\xc2\xe0\x87\xec\xecq\t\xb9\xa2&g`U\xa8\x96\xcf}"(\x11\xec\x8e\xd8~|4m\x8a\xa3"\x97#\x1b\xe3\xf8$\xec\x99\x98\xaaX\xf0\xd8c\xd1ma\x0fI\x82"0\xec\xa0f\xc9\x9d\xc6k\xdb\xd2\x07\xc95\t\xee\x85\xd5\xec\xa8\x8e=\x923L\x91e\x82o}\x02\x84\xf1H\xec\xb1A\x84\x03\x94\xfd\x18\xa9o7:P\x03 \x80\xec\xcd?\xaf\xb5#9\xd3\xf9L\xa0E\xbd\xb7\x83\xc1\xec\xf3\xd2\xc6p\xfe\xd0\x03t\xaf\\{\x80MYY\xed\x1f>\xbb!\x9e\xb9\xb3\xcfW\x14o\xd4\x96nJ\xed*\x0c3\x810\xba\x9e=\x9b\xbe\x14\xa3\x19\xb1\x8c\xedFe\x05\xe6{\xf6\xc6\x8a;\xc3\x1c\r\x00\xbc\xad\xedbj\xca\x1b\xd9m<\xb5\xfb\xae\x8a04n\xb3\xedz\x151\xed\xd1\xe9a\t\x1b\xb7\xcf\xa0/C\xe0\xed}\x16D\x03\xf7\x87?\xf1D\t\xac\x11\xbd\xa9\xff\xed\x96Z\x01\x04\xbd\xe1J\xedD\xef\x02\xc7pV\xd6\xed\xaf\x18\xe6|\x96x\xe5w\x15O\x7f\xd85\\(\xed\xbcKA\xb3\xe0\x1a\xad\xda\xb2W\xd7np\x0c\x87\xed\xfd\x8f\x0c\xa8\x00\xf5\x1e\xeb0I\xb9\x1fS\x8cj\xee\x0e\xe4\xc6\xd8\xf6\x99\xffN\x89\xf1I\xcd\xce\xfeK\xeed\r!\x1f2\xed\xf1\x81\xd0;\x81i]&\x8a\xeeu\xf9\x98\xb5\xc3r\'Di\xba\x10\xc1]U\'\xee~\x88/\xfd\xd8\x8c^Z\xfa\xaf7PB\x95\x86\xee\xa28\xd0\x96\x17\xbb5\x03|T\xad\xc1#\xe3\xdc\xee\xa6d\xbb\xc2\xd4x\xab\x88Y\xfd\xcb\x08m\xd2\xbf\xee\xcf\xdc\x99\xff\xa2\xa3\xfcf\x17\x1bt\xc7Gl7\xee\xebu\xe3\x18/\x1f\xe0\xaf8\x05/\x91\x06\xa5\x7f\xef\x1e\xde8\xa4\x94W\xb9\xda\x94\xfd\x0e\xf7\xd2p\xcb\xef3u;\x86s\xe3\x00\x13\xc4\xe3~ \x7f?\xf9\xef\xa7\x9d\xb4\x82\x8bQ\x83\xe1\xba\x804If\x9a\xe8\xef\xb1y\x16 \x8bz\xf6\xf0z\xf7\xca\xe5\x87\xc4\xf9\xef\xe5\xd2F\xea\xe9Z\x0bq\xfa\xdb\xd2\x0f\x94\xb8R\xf0\x0f\xff\xfa\xb5\xfc\x07\xc6\xac\xba\x94\xa5\x98\xe0\x0c0\xf0\x15s:\x06)K\xdb\xa7\x0b2\xb54Z\x05\xd5\xf0+`1\x007J\x8e\xcd\xefP7Y\xfe\xb7W\xf0,h\x81\'[\x84\x0e\xda\xcf\x92zW^\xa2\xd7\xf0H\xea\xa5\xd9\x9a\xeeX\t\xab\'d\xa9\x9a\rx\xf0NL~\xb2\x89!\x8b\x1f&{\x11\xee\n\xfb\xf0\xf0P(s\xd5[\xf83V\xfd\xfe\xce\x03\xa3\xb0\x91\xf0\x95\xe6\xef\xa7-\x88\xee\xdd\x012\xa1\xcb\xcdV\x1c\xf0\xc1\rM\xa5\x8e\x1d2\xce\xe8X*5\x1fc\xd4\xf0\xd5\xfc\x0f(\x93\x83\x07\xa4\x8a\x95V:\xab\xe4/\xf1\x01rD:3\xa5\x95\x9b\xe0\xadB)\xe4\x10c\xf1\x0b,\xe9<\x0fG#bFV2c\x8c`\x1f\xf1\x168\xabr\x08\xfc\xf2\xf7\xfd\xdc\xb22\xb1\xf4m\xf1JTE\x0bk\xe9\xa3\x19\xa4._\xe3\xb3\xd0\xc9\xf1V\xab-\xaf\x03B9\x16\t\xaf\xb0\xd1H\xec\x95\xf1\x95G#x\x9fI\x83\x966\x92$15\xd11\xf1\x99\xf8\xe3\t\'\xc3\xb8A\xb0d\xdf\x9b\x16<\xde\xf1\xaa/m\x06\x91\xaf\x0c~rs\xe6\x97\xc0PV\xf1\xce\x19le\x8e?\xfc\xf8\xc0\xff \xe6I\'7\xf1\xd7\x04\xe8\x87yVH\x157\xbdd\xac\xb4\x87\xe4\xf1\xe1\xe0k\x8bZc\x89\x16\x9b\x88@\xc4\xf8d\xbd\xf1\xf5\x89\xd6k\x9c)\xd9U\xcap\x86\xe2\x9bb\xed\xf2@\x7f\xefb9\xdcp\xab\xfe\xf5\x12-\x8a\xb3\xe0\xf2M\xac{q\\\x95\xbfd\x8f\xae77\xc3*(\xf2s\xa2\xb9*\x04\x80\xe8\xab}\\\xf4\x85\xfe{C\xf2\xa1\x8a\xb4N\x18E\xfd\xd0\xa5\xad\xe0O\xce\x9eH\xf2\xaa\xc0\xb2\'\xe1\xa9\x15\x1f\xc5DA\x99q\x12\x0e\xf2\xaf\x96\xf3H]\x9f\xcf\xc5-{\x8c\x0e\xbd\x16n\xf2\xb2\xfd\x04\xfe\xfd\xe5\xb5\xfa\xa5\xa3\x85luz\x84\xf2\xf8\r\x12K*p\xa3)\x06\x89\xaa\x9c\xb7\xf6\xf3\xf31\xab\x94q\xd7\x08\xde1\xbd\xc8\x85\x05r\xe2\x06\xf3\xa7\xc5P\xbd\xaa\xacm^\x94\x17\xc9Z{\x98\xbb\xf3\xbd$\xac\xa6\x110d\x1b\xf2=\xa3S\xe9Q\xd9\xf3\xdd\xa6xj9\x829\xbf\xa7@\xc8\x15\xd6\x8d\xf4\xf3\xe3\xc9*y;je\xa9\xe9\xaf\xb8\xbb*\xeb\x16\xf3\xe4a/\xec+\xd1Om!\x0b\xb9%\xfe\x98U\xf3\xf7)\xfa\xff\x10\x9e\xc8q\xffc\xd2\xe9\x01LM\xf4\x14P\x04\x92\x0b%\x8cK,\xfe \xe6\xc5\xdc\x9d\xf4,\xd9<\xda*kp\x0bF\xeb\x9c\xf7t\xdf\xef\xf4.]b}\x00\xdc\xd2\xed\xc8\x83vV\'\xb9\'\xf46\xa9)\x95\xd9i\x00\xe23\xcc0\xc9\xdbi\x84\xf4>\xfc\xe2P\xf7\x86T\xb2\xdfNZKO\x92\xbe\xf4\xaaQi\xe1\x80\xa3\'dv\x8f\xd4j\x98R\xfa\xf4\xaeW\x176\x01\xdf\xd4$=\xc3\xe2\xd5$.\x07\xf4\xdc\xdc\x12K\xc7\x7f\x9d\xe5\xd7\xe7\x0c\x7f\xa9u\x8f\xf4\xe3\x9cs&\x80>\x8c\x9f\xd1\x91S\xad\x99h\xb4\xf5\x02SK\xe0\x10\xb0\xb0I5\x084\xd7\x8f0s\xf5\x15".\x10\xda\xbf\xb3O\xc9\xee\xad\xcd\xf8\xadH\xf5B\xf3\x98N\xe8g\xe4~\xe7\xca\xf0\xa6`U\x1e\xf5s\xd9\x90\xe6&\xe1\x1f\xc2\xe9\x95\xeaZ^b\x02\xf5z7t\xf3\xabc\xc0\xdf\x83N5\xc0\x196\xc0\xf5\xc2\xffT\x95\xdf\x15\xb2\x86-\x87\xb4/=\xf1\xba\xf6#\xef\xe8\xbe\xbf|\xfbIW\x0b\xd5\xefD"\xc5\xf6.\xe2\xdcDp\x10ez\x12]\t\x18\x96p\x92\xf64\x97n\x05\xdc\x05\xb7/\x85\xc6Q\xa1\xa3\xa8;\xf6B|\xef\x9d/\\!\x1dW\x88\xc9E\xd8\xf9o\xf6\x8bS\xb86\xc7\x19\x1e\x04_\x08Nx`b{\xf6\x97%\xc0ZFm\x02\nZ\x9a\x1d\xaf@\x06\xdc\xf6\xc9\x99B\xa6\xd6]Q\xb5\x0f\xa0$\xb1\x03i\xa6\xf6\xee\x81\xa3\xcfV\x85\x0e\'\x86S\x9b\x96\xa3\x8c\x84\xf7\x03\xbft\xdd\xba}7\xe3/\x99\xe1]\xaa4\xac\xf7\x0fL%\xbb&Q\xb1\xb1\xe8\xd9\x1bV\x86\xb9\xa0\xf7f\xe7\x0c\x19A&^\x05\xfc"*\xe2\xb5H\x19\xf7h\x8eP\xb7\x1c\xb6\xfd\xb3C\xddVD\x8b\x03\x1f\xf7\x89\xe2\xe3V\xf5\xb8\x05}\x10\xe8\xfaKJp/\xf7\xd5\xfd4e\xfe\xd9\x10#\xc2pG\xa4\x06\xab*\xf8"\x8a\'\xa0c[R\x88\xbc\x98/\xebT\x9c4\xf88>O_\x168\xbf\xb8\x89+\'\x17O\xa7,\xf8\x95\xbc\xfc\xa1\x8dK\x1eV \x0c\x05?F\x10\xb6\xf8\xa5\x13\xdc\xc0\xdb\x82\x1f\xc9\xba\x08{\x9d{\xea\xc7\xf8\xca\x83\x828\x07J\x89\xf6W\x97P\xaa"\x86\x8c\xf8\xe9\xa5|\xa0`f/\xd0\x17\xb0Ow\xd2\xe6\x17\xf9$l\x0b;\x9e\x14x\x94\x08\x14\xed\x1c\x1e\x89q\xf9{L,B\x951\xf0g\x0f@aU\x80R\x1b\xf9\x8b\x19\x18e:4\x1e\x8d@\x89\x03Y\x1fCW\xf9\x90\xa4s\x90\x0e\xbc@\xa6Ot\xee\xe4Yr\xcb\xf9\xab\x93\xe3h\xac\x9e\x8d\x94\x0b\xbc-\xb6\x1d\xda1\xf9\xcb\xc5\x1f\x8a\x84\xa2\xadO\xcau\xbdG\t\xfcM\xf9\xe1\x88u5\x82\xfe\xb2X\x90\xcf8\xc6\x1c|\x88\xfa*\xad\xba\x87)A\x0f}\xc5\x0e\x8a!\xc2\x04d\xfaB}\xeca\x89\xf4+3\xf0\x0e\xc8\xads\x11\x93\xfav\xf5H\x82o\x07\n!O\xaa\'\x06i\xa9\xc1\xfa\xa1c\xcb\x0fv@<\xf5\x04\xf8\xc9,f\x05Q\xfa\xc5p\xa4U\xfcuD\x8b6\x06#\t\xb3N>\xfa\xd1\x1f\xfb\xa2\xcc,\xa1\x175\xe675\x18V4\xfa\xd7\t\x9c\x18\x83\xbf\x90\xbf\x13E\xe9\xd2\x14u\x99\xfa\xec\xd9\x13F\xc3I\x88.\x91z\xd8\xa21,$\xfa\xf34h\x8c\x1c\xd5\x0f\xee\xd4\xa4\xb4\x84\xf3)q\xfb\x14S;X\xe7C\x14\xce\xe9\xb5c\xf5\xa6\xad\x8e\xfbH\x05g\xfe\xaf\xfa\\\xb7S\xbd\x10\xcdZ\xea\x9b\xfbLz\xe5\x08Xr#\xebL\x0e1\xd3q=\x8d\xfbf\xd1h5\xad\xaa\xbe\xf7\xb1\xc5\x0b\x1b\xcd\xae\xf5\xfbi\xdc\xeez\xcd\xe4\x07\xc5U\x96\xf0D\x13j\xa8\xfb|\xa4V\xde\n/\x05)\xd1\xb4\xa2o\x12O\x88\xfb\x9c\x19L\xe2d7\xedf;\x849c\x95\x06q\xfb\xc5>M\x88\xdb\xdc2\xd9\xfd4\xef\x0c\xd5\xd2\xce\xfb\xce\xffqO\xf1\xc3\xb7{-"H\xfa\xe4=E\xfb\xdc\xacG\x95\x10\x10O/\x05o\x1e\x1b\xdb\x9a8\xfc\xca$\xc9a\xa1\xad\xdc\xaf\x1c\x8e8\xf9\xd9P\xac\xfc\xcf\x1c^\x1e\x1eE\xddW\xf1d8^\xbcMo\xfc\xff\'\xc7\x1f\xe6\r\x018\x06n\x18\xa9\xd4\xba\xaf\xfd^\xa9\x9ab\xca\xf0\xd1\xfdj:\xd6Ty\n\x16\xfd^\xe49Gi\xd4\xbe\xd1:@P\xb4\xfb\x02\x86\xfd\x82\xd1\xe9\xe0\xeaV\x87\xb5F"\xe6\x0b\xd8\xe9\xac\xfd\x9b\xd9\x1e\xf4w\xcb\t\x0b\x11\xa1\xb7\x84Jp+\xfd\xa3\x1et\x02\xf6\xe0ne\xc7>\x10v;\xd6J\xfd\xaa-\xde\xac\xa4\x1a"\x83@\xf7\x96\x9fFy\x8b\xfd\xcaY=\x1d\xf1\xf6\xb4O\x00\x822\xc3\xca1n\xfe4&\xc6\t\x06\xd4"7\x97+>_8Mt\xfeb\xfcC\xf5\xfe\xbe\xe8\x98A\x83\x11\x00\xb5\xbf\xb9\xfej\x84U\x02q\x12\x16\x1b7\xa6\xa4\xca\n\xfa\x1e\xfe\xc6\xb5\x0b\xc1L\xc9\x90\xdb\x9ff\x00\x10\x14[\x1c\xfe\xce \xfa\x85\xa2\x98\x1d*\xbd\xa9\xa4\x10=\x1d\x81\xfe\xd4&|\xd3\xe2\x948\xf1\xfb)\xe3\xb9\x91\xcbQ\xfe\xe5\xc5\x9ek~\xa1\xc3\xfd\xc6\xdf\xa0\xc4\xb9\x86\xe9\xff\x1fQ\xe5\x95?\xafN\xb7@\xd5\x0b\xaf\x9a\xc1\xf3\xff$\x07\xc9,\x81m*m+\xe8\xdb1\x06\xf6\x97\xffU\xca\x96\x8dz2\x02\x87\xb8\x9f\xa0x\\M\xb9\xffwC\xfaH\x8a\x06\x7ft\x88\x7f}X\xbe\xe9=\xff\xd05\x8a\x95\n<\xb6i\xa6\x8b%\xf9\xef\xf2p\xff\xdd\xcd.\xfbk\xb2\xed\x80\x84\x19\xdcv\x80\x84\xe7\xff\xe1\xcf\xb6\xd2\xa2\xf5\xd9\xf5\xdeCX,\xbe^\x9b'
\ No newline at end of file
diff --git a/components/safe_browsing/core/browser/safe_browsing_lookup_mechanism_experimenter.cc b/components/safe_browsing/core/browser/safe_browsing_lookup_mechanism_experimenter.cc
index 187287ba..ab970b1 100644
--- a/components/safe_browsing/core/browser/safe_browsing_lookup_mechanism_experimenter.cc
+++ b/components/safe_browsing/core/browser/safe_browsing_lookup_mechanism_experimenter.cc
@@ -40,13 +40,17 @@
     const GURL& last_committed_url,
     base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service_on_ui,
     UrlRealTimeMechanism::WebUIDelegate* webui_delegate,
-    base::WeakPtr<HashRealTimeService> hash_real_time_service_on_ui) {
+    base::WeakPtr<HashRealTimeService> hash_real_time_service_on_ui,
+    scoped_refptr<UrlCheckerDelegate> url_checker_delegate,
+    const base::RepeatingCallback<content::WebContents*()>&
+        web_contents_getter) {
   auto url_real_time_mechanism = std::make_unique<UrlRealTimeMechanism>(
       url, threat_types, request_destination, database_manager,
       /*can_check_db=*/true, can_check_high_confidence_allowlist,
       url_lookup_service_metric_suffix, last_committed_url, ui_task_runner_,
       url_lookup_service_on_ui, webui_delegate,
-      MechanismExperimentHashDatabaseCache::kUrlRealTimeOnly);
+      MechanismExperimentHashDatabaseCache::kUrlRealTimeOnly,
+      url_checker_delegate, web_contents_getter);
   auto hash_database_mechanism = std::make_unique<DatabaseManagerMechanism>(
       url, threat_types, database_manager,
       MechanismExperimentHashDatabaseCache::kHashDatabaseOnly,
diff --git a/components/safe_browsing/core/browser/safe_browsing_lookup_mechanism_experimenter.h b/components/safe_browsing/core/browser/safe_browsing_lookup_mechanism_experimenter.h
index 2d63b3b..c827851 100644
--- a/components/safe_browsing/core/browser/safe_browsing_lookup_mechanism_experimenter.h
+++ b/components/safe_browsing/core/browser/safe_browsing_lookup_mechanism_experimenter.h
@@ -65,7 +65,10 @@
       const GURL& last_committed_url,
       base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service_on_ui,
       UrlRealTimeMechanism::WebUIDelegate* webui_delegate,
-      base::WeakPtr<HashRealTimeService> hash_real_time_service_on_ui);
+      base::WeakPtr<HashRealTimeService> hash_real_time_service_on_ui,
+      scoped_refptr<UrlCheckerDelegate> url_checker_delegate,
+      const base::RepeatingCallback<content::WebContents*()>&
+          web_contents_getter);
 
   // This records the time that WillProcessResponse was called by
   // BrowserURLLoaderThrottle, which is used for logs when the experiment
diff --git a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc
index 514bf56..3ce87ff 100644
--- a/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc
+++ b/components/safe_browsing/core/browser/safe_browsing_url_checker_impl.cc
@@ -554,7 +554,8 @@
               can_check_high_confidence_allowlist_,
               url_lookup_service_metric_suffix_, last_committed_url_,
               url_lookup_service_on_ui_, webui_delegate_,
-              hash_realtime_service_on_ui_);
+              hash_realtime_service_on_ui_, url_checker_delegate_,
+              web_contents_getter_);
       return KickOffLookupMechanismResult(start_check_result, performed_check);
     } else {
       lookup_mechanism = std::make_unique<UrlRealTimeMechanism>(
@@ -563,7 +564,8 @@
           can_check_high_confidence_allowlist_,
           url_lookup_service_metric_suffix_, last_committed_url_,
           ui_task_runner_, url_lookup_service_on_ui_, webui_delegate_,
-          MechanismExperimentHashDatabaseCache::kNoExperiment);
+          MechanismExperimentHashDatabaseCache::kNoExperiment,
+          url_checker_delegate_, web_contents_getter_);
     }
   } else if (!can_check_db_) {
     return KickOffLookupMechanismResult(
diff --git a/components/safe_browsing/core/browser/url_realtime_mechanism.cc b/components/safe_browsing/core/browser/url_realtime_mechanism.cc
index d43289a..308098c4 100644
--- a/components/safe_browsing/core/browser/url_realtime_mechanism.cc
+++ b/components/safe_browsing/core/browser/url_realtime_mechanism.cc
@@ -53,7 +53,9 @@
     scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
     base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service_on_ui,
     WebUIDelegate* webui_delegate,
-    MechanismExperimentHashDatabaseCache experiment_cache_selection)
+    MechanismExperimentHashDatabaseCache experiment_cache_selection,
+    scoped_refptr<UrlCheckerDelegate> url_checker_delegate,
+    const base::RepeatingCallback<content::WebContents*()>& web_contents_getter)
     : SafeBrowsingLookupMechanism(url,
                                   threat_types,
                                   database_manager,
@@ -65,7 +67,9 @@
       last_committed_url_(last_committed_url),
       ui_task_runner_(ui_task_runner),
       url_lookup_service_on_ui_(url_lookup_service_on_ui),
-      webui_delegate_(webui_delegate) {}
+      webui_delegate_(webui_delegate),
+      url_checker_delegate_(url_checker_delegate),
+      web_contents_getter_(web_contents_getter) {}
 
 UrlRealTimeMechanism::~UrlRealTimeMechanism() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -213,14 +217,18 @@
 
   LogLookupResponse(*response);
 
+  RTLookupResponse::ThreatInfo::VerdictType rt_verdict_type =
+      RTLookupResponse::ThreatInfo::SAFE;
   SBThreatType sb_threat_type = SB_THREAT_TYPE_SAFE;
   if (response && (response->threat_info_size() > 0)) {
+    rt_verdict_type = response->threat_info(0).verdict_type();
     sb_threat_type =
         RealTimeUrlLookupServiceBase::GetSBThreatTypeForRTThreatType(
-            response->threat_info(0).threat_type(),
-            response->threat_info(0).verdict_type());
+            response->threat_info(0).threat_type(), rt_verdict_type);
   }
 
+  MaybePerformSuspiciousSiteDetection(rt_verdict_type);
+
   if (is_cached_response && sb_threat_type == SB_THREAT_TYPE_SAFE) {
     is_cached_safe_url_ = true;
     PerformHashBasedCheck(url_, /*real_time_request_failed=*/false);
@@ -340,4 +348,13 @@
   // object, so there is nothing safe to do here but return.
 }
 
+void UrlRealTimeMechanism::MaybePerformSuspiciousSiteDetection(
+    RTLookupResponse::ThreatInfo::VerdictType rt_verdict_type) {
+  if (rt_verdict_type == RTLookupResponse::ThreatInfo::SUSPICIOUS &&
+      base::FeatureList::IsEnabled(
+          safe_browsing::kSuspiciousSiteDetectionRTLookups)) {
+    url_checker_delegate_->NotifySuspiciousSiteDetected(web_contents_getter_);
+  }
+}
+
 }  // namespace safe_browsing
diff --git a/components/safe_browsing/core/browser/url_realtime_mechanism.h b/components/safe_browsing/core/browser/url_realtime_mechanism.h
index 9202f184..fa45d22 100644
--- a/components/safe_browsing/core/browser/url_realtime_mechanism.h
+++ b/components/safe_browsing/core/browser/url_realtime_mechanism.h
@@ -15,6 +15,7 @@
 #include "components/safe_browsing/core/browser/db/database_manager.h"
 #include "components/safe_browsing/core/browser/realtime/url_lookup_service_base.h"
 #include "components/safe_browsing/core/browser/safe_browsing_lookup_mechanism.h"
+#include "components/safe_browsing/core/browser/url_checker_delegate.h"
 #include "components/safe_browsing/core/common/proto/realtimeapi.pb.h"
 #include "url/gurl.h"
 
@@ -52,7 +53,10 @@
       scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
       base::WeakPtr<RealTimeUrlLookupServiceBase> url_lookup_service_on_ui,
       WebUIDelegate* webui_delegate,
-      MechanismExperimentHashDatabaseCache experiment_cache_selection);
+      MechanismExperimentHashDatabaseCache experiment_cache_selection,
+      scoped_refptr<UrlCheckerDelegate> url_checker_delegate,
+      const base::RepeatingCallback<content::WebContents*()>&
+          web_contents_getter);
   UrlRealTimeMechanism(const UrlRealTimeMechanism&) = delete;
   UrlRealTimeMechanism& operator=(const UrlRealTimeMechanism&) = delete;
   ~UrlRealTimeMechanism() override;
@@ -129,6 +133,9 @@
       absl::optional<ThreatSource> threat_source,
       bool real_time_request_failed);
 
+  void MaybePerformSuspiciousSiteDetection(
+      RTLookupResponse::ThreatInfo::VerdictType rt_verdict_type);
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   // This is used only for logging purposes, primarily (but not exclusively) to
@@ -173,6 +180,14 @@
   // outlive this object by contract.
   raw_ptr<WebUIDelegate> webui_delegate_ = nullptr;
 
+  // This object is used to call the |NotifySusiciousSiteDetected| method on
+  // URLs with suspicious verdicts.
+  scoped_refptr<UrlCheckerDelegate> url_checker_delegate_;
+
+  // This stores the callback method that will be used to obtain WebContents,
+  // which is needed to call the |NotifySusiciousSiteDetected| trigger.
+  base::RepeatingCallback<content::WebContents*()> web_contents_getter_;
+
   // If the URL is classified as safe in cache manager during real time
   // lookup.
   bool is_cached_safe_url_ = false;
diff --git a/components/safe_browsing/core/browser/url_realtime_mechanism_unittest.cc b/components/safe_browsing/core/browser/url_realtime_mechanism_unittest.cc
index 00bea948..092f901c 100644
--- a/components/safe_browsing/core/browser/url_realtime_mechanism_unittest.cc
+++ b/components/safe_browsing/core/browser/url_realtime_mechanism_unittest.cc
@@ -8,11 +8,13 @@
 #include "base/functional/bind.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/test/mock_callback.h"
+#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "components/safe_browsing/core/browser/db/test_database_manager.h"
 #include "components/safe_browsing/core/browser/db/util.h"
 #include "components/safe_browsing/core/browser/db/v4_protocol_manager_util.h"
 #include "components/safe_browsing/core/browser/url_checker_delegate.h"
+#include "components/safe_browsing/core/common/features.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "testing/platform_test.h"
@@ -79,6 +81,10 @@
         threat_type = RTLookupResponse::ThreatInfo::MANAGED_POLICY;
         verdict_type = RTLookupResponse::ThreatInfo::WARN;
         break;
+      case SB_THREAT_TYPE_SUSPICIOUS_SITE:
+        threat_type = RTLookupResponse::ThreatInfo::THREAT_TYPE_UNSPECIFIED;
+        verdict_type = RTLookupResponse::ThreatInfo::SUSPICIOUS;
+        break;
       default:
         NOTREACHED();
         threat_type = RTLookupResponse::ThreatInfo::THREAT_TYPE_UNSPECIFIED;
@@ -293,6 +299,53 @@
   bool called_cancel_check_ = false;
 };
 
+class MockUrlCheckerDelegate : public UrlCheckerDelegate {
+ public:
+  explicit MockUrlCheckerDelegate(
+      SafeBrowsingDatabaseManager* database_manager) {}
+
+  MOCK_METHOD1(MaybeDestroyNoStatePrefetchContents,
+               void(base::OnceCallback<content::WebContents*()>));
+  MOCK_METHOD5(StartDisplayingBlockingPageHelper,
+               void(const security_interstitials::UnsafeResource&,
+                    const std::string&,
+                    const net::HttpRequestHeaders&,
+                    bool,
+                    bool));
+  MOCK_METHOD2(StartObservingInteractionsForDelayedBlockingPageHelper,
+               void(const security_interstitials::UnsafeResource&, bool));
+  MOCK_METHOD5(ShouldSkipRequestCheck,
+               bool(const GURL&,
+                    int,
+                    int,
+                    base::optional_ref<const base::UnguessableToken>,
+                    bool));
+  MOCK_METHOD1(NotifySuspiciousSiteDetected,
+               void(const base::RepeatingCallback<content::WebContents*()>&));
+  MOCK_METHOD0(GetUIManager, BaseUIManager*());
+  MOCK_METHOD1(IsUrlAllowlisted, bool(const GURL& url));
+  MOCK_METHOD1(SetPolicyAllowlistDomains,
+               void(const std::vector<std::string>&));
+  MOCK_METHOD0(GetThreatTypes, const SBThreatTypeSet&());
+  MOCK_METHOD0(GetDatabaseManager, SafeBrowsingDatabaseManager*());
+  MOCK_METHOD3(CheckLookupMechanismExperimentEligibility,
+               void(const security_interstitials::UnsafeResource&,
+                    base::OnceCallback<void(bool)>,
+                    scoped_refptr<base::SequencedTaskRunner>));
+  MOCK_METHOD0(GetNumCheckExperimentEligibilityCalls, int());
+  MOCK_METHOD3(CheckExperimentEligibilityAndStartBlockingPage,
+               void(const security_interstitials::UnsafeResource&,
+                    base::OnceCallback<void(bool)>,
+                    scoped_refptr<base::SequencedTaskRunner>));
+  MOCK_METHOD0(GetNumCheckExperimentEligibilityAndStartBlockingPageCalls,
+               int());
+  MOCK_METHOD2(SetLookupMechanismExperimentEligibility,
+               void(const GURL&, bool));
+
+ protected:
+  ~MockUrlCheckerDelegate() override = default;
+};
+
 }  // namespace
 
 class UrlRealTimeMechanismTest : public PlatformTest {
@@ -301,6 +354,7 @@
     PlatformTest::SetUp();
     database_manager_ = new MockSafeBrowsingDatabaseManager();
     url_lookup_service_ = std::make_unique<MockRealTimeUrlLookupService>();
+    url_checker_delegate_ = new MockUrlCheckerDelegate(database_manager_.get());
   }
 
   std::unique_ptr<UrlRealTimeMechanism> CreateUrlRealTimeMechanism(
@@ -318,13 +372,15 @@
         base::SequencedTaskRunner::GetCurrentDefault(),
         url_lookup_service_->GetWeakPtr(),
         /*webui_delegate_=*/nullptr,
-        MechanismExperimentHashDatabaseCache::kNoExperiment);
+        MechanismExperimentHashDatabaseCache::kNoExperiment,
+        url_checker_delegate_, mock_web_contents_getter.Get());
   }
 
  protected:
   base::test::TaskEnvironment task_environment_;
   scoped_refptr<MockSafeBrowsingDatabaseManager> database_manager_;
   std::unique_ptr<MockRealTimeUrlLookupService> url_lookup_service_;
+  scoped_refptr<MockUrlCheckerDelegate> url_checker_delegate_;
 };
 
 MATCHER_P3(Matches,
@@ -505,4 +561,31 @@
   task_environment_.RunUntilIdle();
 }
 
+TEST_F(UrlRealTimeMechanismTest, CheckUrl_UrlRealTime_SuspiciousSiteDetection) {
+  base::test::ScopedFeatureList scoped_feature_list_;
+  scoped_feature_list_.InitAndEnableFeature(
+      safe_browsing::kSuspiciousSiteDetectionRTLookups);
+  GURL url("https://example.test/");
+  auto mechanism = CreateUrlRealTimeMechanism(url, /*can_check_db=*/true);
+  url_lookup_service_->SetThreatTypeForUrl(url, SB_THREAT_TYPE_SUSPICIOUS_SITE,
+                                           /*should_complete_lookup=*/true);
+  database_manager_->SetAllowlistResultForUrl(url, false);
+  base::MockCallback<SafeBrowsingLookupMechanism::CompleteCheckResultCallback>
+      callback;
+  mechanism->StartCheck(callback.Get());
+
+  // Suspicious site detection should happen for URL real time lookups.
+  EXPECT_CALL(*url_checker_delegate_, NotifySuspiciousSiteDetected(testing::_))
+      .Times(1);
+
+  EXPECT_CALL(callback,
+              Run(Matches(
+                  /*matched_high_confidence_allowlist=*/false,
+                  /*locally_cached_results_threat_type=*/SB_THREAT_TYPE_SAFE,
+                  /*real_time_request_failed=*/false)))
+      .Times(1);
+
+  task_environment_.RunUntilIdle();
+}
+
 }  // namespace safe_browsing
diff --git a/components/safe_browsing/core/common/features.cc b/components/safe_browsing/core/common/features.cc
index 4bade0d..c4cb2fe 100644
--- a/components/safe_browsing/core/common/features.cc
+++ b/components/safe_browsing/core/common/features.cc
@@ -289,6 +289,10 @@
     &kStrictDownloadTimeout, "TimeoutMilliseconds",
     /*default_value=*/7000};
 
+BASE_FEATURE(kSuspiciousSiteDetectionRTLookups,
+             "SuspiciousSiteDetectionRTLookups",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 BASE_FEATURE(kSuspiciousSiteTriggerQuotaFeature,
              "SafeBrowsingSuspiciousSiteTriggerQuota",
              base::FEATURE_ENABLED_BY_DEFAULT);
@@ -387,6 +391,7 @@
     {&kSevenZipEvaluationEnabled, true},
     {&kSimplifiedUrlDisplay, true},
     {&kStrictDownloadTimeout, true},
+    {&kSuspiciousSiteDetectionRTLookups, false},
     {&kSuspiciousSiteTriggerQuotaFeature, true},
     {&kTailoredSecurityIntegration, true},
     {&kThreatDomDetailsTagAndAttributeFeature, false},
diff --git a/components/safe_browsing/core/common/features.h b/components/safe_browsing/core/common/features.h
index 407601d0..3e67fbf 100644
--- a/components/safe_browsing/core/common/features.h
+++ b/components/safe_browsing/core/common/features.h
@@ -263,6 +263,9 @@
 // Specifies the duration of the timeout, in milliseconds.
 extern const base::FeatureParam<int> kStrictDownloadTimeoutMilliseconds;
 
+// Enables suspicious site detection for real time URL lookups.
+BASE_DECLARE_FEATURE(kSuspiciousSiteDetectionRTLookups);
+
 // Controls the daily quota for the suspicious site trigger.
 BASE_DECLARE_FEATURE(kSuspiciousSiteTriggerQuotaFeature);
 
diff --git a/components/segmentation_platform/internal/signals/histogram_signal_handler.cc b/components/segmentation_platform/internal/signals/histogram_signal_handler.cc
index 359a89bd..0982556 100644
--- a/components/segmentation_platform/internal/signals/histogram_signal_handler.cc
+++ b/components/segmentation_platform/internal/signals/histogram_signal_handler.cc
@@ -6,7 +6,6 @@
 #include <cstdint>
 
 #include "base/containers/contains.h"
-#include "base/containers/cxx20_erase_unordered_map.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/metrics/metrics_hashes.h"
diff --git a/components/services/app_service/public/cpp/app_launch_util.cc b/components/services/app_service/public/cpp/app_launch_util.cc
index 6df3b78..6838aad 100644
--- a/components/services/app_service/public/cpp/app_launch_util.cc
+++ b/components/services/app_service/public/cpp/app_launch_util.cc
@@ -95,6 +95,8 @@
     case LaunchSource::kFromSysTrayCalendar:
       return ApplicationLaunchSource::
           APPLICATION_LAUNCH_SOURCE_SYSTEM_TRAY_CALENDAR;
+    case LaunchSource::kFromInstaller:
+      return ApplicationLaunchSource::APPLICATION_LAUNCH_SOURCE_INSTALLER;
   }
 }
 
diff --git a/components/services/app_service/public/cpp/app_launch_util.h b/components/services/app_service/public/cpp/app_launch_util.h
index 71c42fd..303027a 100644
--- a/components/services/app_service/public/cpp/app_launch_util.h
+++ b/components/services/app_service/public/cpp/app_launch_util.h
@@ -65,10 +65,11 @@
   kFromProfileMenu =
       35,  // Profile menu of installable chrome://password-manager WebUI.
   kFromSysTrayCalendar = 36,  // Launches from the system tray Calendar.
+  kFromInstaller = 37,        // Installation UI
 
   // Add any new values above this one, and update kMaxValue to the highest
   // enumerator value.
-  kMaxValue = kFromSysTrayCalendar,
+  kMaxValue = kFromInstaller,
 };
 
 // Don't remove items or change the order of this enum.  It's used in
diff --git a/components/services/app_service/public/cpp/types_util.cc b/components/services/app_service/public/cpp/types_util.cc
index 6f681171..98f8eb3 100644
--- a/components/services/app_service/public/cpp/types_util.cc
+++ b/components/services/app_service/public/cpp/types_util.cc
@@ -50,6 +50,7 @@
     case apps::LaunchSource::kFromReparenting:
     case apps::LaunchSource::kFromProfileMenu:
     case apps::LaunchSource::kFromSysTrayCalendar:
+    case apps::LaunchSource::kFromInstaller:
       return true;
     case apps::LaunchSource::kUnknown:
     case apps::LaunchSource::kFromChromeInternal:
diff --git a/components/services/app_service/public/protos/app_types.proto b/components/services/app_service/public/protos/app_types.proto
index 2b614fb..7baa6ed 100644
--- a/components/services/app_service/public/protos/app_types.proto
+++ b/components/services/app_service/public/protos/app_types.proto
@@ -106,6 +106,7 @@
   APPLICATION_LAUNCH_SOURCE_REPARENTING = 34;
   APPLICATION_LAUNCH_SOURCE_PROFILE_MENU = 35;
   APPLICATION_LAUNCH_SOURCE_SYSTEM_TRAY_CALENDAR = 36;
+  APPLICATION_LAUNCH_SOURCE_INSTALLER = 37;
 }
 
 // Describes the app uninstall source. Should be kept in sync with
diff --git a/components/supervised_user/core/browser/supervised_user_preferences.cc b/components/supervised_user/core/browser/supervised_user_preferences.cc
index 551df25..07589e8 100644
--- a/components/supervised_user/core/browser/supervised_user_preferences.cc
+++ b/components/supervised_user/core/browser/supervised_user_preferences.cc
@@ -175,6 +175,11 @@
   return pref_service.GetString(prefs::kSupervisedUserId) == kChildAccountSUID;
 }
 
+bool IsSafeSitesEnabled(const PrefService& pref_service) {
+  return supervised_user::IsChildAccount(pref_service) &&
+         pref_service.GetBoolean(prefs::kSupervisedUserSafeSites);
+}
+
 bool IsSubjectToParentalControls(const PrefService& pref_service) {
   return IsChildAccount(pref_service) && IsChildAccountSupervisionEnabled();
 }
diff --git a/components/supervised_user/core/browser/supervised_user_preferences.h b/components/supervised_user/core/browser/supervised_user_preferences.h
index e8d0b6c..dcb6c19 100644
--- a/components/supervised_user/core/browser/supervised_user_preferences.h
+++ b/components/supervised_user/core/browser/supervised_user_preferences.h
@@ -31,6 +31,9 @@
 // is no dedicated method for the feature (e.g IsURLFilteringEnabled).
 bool IsChildAccount(const PrefService& pref_service);
 
+// Returns true if the safe sites preference is enabled and user is supervised.
+bool IsSafeSitesEnabled(const PrefService& pref_service);
+
 // Returns true if both the primary account is a child account subject to
 // parental controls and the platform supports Family Link supervision features.
 bool IsSubjectToParentalControls(const PrefService& pref_service);
diff --git a/components/supervised_user/core/browser/supervised_user_preferences_unittest.cc b/components/supervised_user/core/browser/supervised_user_preferences_unittest.cc
index 043fdd42..19d0d137 100644
--- a/components/supervised_user/core/browser/supervised_user_preferences_unittest.cc
+++ b/components/supervised_user/core/browser/supervised_user_preferences_unittest.cc
@@ -122,6 +122,27 @@
   EXPECT_FALSE(supervised_user::IsChildAccount(pref_service_));
 }
 
+TEST_F(SupervisedUserPreferencesTest, IsSafeSitesEnabledSupervisedUser) {
+  pref_service_.SetBoolean(prefs::kSupervisedUserSafeSites, true);
+  pref_service_.SetString(prefs::kSupervisedUserId,
+                            supervised_user::kChildAccountSUID);
+
+  EXPECT_TRUE(supervised_user::IsSafeSitesEnabled(pref_service_));
+}
+
+TEST_F(SupervisedUserPreferencesTest, IsSafeSitesEnabledNonSupervisedUser) {
+  pref_service_.SetBoolean(prefs::kSupervisedUserSafeSites, true);
+  pref_service_.SetString(prefs::kSupervisedUserId, std::string());
+
+  EXPECT_FALSE(supervised_user::IsSafeSitesEnabled(pref_service_));
+}
+
+TEST_F(SupervisedUserPreferencesTest, IsSafeSitesDisabled) {
+  pref_service_.SetBoolean(prefs::kSupervisedUserSafeSites, false);
+
+  EXPECT_FALSE(supervised_user::IsSafeSitesEnabled(pref_service_));
+}
+
 enum class UrlFilteringStatus { kEnabled, kDisabled };
 
 // Tests for the method IsSubjectToParentalControlsForSupervisedUser which
diff --git a/components/supervised_user/core/browser/supervised_user_service.cc b/components/supervised_user/core/browser/supervised_user_service.cc
index a4751c6..5649291 100644
--- a/components/supervised_user/core/browser/supervised_user_service.cc
+++ b/components/supervised_user/core/browser/supervised_user_service.cc
@@ -295,11 +295,6 @@
   }
 }
 
-bool SupervisedUserService::IsSafeSitesEnabled() const {
-  return supervised_user::IsChildAccount(user_prefs_.get()) &&
-         user_prefs_->GetBoolean(prefs::kSupervisedUserSafeSites);
-}
-
 void SupervisedUserService::OnSafeSitesSettingChanged() {
   UpdateAsyncUrlChecker();
 
@@ -319,7 +314,7 @@
       SupervisedUserURLFilter::BehaviorFromInt(behavior_value);
 
   bool use_online_check =
-      IsSafeSitesEnabled() ||
+      IsSafeSitesEnabled(user_prefs_.get()) ||
       behavior == supervised_user::FilteringBehavior::kBlock;
 
   if (use_online_check != url_filter_->HasAsyncURLChecker()) {
diff --git a/components/supervised_user/core/browser/supervised_user_service.h b/components/supervised_user/core/browser/supervised_user_service.h
index f015298..0b9ede72 100644
--- a/components/supervised_user/core/browser/supervised_user_service.h
+++ b/components/supervised_user/core/browser/supervised_user_service.h
@@ -178,8 +178,6 @@
 
   void OnDefaultFilteringBehaviorChanged();
 
-  bool IsSafeSitesEnabled() const;
-
   void OnSafeSitesSettingChanged();
 
   void UpdateAsyncUrlChecker();
diff --git a/components/sync/base/client_tag_hash.cc b/components/sync/base/client_tag_hash.cc
index 59f44a99..1ee6ec7 100644
--- a/components/sync/base/client_tag_hash.cc
+++ b/components/sync/base/client_tag_hash.cc
@@ -24,8 +24,8 @@
   serialized_type.AppendToString(&hash_input);
   hash_input.append(client_tag);
 
-  std::string encode_output;
-  base::Base64Encode(base::SHA1HashString(hash_input), &encode_output);
+  std::string encode_output = base::Base64Encode(
+      base::SHA1HashSpan(base::as_bytes(base::make_span(hash_input))));
   return FromHashed(encode_output);
 }
 
diff --git a/components/sync/base/hash_util.cc b/components/sync/base/hash_util.cc
index 9dc69fee..347fec12 100644
--- a/components/sync/base/hash_util.cc
+++ b/components/sync/base/hash_util.cc
@@ -27,9 +27,8 @@
   serialized_type.AppendToString(&hash_input);
   hash_input.append(originator_cache_guid + originator_client_item_id);
 
-  std::string encode_output;
-  base::Base64Encode(base::SHA1HashString(hash_input), &encode_output);
-  return encode_output;
+  return base::Base64Encode(
+      base::SHA1HashSpan(base::as_bytes(base::make_span(hash_input))));
 }
 
 std::string GetUnhashedClientTagFromAutofillWalletSpecifics(
diff --git a/components/sync/base/unique_position_unittest.cc b/components/sync/base/unique_position_unittest.cc
index c144367..a638a246 100644
--- a/components/sync/base/unique_position_unittest.cc
+++ b/components/sync/base/unique_position_unittest.cc
@@ -394,9 +394,8 @@
     // suffix format is a base64'ed SHA1 hash, which should be fairly close to
     // random anyway.
     std::string input = cache_guid_ + base::NumberToString(next_id_--);
-    std::string output;
-    base::Base64Encode(base::SHA1HashString(input), &output);
-    return output;
+    return base::Base64Encode(
+        base::SHA1HashSpan(base::as_bytes(base::make_span(input))));
   }
 
  private:
diff --git a/components/variations/field_trial_config/field_trial_util_unittest.cc b/components/variations/field_trial_config/field_trial_util_unittest.cc
index 356aa452..b2c6621 100644
--- a/components/variations/field_trial_config/field_trial_util_unittest.cc
+++ b/components/variations/field_trial_config/field_trial_util_unittest.cc
@@ -518,13 +518,14 @@
       Study::PHONE,
       Study::TABLET,
       Study::MEET_DEVICE,
+      Study::FOLDABLE,
   };
   const FieldTrialTestingExperimentParams array_kFieldTrialConfig_params[] =
       {{"x", "1"}, {"y", "2"}};
   const FieldTrialTestingExperiment array_kFieldTrialConfig_experiments[] = {
-      {"TestGroup", &platform, 1, form_factors, 4, absl::nullopt, nullptr,
-       array_kFieldTrialConfig_params, 2, nullptr, 0, nullptr, 0, nullptr,
-       nullptr, 0},
+      {"TestGroup", &platform, 1, form_factors, std::size(form_factors),
+       absl::nullopt, nullptr, array_kFieldTrialConfig_params, 2, nullptr, 0,
+       nullptr, 0, nullptr,nullptr, 0},
   };
   const FieldTrialTestingStudy array_kFieldTrialConfig_studies[] =
       {{"TestTrial", array_kFieldTrialConfig_experiments, 1}};
diff --git a/components/variations/service/variations_service_client.cc b/components/variations/service/variations_service_client.cc
index 527a95f..e51b992 100644
--- a/components/variations/service/variations_service_client.cc
+++ b/components/variations/service/variations_service_client.cc
@@ -47,6 +47,17 @@
 }
 
 Study::FormFactor VariationsServiceClient::GetCurrentFormFactor() {
+// Temporary workaround to report foldable for variations without affecting
+// other form factors. This will be removed and replaced with a long-term
+// solution in DeviceFormFactor::GetDeviceFormFactor() after conducting an
+// audit of form factor usage or exposing ui_mode.
+// FormFactorMetricsProvider::GetFormFactor() also needs to be updated.
+#if BUILDFLAG(IS_ANDROID)
+  if (base::android::BuildInfo::GetInstance()->is_foldable()) {
+    return Study::FOLDABLE;
+  }
+#endif
+
 #if BUILDFLAG(PLATFORM_CFM)
   return Study::MEET_DEVICE;
 #else
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 49f78ae3..b2b75774 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -1183,6 +1183,8 @@
     "interest_group/interest_group_auction_reporter.h",
     "interest_group/interest_group_caching_storage.cc",
     "interest_group/interest_group_caching_storage.h",
+    "interest_group/interest_group_features.cc",
+    "interest_group/interest_group_features.h",
     "interest_group/interest_group_k_anonymity_manager.cc",
     "interest_group/interest_group_k_anonymity_manager.h",
     "interest_group/interest_group_manager_impl.cc",
diff --git a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
index 66ed45d5..330168c 100644
--- a/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
+++ b/content/browser/android/java/gin_java_bridge_dispatcher_host.cc
@@ -46,17 +46,6 @@
 GinJavaBridgeDispatcherHost::~GinJavaBridgeDispatcherHost() {
 }
 
-void GinJavaBridgeDispatcherHost::BindNewHost(
-    GlobalRenderFrameHostId routing_id,
-    mojo::PendingReceiver<mojom::GinJavaBridgeHost> host) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  JavaBridgeThread::GetTaskRunner()->PostTask(
-      FROM_HERE,
-      base::BindOnce(
-          &GinJavaBridgeDispatcherHost::BindNewHostOnBackgroundThread, this,
-          routing_id, std::move(host)));
-}
-
 void GinJavaBridgeDispatcherHost::BindNewHostOnBackgroundThread(
     GlobalRenderFrameHostId routing_id,
     mojo::PendingReceiver<mojom::GinJavaBridgeHost> host) {
@@ -85,10 +74,19 @@
       return nullptr;
     }
     CHECK(frame_host->IsRenderFrameLive());
-    auto& bound_host = remotes_[routing_id];
+    auto& bound_remote = remotes_[routing_id];
     frame_host->GetRemoteAssociatedInterfaces()->GetInterface(
-        bound_host.BindNewEndpointAndPassReceiver());
-    return bound_host.get();
+        bound_remote.BindNewEndpointAndPassReceiver());
+
+    mojo::PendingReceiver<mojom::GinJavaBridgeHost> host_receiver;
+    bound_remote->SetHost(host_receiver.InitWithNewPipeAndPassRemote());
+    JavaBridgeThread::GetTaskRunner()->PostTask(
+        FROM_HERE,
+        base::BindOnce(
+            &GinJavaBridgeDispatcherHost::BindNewHostOnBackgroundThread, this,
+            routing_id, std::move(host_receiver)));
+
+    return bound_remote.get();
   }
   return it->second.get();
 }
diff --git a/content/browser/android/java/gin_java_bridge_dispatcher_host.h b/content/browser/android/java/gin_java_bridge_dispatcher_host.h
index 166f995f..f1ae313 100644
--- a/content/browser/android/java/gin_java_bridge_dispatcher_host.h
+++ b/content/browser/android/java/gin_java_bridge_dispatcher_host.h
@@ -64,9 +64,6 @@
   void PrimaryMainDocumentElementAvailable() override;
   void PrimaryPageChanged(Page& page) override;
 
-  void BindNewHost(GlobalRenderFrameHostId routing_id,
-                   mojo::PendingReceiver<mojom::GinJavaBridgeHost> host);
-
   // GinJavaMethodInvocationHelper::DispatcherDelegate
   JavaObjectWeakGlobalRef GetObjectWeakRef(
       GinJavaBoundObject::ObjectID object_id) override;
diff --git a/content/browser/android/javascript_injector.cc b/content/browser/android/javascript_injector.cc
index deefd8cc..f48ff46 100644
--- a/content/browser/android/javascript_injector.cc
+++ b/content/browser/android/javascript_injector.cc
@@ -77,16 +77,6 @@
   return reinterpret_cast<intptr_t>(injector);
 }
 
-void JavascriptInjector::BindGinJavaBridgeHost(
-    RenderFrameHost* host,
-    mojo::PendingReceiver<mojom::GinJavaBridgeHost> receiver) {
-  auto* injector = JavascriptInjector::FromWebContents(
-      WebContents::FromRenderFrameHost(host));
-  CHECK(injector);
-  injector->java_bridge_dispatcher_host_->BindNewHost(host->GetGlobalId(),
-                                                      std::move(receiver));
-}
-
 WEB_CONTENTS_USER_DATA_KEY_IMPL(JavascriptInjector);
 
 }  // namespace content
diff --git a/content/browser/android/javascript_injector.h b/content/browser/android/javascript_injector.h
index 6999fd3d9..d64dffb 100644
--- a/content/browser/android/javascript_injector.h
+++ b/content/browser/android/javascript_injector.h
@@ -15,7 +15,6 @@
 namespace content {
 
 class GinJavaBridgeDispatcherHost;
-class RenderFrameHost;
 
 class JavascriptInjector : public WebContentsUserData<JavascriptInjector> {
  public:
@@ -44,11 +43,6 @@
   void RemoveInterface(JNIEnv* env,
                        const base::android::JavaParamRef<jobject>& /* obj */,
                        const base::android::JavaParamRef<jstring>& name);
-
-  static void BindGinJavaBridgeHost(
-      RenderFrameHost* host,
-      mojo::PendingReceiver<mojom::GinJavaBridgeHost> receiver);
-
  private:
   friend class content::WebContentsUserData<JavascriptInjector>;
   // A weak reference to the Java JavascriptInjectorImpl object.
diff --git a/content/browser/attribution_reporting/attribution_internals.mojom b/content/browser/attribution_reporting/attribution_internals.mojom
index d9242cd..55771e0 100644
--- a/content/browser/attribution_reporting/attribution_internals.mojom
+++ b/content/browser/attribution_reporting/attribution_internals.mojom
@@ -6,6 +6,7 @@
 
 import "components/attribution_reporting/registration.mojom";
 import "components/attribution_reporting/source_type.mojom";
+import "components/attribution_reporting/trigger_data_matching.mojom";
 import "content/browser/attribution_reporting/aggregatable_result.mojom";
 import "content/browser/attribution_reporting/attribution_reporting.mojom";
 import "content/browser/attribution_reporting/event_level_result.mojom";
@@ -110,7 +111,7 @@
   map<string, string> aggregation_keys;
   uint64 aggregatable_budget_consumed;
   array<uint64> aggregatable_dedup_keys;
-  attribution_reporting.mojom.TriggerConfig trigger_config;
+  attribution_reporting.mojom.TriggerDataMatching trigger_data_matching;
   bool debug_cookie_set;
 
   enum Attributability {
diff --git a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
index 5ce0d0a..58425f0 100644
--- a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
+++ b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
@@ -92,7 +92,8 @@
                 attribution_reporting::HexEncodeAggregationKey(key.second));
           }),
       source.aggregatable_budget_consumed(), source.aggregatable_dedup_keys(),
-      source.trigger_config(), source.debug_cookie_set(), attributability);
+      source.trigger_data_matching(), source.debug_cookie_set(),
+      attributability);
 }
 
 void ForwardSourcesToWebUI(
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc
index 9c8be9d..6f7718e 100644
--- a/content/browser/attribution_reporting/attribution_storage_sql.cc
+++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -367,8 +367,7 @@
       max_event_level_reports, priority, std::move(*filter_data), debug_key,
       std::move(*aggregation_keys), *attribution_logic, *active_state,
       source_id, aggregatable_budget_consumed, randomized_response_rate,
-      attribution_reporting::TriggerConfig(trigger_data_matching),
-      debug_cookie_set);
+      trigger_data_matching, debug_cookie_set);
   if (!stored_source.has_value()) {
     return absl::nullopt;
   }
@@ -600,10 +599,10 @@
   statement.BindBlob(14, SerializeAggregationKeys(reg.aggregation_keys));
   statement.BindBlob(15, SerializeFilterData(reg.filter_data));
   statement.BindBlob(
-      16, SerializeReadOnlySourceData(reg.event_report_windows,
-                                      reg.max_event_level_reports,
-                                      randomized_response_data.rate(),
-                                      reg.trigger_config, debug_cookie_set));
+      16, SerializeReadOnlySourceData(
+              reg.event_report_windows, reg.max_event_level_reports,
+              randomized_response_data.rate(), reg.trigger_data_matching,
+              debug_cookie_set));
 
   if (!statement.Run()) {
     return StoreSourceResult::InternalError();
@@ -632,7 +631,7 @@
       reg.priority, reg.filter_data, reg.debug_key, reg.aggregation_keys,
       attribution_logic, *active_state, source_id,
       /*aggregatable_budget_consumed=*/0, randomized_response_data.rate(),
-      reg.trigger_config, debug_cookie_set);
+      reg.trigger_data_matching, debug_cookie_set);
 
   if (!stored_source.has_value() ||
       !rate_limit_table_.AddRateLimitForSource(&db_, *stored_source)) {
@@ -1282,7 +1281,7 @@
   }
 
   auto trigger_spec_it = source.trigger_specs().find(
-      event_trigger->data, source.trigger_config().trigger_data_matching());
+      event_trigger->data, source.trigger_data_matching());
   if (!trigger_spec_it) {
     return EventLevelResult::kNoMatchingTriggerData;
   }
diff --git a/content/browser/attribution_reporting/attribution_storage_unittest.cc b/content/browser/attribution_reporting/attribution_storage_unittest.cc
index a68fa67..1c50d46 100644
--- a/content/browser/attribution_reporting/attribution_storage_unittest.cc
+++ b/content/browser/attribution_reporting/attribution_storage_unittest.cc
@@ -3976,8 +3976,7 @@
         SourceBuilder()
             .SetSourceType(
                 SourceType::kNavigation)  // valid trigger data [0, 7]
-            .SetTriggerConfig(attribution_reporting::TriggerConfig(
-                test_case.trigger_data_matching))
+            .SetTriggerDataMatching(test_case.trigger_data_matching)
             .Build());
 
     EXPECT_EQ(
diff --git a/content/browser/attribution_reporting/attribution_test_utils.cc b/content/browser/attribution_reporting/attribution_test_utils.cc
index 53cc94e..357fcd9d 100644
--- a/content/browser/attribution_reporting/attribution_test_utils.cc
+++ b/content/browser/attribution_reporting/attribution_test_utils.cc
@@ -25,6 +25,7 @@
 #include "components/attribution_reporting/suitable_origin.h"
 #include "components/attribution_reporting/test_utils.h"
 #include "components/attribution_reporting/trigger_config.h"
+#include "components/attribution_reporting/trigger_data_matching.mojom-forward.h"
 #include "components/attribution_reporting/trigger_registration.h"
 #include "content/browser/attribution_reporting/attribution_observer.h"
 #include "content/browser/attribution_reporting/attribution_reporting.mojom.h"
@@ -210,9 +211,9 @@
   return *this;
 }
 
-SourceBuilder& SourceBuilder::SetTriggerConfig(
-    attribution_reporting::TriggerConfig config) {
-  registration_.trigger_config = std::move(config);
+SourceBuilder& SourceBuilder::SetTriggerDataMatching(
+    attribution_reporting::mojom::TriggerDataMatching trigger_data_matching) {
+  registration_.trigger_data_matching = trigger_data_matching;
   return *this;
 }
 
@@ -239,7 +240,7 @@
       registration_.filter_data, registration_.debug_key,
       registration_.aggregation_keys, attribution_logic_, active_state_,
       source_id_, aggregatable_budget_consumed_, randomized_response_rate_,
-      registration_.trigger_config, debug_cookie_set_);
+      registration_.trigger_data_matching, debug_cookie_set_);
   source.SetDedupKeys(dedup_keys_);
   source.SetAggregatableDedupKeys(aggregatable_dedup_keys_);
   return source;
@@ -503,7 +504,7 @@
         source.filter_data(), source.debug_key(), source.aggregation_keys(),
         source.attribution_logic(), source.active_state(), source.dedup_keys(),
         source.aggregatable_budget_consumed(), source.aggregatable_dedup_keys(),
-        source.randomized_response_rate(), source.trigger_config(),
+        source.randomized_response_rate(), source.trigger_data_matching(),
         source.debug_cookie_set());
   };
   return tie(a) == tie(b);
@@ -659,7 +660,8 @@
       << ",aggregatable_budget_consumed="
       << source.aggregatable_budget_consumed()
       << ",randomized_response_rate=" << source.randomized_response_rate()
-      << ",trigger_config=" << source.trigger_config() << ",dedup_keys=[";
+      << ",trigger_data_matching=" << source.trigger_data_matching()
+      << ",dedup_keys=[";
 
   const char* separator = "";
   for (int64_t dedup_key : source.dedup_keys()) {
diff --git a/content/browser/attribution_reporting/attribution_test_utils.h b/content/browser/attribution_reporting/attribution_test_utils.h
index c5b4523..0663698 100644
--- a/content/browser/attribution_reporting/attribution_test_utils.h
+++ b/content/browser/attribution_reporting/attribution_test_utils.h
@@ -21,6 +21,7 @@
 #include "components/attribution_reporting/source_type.mojom.h"
 #include "components/attribution_reporting/suitable_origin.h"
 #include "components/attribution_reporting/test_utils.h"
+#include "components/attribution_reporting/trigger_data_matching.mojom-forward.h"
 #include "content/browser/attribution_reporting/aggregatable_histogram_contribution.h"
 #include "content/browser/attribution_reporting/attribution_info.h"
 #include "content/browser/attribution_reporting/attribution_report.h"
@@ -35,7 +36,6 @@
 namespace attribution_reporting {
 class AggregationKeys;
 class EventReportWindows;
-class TriggerConfig;
 }  // namespace attribution_reporting
 
 namespace net {
@@ -119,7 +119,8 @@
 
   SourceBuilder& SetMaxEventLevelReports(int max_event_level_reports);
 
-  SourceBuilder& SetTriggerConfig(attribution_reporting::TriggerConfig);
+  SourceBuilder& SetTriggerDataMatching(
+      attribution_reporting::mojom::TriggerDataMatching);
 
   SourceBuilder& SetDebugCookieSet(bool debug_cookie_set);
 
diff --git a/content/browser/attribution_reporting/privacy_math.cc b/content/browser/attribution_reporting/privacy_math.cc
index 227199b..1ea60bd 100644
--- a/content/browser/attribution_reporting/privacy_math.cc
+++ b/content/browser/attribution_reporting/privacy_math.cc
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include "base/check_op.h"
+#include "base/notreached.h"
 #include "base/numerics/checked_math.h"
 #include "base/rand_util.h"
 #include "base/ranges/algorithm.h"
diff --git a/content/browser/attribution_reporting/sql_utils.cc b/content/browser/attribution_reporting/sql_utils.cc
index 47a1592..368fd621 100644
--- a/content/browser/attribution_reporting/sql_utils.cc
+++ b/content/browser/attribution_reporting/sql_utils.cc
@@ -145,7 +145,7 @@
     const attribution_reporting::EventReportWindows& event_report_windows,
     attribution_reporting::MaxEventLevelReports max_event_level_reports,
     double randomized_response_rate,
-    const attribution_reporting::TriggerConfig& trigger_config,
+    TriggerDataMatching trigger_data_matching,
     bool debug_cookie_set) {
   DCHECK_GE(randomized_response_rate, 0);
   DCHECK_LE(randomized_response_rate, 1);
@@ -156,7 +156,7 @@
 
   msg.set_randomized_response_rate(randomized_response_rate);
 
-  switch (trigger_config.trigger_data_matching()) {
+  switch (trigger_data_matching) {
     case TriggerDataMatching::kExact:
       msg.set_trigger_data_matching(
           proto::AttributionReadOnlySourceData::EXACT);
diff --git a/content/browser/attribution_reporting/sql_utils.h b/content/browser/attribution_reporting/sql_utils.h
index 37f0be5..e71bea6 100644
--- a/content/browser/attribution_reporting/sql_utils.h
+++ b/content/browser/attribution_reporting/sql_utils.h
@@ -10,6 +10,7 @@
 #include <string>
 
 #include "components/attribution_reporting/source_type.mojom-forward.h"
+#include "components/attribution_reporting/trigger_data_matching.mojom-forward.h"
 #include "content/browser/attribution_reporting/attribution_report.h"
 #include "content/common/content_export.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -19,7 +20,6 @@
 class EventReportWindows;
 class FilterData;
 class MaxEventLevelReports;
-class TriggerConfig;
 }  // namespace attribution_reporting
 
 namespace sql {
@@ -51,7 +51,7 @@
     const attribution_reporting::EventReportWindows&,
     attribution_reporting::MaxEventLevelReports,
     double randomized_response_rate,
-    const attribution_reporting::TriggerConfig&,
+    attribution_reporting::mojom::TriggerDataMatching,
     bool debug_cookie_set);
 
 CONTENT_EXPORT absl::optional<proto::AttributionReadOnlySourceData>
diff --git a/content/browser/attribution_reporting/stored_source.cc b/content/browser/attribution_reporting/stored_source.cc
index a8dc6dd..1587f40b 100644
--- a/content/browser/attribution_reporting/stored_source.cc
+++ b/content/browser/attribution_reporting/stored_source.cc
@@ -17,6 +17,7 @@
 #include "components/attribution_reporting/filters.h"
 #include "components/attribution_reporting/max_event_level_reports.h"
 #include "components/attribution_reporting/trigger_config.h"
+#include "components/attribution_reporting/trigger_data_matching.mojom-forward.h"
 #include "content/browser/attribution_reporting/common_source_info.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -68,7 +69,7 @@
     Id source_id,
     int64_t aggregatable_budget_consumed,
     double randomized_response_rate,
-    attribution_reporting::TriggerConfig trigger_config,
+    attribution_reporting::mojom::TriggerDataMatching trigger_data_matching,
     bool debug_cookie_set) {
   if (!AreFieldsValid(aggregatable_budget_consumed, randomized_response_rate,
                       source_time, expiry_time, aggregatable_report_window_time,
@@ -82,7 +83,7 @@
       aggregatable_report_window_time, max_event_level_reports, priority,
       std::move(filter_data), debug_key, std::move(aggregation_keys),
       attribution_logic, active_state, source_id, aggregatable_budget_consumed,
-      randomized_response_rate, std::move(trigger_config), debug_cookie_set);
+      randomized_response_rate, trigger_data_matching, debug_cookie_set);
 }
 
 StoredSource::StoredSource(
@@ -103,7 +104,7 @@
     Id source_id,
     int64_t aggregatable_budget_consumed,
     double randomized_response_rate,
-    attribution_reporting::TriggerConfig trigger_config,
+    attribution_reporting::mojom::TriggerDataMatching trigger_data_matching,
     bool debug_cookie_set)
     : common_info_(std::move(common_info)),
       source_event_id_(source_event_id),
@@ -122,7 +123,7 @@
       source_id_(source_id),
       aggregatable_budget_consumed_(aggregatable_budget_consumed),
       randomized_response_rate_(randomized_response_rate),
-      trigger_config_(std::move(trigger_config)),
+      trigger_data_matching_(std::move(trigger_data_matching)),
       debug_cookie_set_(debug_cookie_set) {
   DCHECK(AreFieldsValid(aggregatable_budget_consumed_,
                         randomized_response_rate_, source_time_, expiry_time_,
diff --git a/content/browser/attribution_reporting/stored_source.h b/content/browser/attribution_reporting/stored_source.h
index 65c480036..87ad193 100644
--- a/content/browser/attribution_reporting/stored_source.h
+++ b/content/browser/attribution_reporting/stored_source.h
@@ -16,6 +16,7 @@
 #include "components/attribution_reporting/filters.h"
 #include "components/attribution_reporting/max_event_level_reports.h"
 #include "components/attribution_reporting/trigger_config.h"
+#include "components/attribution_reporting/trigger_data_matching.mojom-forward.h"
 #include "content/browser/attribution_reporting/common_source_info.h"
 #include "content/common/content_export.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
@@ -63,7 +64,7 @@
       Id source_id,
       int64_t aggregatable_budget_consumed,
       double randomized_response_rate,
-      attribution_reporting::TriggerConfig,
+      attribution_reporting::mojom::TriggerDataMatching,
       bool debug_cookie_set);
 
   ~StoredSource();
@@ -128,8 +129,9 @@
 
   double randomized_response_rate() const { return randomized_response_rate_; }
 
-  const attribution_reporting::TriggerConfig& trigger_config() const {
-    return trigger_config_;
+  attribution_reporting::mojom::TriggerDataMatching trigger_data_matching()
+      const {
+    return trigger_data_matching_;
   }
 
   bool debug_cookie_set() const { return debug_cookie_set_; }
@@ -160,7 +162,7 @@
                Id source_id,
                int64_t aggregatable_budget_consumed,
                double randomized_response_rate,
-               attribution_reporting::TriggerConfig,
+               attribution_reporting::mojom::TriggerDataMatching,
                bool debug_cookie_set);
 
   CommonSourceInfo common_info_;
@@ -193,8 +195,7 @@
 
   double randomized_response_rate_;
 
-  // TODO(apaseltiner): Merge this field with `trigger_specs_`.
-  attribution_reporting::TriggerConfig trigger_config_;
+  attribution_reporting::mojom::TriggerDataMatching trigger_data_matching_;
 
   bool debug_cookie_set_;
 
diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc
index b76215ee..13d5bbd 100644
--- a/content/browser/browser_interface_binders.cc
+++ b/content/browser/browser_interface_binders.cc
@@ -184,7 +184,6 @@
 #include "url/origin.h"
 
 #if BUILDFLAG(IS_ANDROID)
-#include "content/browser/android/javascript_injector.h"
 #include "content/browser/android/text_suggestion_host_android.h"
 #include "content/browser/renderer_host/render_widget_host_view_android.h"
 #include "content/common/gin_java_bridge.mojom.h"
@@ -1089,8 +1088,6 @@
     map->Add<device::mojom::NFC>(base::BindRepeating(
         &RenderFrameHostImpl::BindNFCReceiver, base::Unretained(host)));
   }
-  map->Add<mojom::GinJavaBridgeHost>(base::BindRepeating(
-      &JavascriptInjector::BindGinJavaBridgeHost, base::Unretained(host)));
 #else
   map->Add<blink::mojom::HidService>(base::BindRepeating(
       &RenderFrameHostImpl::GetHidService, base::Unretained(host)));
diff --git a/content/browser/cache_storage/cache_storage_manager.cc b/content/browser/cache_storage/cache_storage_manager.cc
index 3316b6b..4c3e18c1 100644
--- a/content/browser/cache_storage/cache_storage_manager.cc
+++ b/content/browser/cache_storage/cache_storage_manager.cc
@@ -165,9 +165,8 @@
   if (owner != storage::mojom::CacheStorageOwner::kCacheAPI) {
     identifier += "-" + base::NumberToString(static_cast<int>(owner));
   }
-  const std::string origin_hash = base::SHA1HashString(identifier);
-  const std::string origin_hash_hex = base::ToLowerASCII(
-      base::HexEncode(origin_hash.c_str(), origin_hash.length()));
+  const std::string origin_hash_hex = base::ToLowerASCII(base::HexEncode(
+      base::SHA1HashSpan(base::as_bytes(base::make_span(identifier)))));
   return first_party_default_root_path.AppendASCII(origin_hash_hex);
 }
 
diff --git a/content/browser/client_hints/client_hints.cc b/content/browser/client_hints/client_hints.cc
index d05a2e2c..adf593b 100644
--- a/content/browser/client_hints/client_hints.cc
+++ b/content/browser/client_hints/client_hints.cc
@@ -785,7 +785,7 @@
     }
     if (ShouldAddClientHint(data, WebClientHintsType::kUAFormFactor)) {
       AddUAHeader(headers, WebClientHintsType::kUAFormFactor,
-                  SerializeHeaderString(ua_metadata->form_factor));
+                  ua_metadata->SerializeFormFactor());
     }
   } else if (call_type == ClientUaHeaderCallType::kAfterCreated) {
     RemoveClientHintHeader(WebClientHintsType::kUA, headers);
diff --git a/content/browser/devtools/protocol/storage_handler.cc b/content/browser/devtools/protocol/storage_handler.cc
index 351539a..0b9c212f 100644
--- a/content/browser/devtools/protocol/storage_handler.cc
+++ b/content/browser/devtools/protocol/storage_handler.cc
@@ -1827,8 +1827,8 @@
                   registration.event_report_windows)))
           .SetAggregatableReportWindow(
               registration.aggregatable_report_window.InSeconds())
-          .SetTriggerDataMatching(ToTriggerDataMatching(
-              registration.trigger_config.trigger_data_matching()))
+          .SetTriggerDataMatching(
+              ToTriggerDataMatching(registration.trigger_data_matching))
           .Build();
 
   if (registration.debug_key.has_value()) {
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index bc0ad8cd..0b68ef17 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -1224,26 +1224,7 @@
       if (download->IsTransient())
         continue;
       if (download->GetState() == download::DownloadItem::IN_PROGRESS &&
-          download->GetDangerType() !=
-              download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL &&
-          download->GetDangerType() !=
-              download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT &&
-          download->GetDangerType() !=
-              download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST &&
-          download->GetDangerType() !=
-              download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED &&
-          download->GetDangerType() !=
-              download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_OPENED_DANGEROUS &&
-          it.second->GetDangerType() !=
-              download::DOWNLOAD_DANGER_TYPE_DANGEROUS_ACCOUNT_COMPROMISE &&
-          it.second->GetDangerType() !=
-              download::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT &&
-          it.second->GetDangerType() !=
-              download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING &&
-          it.second->GetDangerType() !=
-              download::
-                  DOWNLOAD_DANGER_TYPE_PROMPT_FOR_LOCAL_PASSWORD_SCANNING &&
-          !download->IsInsecure()) {
+          !download->IsDangerous() && !download->IsInsecure()) {
         ++count;
       }
     }
diff --git a/content/browser/download/download_manager_impl_unittest.cc b/content/browser/download/download_manager_impl_unittest.cc
index a883962..ca6c77b 100644
--- a/content/browser/download/download_manager_impl_unittest.cc
+++ b/content/browser/download/download_manager_impl_unittest.cc
@@ -905,6 +905,7 @@
   download::MockDownloadItemImpl& item(AddItemToManager());
 
   EXPECT_CALL(item, IsInsecure()).WillRepeatedly(Return(false));
+  EXPECT_CALL(item, IsDangerous()).WillRepeatedly(Return(false));
 
   EXPECT_CALL(item, GetState())
       .WillRepeatedly(Return(download::DownloadItem::COMPLETE));
@@ -914,22 +915,9 @@
       .WillRepeatedly(Return(download::DownloadItem::IN_PROGRESS));
   EXPECT_EQ(download_manager_->BlockingShutdownCount(), 1);
 
-  const download::DownloadDangerType kDangerTypes[] = {
-      download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
-      download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT,
-      download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST,
-      download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED,
-      download::DOWNLOAD_DANGER_TYPE_DEEP_SCANNED_OPENED_DANGEROUS,
-      download::DOWNLOAD_DANGER_TYPE_DANGEROUS_ACCOUNT_COMPROMISE,
-      download::DOWNLOAD_DANGER_TYPE_PROMPT_FOR_SCANNING};
-  for (download::DownloadDangerType danger_type : kDangerTypes) {
-    SCOPED_TRACE(testing::Message()
-                 << "Failed for danger type "
-                 << download::GetDownloadDangerTypeString(danger_type)
-                 << std::endl);
-    EXPECT_CALL(item, GetDangerType()).WillRepeatedly(Return(danger_type));
-    EXPECT_EQ(download_manager_->BlockingShutdownCount(), 0);
-  }
+  EXPECT_CALL(item, IsDangerous()).WillRepeatedly(Return(true));
+  EXPECT_EQ(download_manager_->BlockingShutdownCount(), 0);
+  EXPECT_CALL(item, IsDangerous()).WillRepeatedly(Return(false));
 
   SCOPED_TRACE(testing::Message() << "Failed for insecure" << std::endl);
   EXPECT_CALL(item, IsInsecure()).WillRepeatedly(Return(true));
diff --git a/content/browser/indexed_db/indexed_db_factory_unittest.cc b/content/browser/indexed_db/indexed_db_factory_unittest.cc
index 4c7d45a..d023e19a 100644
--- a/content/browser/indexed_db/indexed_db_factory_unittest.cc
+++ b/content/browser/indexed_db/indexed_db_factory_unittest.cc
@@ -880,6 +880,8 @@
   ASSERT_EQ(1U, quota_manager()->write_error_tracker().size());
   EXPECT_EQ(storage_key, quota_manager()->write_error_tracker().begin()->first);
   EXPECT_EQ(1, quota_manager()->write_error_tracker().begin()->second);
+
+  leveldb_env::SetDBFactoryForTesting({});
 }
 
 TEST_F(IndexedDBFactoryTest, NotifyQuotaOnDatabaseError) {
diff --git a/content/browser/interest_group/ad_auction_service_impl_unittest.cc b/content/browser/interest_group/ad_auction_service_impl_unittest.cc
index 89d1c60c..a498c148 100644
--- a/content/browser/interest_group/ad_auction_service_impl_unittest.cc
+++ b/content/browser/interest_group/ad_auction_service_impl_unittest.cc
@@ -46,6 +46,7 @@
 #include "content/browser/interest_group/ad_auction_page_data.h"
 #include "content/browser/interest_group/auction_process_manager.h"
 #include "content/browser/interest_group/interest_group_caching_storage.h"
+#include "content/browser/interest_group/interest_group_features.h"
 #include "content/browser/interest_group/interest_group_manager_impl.h"
 #include "content/browser/interest_group/interest_group_storage.h"
 #include "content/browser/interest_group/storage_interest_group.h"
@@ -727,7 +728,8 @@
          blink::features::kFledgeClearOriginJoinedAdInterestGroups,
          blink::features::kFledgeNegativeTargeting,
          blink::features::kPrivateAggregationApiMultipleCloudProviders,
-         aggregation_service::kAggregationServiceMultipleCloudProviders},
+         aggregation_service::kAggregationServiceMultipleCloudProviders,
+         features::kEnableUpdatingUserBiddingSignals},
         /*disabled_features=*/{});
     fenced_frame_feature_list_.InitAndEnableFeatureWithParameters(
         blink::features::kFencedFrames, {{"implementation_type", "mparch"}});
@@ -1415,6 +1417,7 @@
 "trustedBiddingSignalsURL":
   "%s/interest_group/new_trusted_bidding_signals_url.json",
 "trustedBiddingSignalsKeys": ["new_key"],
+"userBiddingSignals": {"test":10},
 "updateURL": "%s/interest_group/new_daily_update_partial.json",
 "ads": [{"renderURL": "%s/new_ad_render_url",
          "sizeGroup": "group_new",
@@ -1460,6 +1463,8 @@
   interest_group.trusted_bidding_signals_url = kTrustedBiddingSignalsUrlA;
   interest_group.trusted_bidding_signals_keys.emplace();
   interest_group.trusted_bidding_signals_keys->push_back("key1");
+  interest_group.user_bidding_signals.emplace();
+  interest_group.user_bidding_signals = "{\"test\":4}";
   interest_group.ads.emplace();
   std::vector<url::Origin> allowed_reporting_origins = {kOriginF};
   blink::InterestGroup::Ad ad(
@@ -1539,6 +1544,9 @@
   ASSERT_TRUE(group.trusted_bidding_signals_keys.has_value());
   EXPECT_EQ(group.trusted_bidding_signals_keys->size(), 1u);
   EXPECT_EQ(group.trusted_bidding_signals_keys.value()[0], "new_key");
+  ASSERT_TRUE(group.user_bidding_signals.has_value());
+  EXPECT_EQ(group.user_bidding_signals.value(), "{\"test\":10}");
+
   ASSERT_TRUE(group.update_url.has_value());
   EXPECT_EQ(
       group.update_url->spec(),
@@ -9587,6 +9595,64 @@
   EXPECT_EQ(auction_result, absl::nullopt);
 }
 
+class AdAuctionServiceImplUpdateUserBiddingSignalsDisabledTest
+    : public AdAuctionServiceImplTest {
+ public:
+  AdAuctionServiceImplUpdateUserBiddingSignalsDisabledTest() {
+    feature_list_.InitAndDisableFeature(
+        features::kEnableUpdatingUserBiddingSignals);
+  }
+
+ protected:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+TEST_F(AdAuctionServiceImplUpdateUserBiddingSignalsDisabledTest,
+       DisabledUserBiddingSignalsTest) {
+  network_responder_->RegisterUpdateResponse(kUpdateUrlPath, R"({
+"userBiddingSignals": {"new":10},
+"ads": [{
+  "renderURL": "https://example.com/new_render",
+  "unsupportedField": "InAd"
+        }],
+"adComponents": [{
+  "renderURL": "https://example.com/new_component",
+  "unsupportedField": "InAdComponent"
+        }]
+})");
+
+  blink::InterestGroup interest_group = CreateInterestGroup();
+  interest_group.update_url = kUpdateUrlA;
+  interest_group.user_bidding_signals.emplace();
+  interest_group.user_bidding_signals = "{\"old\":4}";
+  interest_group.bidding_url = kBiddingLogicUrlA;
+  interest_group.trusted_bidding_signals_url = kTrustedBiddingSignalsUrlA;
+  interest_group.trusted_bidding_signals_keys.emplace();
+  interest_group.trusted_bidding_signals_keys->push_back("key1");
+  interest_group.ads.emplace();
+  blink::InterestGroup::Ad ad(
+      /*render_url=*/GURL("https://example.com/render"),
+      /*metadata=*/absl::nullopt);
+  interest_group.ads->emplace_back(std::move(ad));
+  JoinInterestGroupAndFlush(interest_group);
+  EXPECT_EQ(1, GetJoinCount(kOriginA, kInterestGroupName));
+
+  UpdateInterestGroupNoFlush();
+  task_environment()->RunUntilIdle();
+
+  auto groups = GetInterestGroupsForOwner(kOriginA);
+  ASSERT_EQ(groups->size(), 1u);
+  const auto& group = groups->GetInterestGroups()[0]->interest_group;
+  ASSERT_TRUE(group.ads.has_value());
+  ASSERT_EQ(group.ads->size(), 1u);
+  EXPECT_EQ(group.ads.value()[0].render_url.spec(),
+            "https://example.com/new_render");
+  ASSERT_EQ(group.ad_components->size(), 1u);
+  EXPECT_EQ(group.ad_components.value()[0].render_url.spec(),
+            "https://example.com/new_component");
+  EXPECT_EQ(group.user_bidding_signals.value(), "{\"old\":4}");
+}
+
 class AdAuctionServiceImplKAnonTest
     : public AdAuctionServiceImplTest,
       public ::testing::WithParamInterface<
diff --git a/content/browser/interest_group/interest_group_features.cc b/content/browser/interest_group/interest_group_features.cc
new file mode 100644
index 0000000..9aea0c4
--- /dev/null
+++ b/content/browser/interest_group/interest_group_features.cc
@@ -0,0 +1,18 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/interest_group/interest_group_features.h"
+
+#include "base/feature_list.h"
+
+namespace features {
+
+// Please keep features in alphabetical order.
+
+// Enable updating userBiddingSignals when updating a user's interests groups.
+BASE_FEATURE(kEnableUpdatingUserBiddingSignals,
+             "EnableUpdatingUserBiddingSignals",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+}  // namespace features
diff --git a/content/browser/interest_group/interest_group_features.h b/content/browser/interest_group/interest_group_features.h
new file mode 100644
index 0000000..6a5863d6
--- /dev/null
+++ b/content/browser/interest_group/interest_group_features.h
@@ -0,0 +1,18 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_INTEREST_GROUP_INTEREST_GROUP_FEATURES_H_
+#define CONTENT_BROWSER_INTEREST_GROUP_INTEREST_GROUP_FEATURES_H_
+
+#include "base/feature_list.h"
+#include "content/common/content_export.h"
+
+namespace features {
+// Please keep features in alphabetical order.
+
+CONTENT_EXPORT BASE_DECLARE_FEATURE(kEnableUpdatingUserBiddingSignals);
+
+}  // namespace features
+
+#endif  // CONTENT_BROWSER_INTEREST_GROUP_INTEREST_GROUP_FEATURES_H_
diff --git a/content/browser/interest_group/interest_group_storage.cc b/content/browser/interest_group/interest_group_storage.cc
index 22a183f..9de778b 100644
--- a/content/browser/interest_group/interest_group_storage.cc
+++ b/content/browser/interest_group/interest_group_storage.cc
@@ -2279,6 +2279,7 @@
             "update_url=?,"
             "trusted_bidding_signals_url=?,"
             "trusted_bidding_signals_keys=?,"
+            "user_bidding_signals=?,"
             "ads_pb=?,"
             "ad_components_pb=?,"
             "ad_sizes=?,"
@@ -2310,22 +2311,27 @@
   store_group.BindString(11, Serialize(group.update_url));
   store_group.BindString(12, Serialize(group.trusted_bidding_signals_url));
   store_group.BindString(13, Serialize(group.trusted_bidding_signals_keys));
-  store_group.BindBlob(14, Serialize(group.ads));
-  store_group.BindBlob(15, Serialize(group.ad_components));
-  store_group.BindString(16, Serialize(group.ad_sizes));
-  store_group.BindString(17, Serialize(group.size_groups));
-  store_group.BindInt64(18, Serialize(group.auction_server_request_flags));
-  store_group.BindBlob(19, Serialize(group.additional_bid_key));
+  if (group.user_bidding_signals) {
+    store_group.BindString(14, group.user_bidding_signals.value());
+  } else {
+    store_group.BindNull(14);
+  }
+  store_group.BindBlob(15, Serialize(group.ads));
+  store_group.BindBlob(16, Serialize(group.ad_components));
+  store_group.BindString(17, Serialize(group.ad_sizes));
+  store_group.BindString(18, Serialize(group.size_groups));
+  store_group.BindInt64(19, Serialize(group.auction_server_request_flags));
+  store_group.BindBlob(20, Serialize(group.additional_bid_key));
   if (group.aggregation_coordinator_origin) {
-    store_group.BindString(20,
+    store_group.BindString(21,
                            Serialize(*group.aggregation_coordinator_origin));
   } else {
-    store_group.BindNull(20);
+    store_group.BindNull(21);
   }
-  store_group.BindInt64(21, group.EstimateSize());
+  store_group.BindInt64(22, group.EstimateSize());
 
-  store_group.BindString(22, Serialize(group.owner));
-  store_group.BindString(23, group.name);
+  store_group.BindString(23, Serialize(group.owner));
+  store_group.BindString(24, group.name);
 
   return store_group.Run();
 }
@@ -2401,6 +2407,9 @@
     stored_group.trusted_bidding_signals_keys =
         std::move(update.trusted_bidding_signals_keys);
   }
+  if (update.user_bidding_signals) {
+    stored_group.user_bidding_signals = std::move(update.user_bidding_signals);
+  }
   if (update.ads) {
     stored_group.ads = std::move(update.ads);
   }
diff --git a/content/browser/interest_group/interest_group_update.h b/content/browser/interest_group/interest_group_update.h
index d89f74d..b62c5bc 100644
--- a/content/browser/interest_group/interest_group_update.h
+++ b/content/browser/interest_group/interest_group_update.h
@@ -21,9 +21,9 @@
 
 // InterestGroupUpdate represents the results of parsing a JSON update for a
 // stored blink::InterestGroup file. It contains all updatable fields of a
-// InterestGroup - that is, everything but `name`, `origin`, `expiry`, and
-// `user_bidding_signals`. All fields are optional, even ones that are mandatory
-// in an InterestGroup, since the value of the original InterestGroup will be
+// InterestGroup - that is, everything but `name`, `origin`, and `expiry`.
+// All fields are optional, even ones that are mandatory in an InterestGroup,
+// since the value of the original InterestGroup will be
 // used when they're not present in an InterestGroupUpdate.
 struct CONTENT_EXPORT InterestGroupUpdate {
   InterestGroupUpdate();
@@ -47,6 +47,7 @@
   absl::optional<GURL> daily_update_url;
   absl::optional<GURL> trusted_bidding_signals_url;
   absl::optional<std::vector<std::string>> trusted_bidding_signals_keys;
+  absl::optional<std::string> user_bidding_signals;
   absl::optional<std::vector<blink::InterestGroup::Ad>> ads, ad_components;
   absl::optional<base::flat_map<std::string, blink::AdSize>> ad_sizes;
   absl::optional<base::flat_map<std::string, std::vector<std::string>>>
diff --git a/content/browser/interest_group/interest_group_update_manager.cc b/content/browser/interest_group/interest_group_update_manager.cc
index d1180f0..faad5b52 100644
--- a/content/browser/interest_group/interest_group_update_manager.cc
+++ b/content/browser/interest_group/interest_group_update_manager.cc
@@ -28,6 +28,7 @@
 #include "base/values.h"
 #include "components/aggregation_service/aggregation_coordinator_utils.h"
 #include "components/aggregation_service/features.h"
+#include "content/browser/interest_group/interest_group_features.h"
 #include "content/browser/interest_group/interest_group_manager_impl.h"
 #include "content/browser/interest_group/interest_group_storage.h"
 #include "content/browser/interest_group/interest_group_update.h"
@@ -284,6 +285,25 @@
   return true;
 }
 
+// Copies the userBiddingSignals JSON "any" field into
+// `interest_group_update` as a string, returns true iff re-serialization
+// succeeded and the copy completed.
+[[nodiscard]] bool TryToCopyUserBiddingSignals(
+    const base::Value::Dict& dict,
+    InterestGroupUpdate& interest_group_update) {
+  const base::Value* maybe_user_bidding_signals =
+      dict.Find("userBiddingSignals");
+  if (!maybe_user_bidding_signals) {
+    return true;
+  }
+  std::string user_bidding_signals;
+  JSONStringValueSerializer serializer(&user_bidding_signals);
+  if (!serializer.Serialize(*maybe_user_bidding_signals)) {
+    return false;
+  }
+  interest_group_update.user_bidding_signals = std::move(user_bidding_signals);
+  return true;
+}
 // Helper for TryToCopyAds() and TryToCopyAdComponents().
 [[nodiscard]] absl::optional<std::vector<blink::InterestGroup::Ad>> ExtractAds(
     const base::Value::List& ads_list,
@@ -615,6 +635,12 @@
   if (!TryToCopyTrustedBiddingSignalsKeys(*dict, interest_group_update)) {
     return absl::nullopt;
   }
+  if (base::FeatureList::IsEnabled(
+          features::kEnableUpdatingUserBiddingSignals)) {
+    if (!TryToCopyUserBiddingSignals(*dict, interest_group_update)) {
+      return absl::nullopt;
+    }
+  }
   if (!TryToCopyAds(*dict, interest_group_update)) {
     return absl::nullopt;
   }
diff --git a/content/browser/media/capture/web_contents_frame_tracker.cc b/content/browser/media/capture/web_contents_frame_tracker.cc
index fcb74e7..49448c7 100644
--- a/content/browser/media/capture/web_contents_frame_tracker.cc
+++ b/content/browser/media/capture/web_contents_frame_tracker.cc
@@ -112,14 +112,6 @@
   raw_ptr<WebContents, DanglingUntriaged> contents_;
 };
 
-viz::VideoCaptureSubTarget DeriveSubTarget(base::Token crop_id) {
-  if (base::FeatureList::IsEnabled(media::kUseElementInsteadOfRegionCapture)) {
-    return viz::SubtreeCaptureId(crop_id);
-  } else {
-    return crop_id;
-  }
-}
-
 }  // namespace
 
 // A max factor above 2.0 would cause a quality degradation for local
@@ -450,24 +442,21 @@
     return;
   }
 
-  if (type != media::mojom::SubCaptureTargetType::kCropTarget) {
-    // TODO(crbug.com/1418194): Implement.
-    std::move(callback).Run(
-        media::mojom::ApplySubCaptureTargetResult::kNotImplemented);
-    return;
-  }
+  sub_capture_target_ =
+      target_token.is_zero()
+          ? absl::nullopt
+          : absl::make_optional<SubCaptureTargetInfo>(type, target_token);
 
-  crop_id_ = target_token;
   sub_capture_target_version_ = sub_capture_target_version;
 
-  // If we don't have a target yet, we can store the crop ID but cannot actually
-  // crop yet.
+  // If we don't have a target yet, we can store the sub-capture target,
+  // but cannot actually apply it yet.
   if (!target_frame_sink_id_.is_valid()) {
     return;
   }
 
   const viz::VideoCaptureTarget target(target_frame_sink_id_,
-                                       DeriveSubTarget(crop_id_));
+                                       DeriveSubTarget());
   device_task_runner_->PostTask(
       FROM_HERE,
       base::BindOnce(
@@ -513,14 +502,14 @@
       context_ ? context_->GetCaptureTarget()
                : WebContentsImpl::CaptureTarget{};
 
-  // TODO(crbug.com/1264849): Clear |crop_id_| when share-this-tab-instead
-  // is clicked.
+  // TODO(crbug.com/1264849): Clear |sub_capture_target_| when
+  // share-this-tab-instead is clicked.
   if (capture_target.sink_id != target_frame_sink_id_) {
     target_frame_sink_id_ = capture_target.sink_id;
     absl::optional<viz::VideoCaptureTarget> target;
     if (capture_target.sink_id.is_valid()) {
-      target = viz::VideoCaptureTarget(capture_target.sink_id,
-                                       DeriveSubTarget(crop_id_));
+      target =
+          viz::VideoCaptureTarget(capture_target.sink_id, DeriveSubTarget());
     }
 
     // The target may change to an invalid one, but we don't consider it
@@ -625,4 +614,20 @@
   return max_capture_scale_override_;
 }
 
+viz::VideoCaptureSubTarget WebContentsFrameTracker::DeriveSubTarget() const {
+  if (!sub_capture_target_.has_value()) {
+    return base::Token();
+  }
+
+  const SubCaptureTargetInfo& sub_capture_target = sub_capture_target_.value();
+  switch (sub_capture_target.type) {
+    case media::mojom::SubCaptureTargetType::kCropTarget:
+      return sub_capture_target.token;
+    case media::mojom::SubCaptureTargetType::kRestrictionTarget:
+      return viz::SubtreeCaptureId(sub_capture_target.token);
+  }
+
+  NOTREACHED_NORETURN();
+}
+
 }  // namespace content
diff --git a/content/browser/media/capture/web_contents_frame_tracker.h b/content/browser/media/capture/web_contents_frame_tracker.h
index bdea5f5..be27844 100644
--- a/content/browser/media/capture/web_contents_frame_tracker.h
+++ b/content/browser/media/capture/web_contents_frame_tracker.h
@@ -172,6 +172,10 @@
   // the capture scale override, if necessary.
   float DetermineMaxScaleOverride();
 
+  // Return the right VideoCaptureSubTarget based on whether which sub-capture
+  // has been applied, if any.
+  viz::VideoCaptureSubTarget DeriveSubTarget() const;
+
   // The maximum capture scale override.
   static const float kMaxCaptureScaleOverride;
 
@@ -192,9 +196,17 @@
   // We may not have a frame sink ID target at all times.
   std::unique_ptr<Context> context_;
   viz::FrameSinkId target_frame_sink_id_;
-  base::Token crop_id_;
   gfx::NativeView target_native_view_ = gfx::NativeView();
 
+  struct SubCaptureTargetInfo {
+    SubCaptureTargetInfo(media::mojom::SubCaptureTargetType type,
+                         base::Token token)
+        : type(type), token(token) {}
+    media::mojom::SubCaptureTargetType type;
+    base::Token token;
+  };
+  absl::optional<SubCaptureTargetInfo> sub_capture_target_;
+
   // Indicates whether the WebContents's capturer count needs to be
   // decremented.
   bool is_capturing_ = false;
diff --git a/content/browser/renderer_host/clipboard_host_impl.cc b/content/browser/renderer_host/clipboard_host_impl.cc
index dc397a00..0154da3 100644
--- a/content/browser/renderer_host/clipboard_host_impl.cc
+++ b/content/browser/renderer_host/clipboard_host_impl.cc
@@ -679,8 +679,8 @@
     auto source =
         ui::Clipboard::GetForCurrentThread()->GetSource(clipboard_buffer);
     ui::DataTransferPolicyController::Get()->PasteIfAllowed(
-        base::OptionalToPtr(source), CreateDataEndpoint().get(), data_size,
-        &render_frame_host(), std::move(policy_cb));
+        source, CreateDataEndpoint().get(), data_size, &render_frame_host(),
+        std::move(policy_cb));
     return;
   }
   std::move(policy_cb).Run(/*is_allowed=*/true);
diff --git a/content/browser/renderer_host/clipboard_host_impl_unittest.cc b/content/browser/renderer_host/clipboard_host_impl_unittest.cc
index b79ff491..b0cf307 100644
--- a/content/browser/renderer_host/clipboard_host_impl_unittest.cc
+++ b/content/browser/renderer_host/clipboard_host_impl_unittest.cc
@@ -92,15 +92,15 @@
                     const absl::optional<size_t> size));
 
   MOCK_METHOD5(PasteIfAllowed,
-               void(const ui::DataTransferEndpoint* const data_src,
-                    const ui::DataTransferEndpoint* const data_dst,
+               void(base::optional_ref<const ui::DataTransferEndpoint> data_src,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     const absl::optional<size_t> size,
                     content::RenderFrameHost* rfh,
                     base::OnceCallback<void(bool)> callback));
 
   MOCK_METHOD3(DropIfAllowed,
                void(const ui::OSExchangeData* drag_data,
-                    const ui::DataTransferEndpoint* data_dst,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::OnceClosure drop_cb));
 };
 
@@ -489,8 +489,8 @@
   PolicyControllerTest policy_controller;
   EXPECT_CALL(policy_controller, PasteIfAllowed)
       .WillOnce(testing::Invoke(
-          [](const ui::DataTransferEndpoint* const data_src,
-             const ui::DataTransferEndpoint* const data_dst,
+          [](base::optional_ref<const ui::DataTransferEndpoint> data_src,
+             base::optional_ref<const ui::DataTransferEndpoint> data_dst,
              const absl::optional<size_t> size, content::RenderFrameHost* rfh,
              base::OnceCallback<void(bool)> callback) {
             std::move(callback).Run(false);
@@ -522,8 +522,8 @@
   PolicyControllerTest policy_controller;
   EXPECT_CALL(policy_controller, PasteIfAllowed)
       .WillOnce(testing::Invoke(
-          [](const ui::DataTransferEndpoint* const data_src,
-             const ui::DataTransferEndpoint* const data_dst,
+          [](base::optional_ref<const ui::DataTransferEndpoint> data_src,
+             base::optional_ref<const ui::DataTransferEndpoint> data_dst,
              const absl::optional<size_t> size, content::RenderFrameHost* rfh,
              base::OnceCallback<void(bool)> callback) {
             std::move(callback).Run(true);
@@ -579,12 +579,12 @@
   PolicyControllerTest policy_controller;
   EXPECT_CALL(policy_controller, PasteIfAllowed)
       .WillOnce(testing::Invoke(
-          [&gurl1](const ui::DataTransferEndpoint* const data_src,
-                   const ui::DataTransferEndpoint* const data_dst,
+          [&gurl1](base::optional_ref<const ui::DataTransferEndpoint> data_src,
+                   base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                    const absl::optional<size_t> size,
                    content::RenderFrameHost* rfh,
                    base::OnceCallback<void(bool)> callback) {
-            ASSERT_TRUE(data_dst);
+            ASSERT_TRUE(data_dst.has_value());
             EXPECT_EQ(*data_dst->GetURL(), gurl1);
             std::move(callback).Run(true);
           }));
diff --git a/content/browser/resources/attribution_reporting/attribution_internals.ts b/content/browser/resources/attribution_reporting/attribution_internals.ts
index 76c0638c..1f60f4a 100644
--- a/content/browser/resources/attribution_reporting/attribution_internals.ts
+++ b/content/browser/resources/attribution_reporting/attribution_internals.ts
@@ -273,7 +273,7 @@
     this.aggregatableBudgetConsumed = mojo.aggregatableBudgetConsumed;
     this.aggregatableDedupKeys = mojo.aggregatableDedupKeys;
     this.triggerDataMatching =
-        triggerDataMatchingText[mojo.triggerConfig.triggerDataMatching];
+        triggerDataMatchingText[mojo.triggerDataMatching];
     this.status = attributabilityText[mojo.attributability];
     this.debugCookieSet = mojo.debugCookieSet;
   }
diff --git a/content/browser/web_contents/web_contents_view_child_frame.cc b/content/browser/web_contents/web_contents_view_child_frame.cc
index f63fa26..b876b1b6 100644
--- a/content/browser/web_contents/web_contents_view_child_frame.cc
+++ b/content/browser/web_contents/web_contents_view_child_frame.cc
@@ -48,11 +48,19 @@
 WebContentsViewChildFrame::~WebContentsViewChildFrame() = default;
 
 WebContentsView* WebContentsViewChildFrame::GetOuterView() {
-  return web_contents_->GetOuterWebContents()->GetView();
+  if (auto* outer_web_contents = web_contents_->GetOuterWebContents()) {
+    return outer_web_contents->GetView();
+  }
+
+  return nullptr;
 }
 
 const WebContentsView* WebContentsViewChildFrame::GetOuterView() const {
-  return web_contents_->GetOuterWebContents()->GetView();
+  if (auto* outer_web_contents = web_contents_->GetOuterWebContents()) {
+    return outer_web_contents->GetView();
+  }
+
+  return nullptr;
 }
 
 RenderViewHostDelegateView* WebContentsViewChildFrame::GetOuterDelegateView() {
@@ -63,15 +71,27 @@
 }
 
 gfx::NativeView WebContentsViewChildFrame::GetNativeView() const {
-  return GetOuterView()->GetNativeView();
+  if (auto* outer_view = GetOuterView()) {
+    return outer_view->GetNativeView();
+  }
+
+  return nullptr;
 }
 
 gfx::NativeView WebContentsViewChildFrame::GetContentNativeView() const {
-  return GetOuterView()->GetContentNativeView();
+  if (auto* outer_view = GetOuterView()) {
+    return outer_view->GetContentNativeView();
+  }
+
+  return nullptr;
 }
 
 gfx::NativeWindow WebContentsViewChildFrame::GetTopLevelNativeWindow() const {
-  return GetOuterView()->GetTopLevelNativeWindow();
+  if (auto* outer_view = GetOuterView()) {
+    return outer_view->GetTopLevelNativeWindow();
+  }
+
+  return nullptr;
 }
 
 gfx::Rect WebContentsViewChildFrame::GetContainerBounds() const {
diff --git a/content/browser/webid/federated_auth_revoke_request.cc b/content/browser/webid/federated_auth_revoke_request.cc
index 9328d58..4ff97e3 100644
--- a/content/browser/webid/federated_auth_revoke_request.cc
+++ b/content/browser/webid/federated_auth_revoke_request.cc
@@ -93,7 +93,6 @@
       error_revoke_status = RevokeStatusForMetrics::kDisabledInFlags;
       break;
     case FederatedApiPermissionStatus::BLOCKED_SETTINGS:
-      // TODO(crbug.com/1495108): determine if blocking is the right behavior.
       error_revoke_status = RevokeStatusForMetrics::kDisabledInSettings;
       break;
     // We do not block revocation on FedCM cooldown.
@@ -227,19 +226,23 @@
     IdpNetworkRequestManager::FetchStatus fetch_status,
     const std::string& account_id) {
   CHECK(callback_);
-  if (fetch_status.parse_status !=
-      IdpNetworkRequestManager::ParseStatus::kSuccess) {
-    Complete(RevokeStatus::kError,
-             RevokeStatusForMetrics::kRevocationFailedOnServer,
-             /*should_delay_callback=*/false);
-    return;
-  }
   // Matches the GrantSharingPermission() call in
   // FederatedAuthRequestImpl::CompleteTokenRequest(). Note that the IDP origin
   // cannot be an arbitrary origin, but rather needs to be a potentially
   // trustworthy one.
   url::Origin idp_origin = url::Origin::Create(options_->config->config_url);
-  // TODO(crbug.com/1473134): revoke relevant permissions.
+  if (fetch_status.parse_status !=
+      IdpNetworkRequestManager::ParseStatus::kSuccess) {
+    // Even though the response was unsuccessful, the credentialed fetch was
+    // sent to the IDP, so revoke all permissions associated with the triple
+    // (`origin_`, `embedding_origin`, `idp_origin`).
+    permission_delegate_->RevokeSharingPermission(
+        origin_, embedding_origin_, idp_origin, /*account_id=*/"");
+    Complete(RevokeStatus::kError,
+             RevokeStatusForMetrics::kRevocationFailedOnServer,
+             /*should_delay_callback=*/false);
+    return;
+  }
   permission_delegate_->RevokeSharingPermission(origin_, embedding_origin_,
                                                 idp_origin, account_id);
   Complete(RevokeStatus::kSuccess, RevokeStatusForMetrics::kSuccess,
diff --git a/content/common/gin_java_bridge.mojom b/content/common/gin_java_bridge.mojom
index ff803b2b..50a1f03d 100644
--- a/content/common/gin_java_bridge.mojom
+++ b/content/common/gin_java_bridge.mojom
@@ -29,6 +29,9 @@
 
   // Sent from browser to renderer to remove a Java object with the given name.
   RemoveNamedObject(string name);
+
+  // Sets the associated GinJavaBridgeHost object.
+  SetHost(pending_remote<GinJavaBridgeHost> host);
 };
 
 // Implemented in the process hosting the remote object. Allows methods to be
diff --git a/content/renderer/java/gin_java_bridge_dispatcher.cc b/content/renderer/java/gin_java_bridge_dispatcher.cc
index 4e6d73b..d53a8ee 100644
--- a/content/renderer/java/gin_java_bridge_dispatcher.cc
+++ b/content/renderer/java/gin_java_bridge_dispatcher.cc
@@ -83,6 +83,12 @@
   named_objects_.erase(name);
 }
 
+void GinJavaBridgeDispatcher::SetHost(
+    mojo::PendingRemote<mojom::GinJavaBridgeHost> host) {
+  CHECK(!remote_);
+  remote_.Bind(std::move(host));
+}
+
 void GinJavaBridgeDispatcher::GetJavaMethods(
     ObjectID object_id,
     std::vector<std::string>* methods) {
@@ -149,12 +155,9 @@
 }
 
 mojom::GinJavaBridgeHost* GinJavaBridgeDispatcher::GetRemoteObjectHost() {
-  if (!remote_) {
-    render_frame()->GetBrowserInterfaceBroker()->GetInterface(
-        remote_.BindNewPipeAndPassReceiver());
-    remote_.reset_on_disconnect();
-  }
-
+  // Remote should always be sent because it is the first method sent to
+  // this object.
+  CHECK(remote_);
   return remote_.get();
 }
 
diff --git a/content/renderer/java/gin_java_bridge_dispatcher.h b/content/renderer/java/gin_java_bridge_dispatcher.h
index 4081ca2..7d45f38 100644
--- a/content/renderer/java/gin_java_bridge_dispatcher.h
+++ b/content/renderer/java/gin_java_bridge_dispatcher.h
@@ -66,6 +66,7 @@
 
   void AddNamedObject(const std::string& name, ObjectID object_id) override;
   void RemoveNamedObject(const std::string& name) override;
+  void SetHost(mojo::PendingRemote<mojom::GinJavaBridgeHost> host) override;
 
   mojom::GinJavaBridgeHost* GetRemoteObjectHost();
 
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index d667fad..84da983 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -323,7 +323,7 @@
 
   metadata.bitness = GetCpuBitness();
   metadata.wow64 = content::IsWoW64();
-  metadata.form_factor = "";  // Empty value signifies desktop.
+  metadata.form_factor = {"Desktop"};
 
   return metadata;
 }
diff --git a/content/shell/browser/shell_federated_permission_context.cc b/content/shell/browser/shell_federated_permission_context.cc
index 16bae61..6a212f96 100644
--- a/content/shell/browser/shell_federated_permission_context.cc
+++ b/content/shell/browser/shell_federated_permission_context.cc
@@ -158,11 +158,23 @@
       relying_party_requester.Serialize(), relying_party_embedder.Serialize(),
       identity_provider.Serialize(), account_id));
   // If we did not remove any sharing permission, to preserve strong privacy
-  // guarantees of the FedCM API, remove an arbitrary sharing permission. This
-  // disabled auto re-authentication on that account and means revocation may
-  // not be invoked repeatedly after a single successful FedCM flow.
+  // guarantees of the FedCM API, remove all sharing permissions associated with
+  // the (`relying_party_requester`, `relying_party_embedder`,
+  // `identity_provider` triple). This disabled auto re-authentication on that
+  // account and means revocation may not be invoked repeatedly after a single
+  // successful FedCM flow.
   if (!removed && !sharing_permissions_.empty()) {
-    sharing_permissions_.erase(sharing_permissions_.begin());
+    auto it = sharing_permissions_.begin();
+    while (it != sharing_permissions_.end()) {
+      const auto& [requester, embedder, idp, account] = *it;
+      if (requester == relying_party_requester.Serialize() &&
+          embedder == relying_party_embedder.Serialize() &&
+          idp == identity_provider.Serialize()) {
+        it = sharing_permissions_.erase(it);
+      } else {
+        ++it;
+      }
+    }
   }
 }
 
diff --git a/device/vr/android/arcore/address_to_id_map.h b/device/vr/android/arcore/address_to_id_map.h
index 9970c945..d81ce365 100644
--- a/device/vr/android/arcore/address_to_id_map.h
+++ b/device/vr/android/arcore/address_to_id_map.h
@@ -9,7 +9,6 @@
 #include <unordered_map>
 
 #include "base/check.h"
-#include "base/containers/cxx20_erase_unordered_map.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace device {
@@ -68,7 +67,7 @@
   // generated if the address is passed into CreateOrGetId.
   template <class Predicate>
   size_t EraseIf(Predicate pred) {
-    return base::EraseIf(address_to_id_, pred);
+    return std::erase_if(address_to_id_, pred);
   }
 
  private:
diff --git a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_attach_helper.h b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_attach_helper.h
index 5e9204a8..bbbbd3dc 100644
--- a/extensions/browser/guest_view/mime_handler_view/mime_handler_view_attach_helper.h
+++ b/extensions/browser/guest_view/mime_handler_view/mime_handler_view_attach_helper.h
@@ -7,11 +7,9 @@
 
 #include <stdint.h>
 
-#include <map>
 #include <string>
 
-#include "base/containers/flat_map.h"
-#include "base/functional/callback_helpers.h"
+#include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "content/public/browser/render_process_host_observer.h"
@@ -63,7 +61,7 @@
       const std::string& mime_type,
       const std::string& stream_id,
       const std::string& internal_id,
-      base::OnceClosure resume_load = base::DoNothing());
+      base::OnceClosure resume_load);
 
   MimeHandlerViewAttachHelper(const MimeHandlerViewAttachHelper&) = delete;
   MimeHandlerViewAttachHelper& operator=(const MimeHandlerViewAttachHelper&) =
diff --git a/headless/test/headless_browser_user_agent_metadata_browsertest.cc b/headless/test/headless_browser_user_agent_metadata_browsertest.cc
index f243cc1..c41f11c6 100644
--- a/headless/test/headless_browser_user_agent_metadata_browsertest.cc
+++ b/headless/test/headless_browser_user_agent_metadata_browsertest.cc
@@ -6,6 +6,7 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/strings/strcat.h"
+#include "base/strings/string_util.h"
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/values.h"
@@ -156,7 +157,7 @@
               .then(r => r.wow64))";
   static constexpr char kFormFactorScript[] = R"(
           navigator.userAgentData.getHighEntropyValues(['formFactor'])
-              .then(r => r.formFactor))";
+              .then(r => r.formFactor.join(', ')))";
 
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
@@ -188,7 +189,8 @@
   EXPECT_THAT(GetUAMetadataValue(kWow64Script),
               DictHasValue("result.result.value", expected.wow64));
   EXPECT_THAT(GetUAMetadataValue(kFormFactorScript),
-              DictHasValue("result.result.value", expected.form_factor));
+              DictHasValue("result.result.value",
+                           base::JoinString(expected.form_factor, ", ")));
 }
 
 // UA Metadata is available via `navigator.userAgentData` when overridden via
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-asan-rel/gn-args.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-asan-rel/gn-args.json
new file mode 100644
index 0000000..42bb990
--- /dev/null
+++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-asan-rel/gn-args.json
@@ -0,0 +1,10 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic.gni",
+  "gn_args": {
+    "dcheck_always_on": false,
+    "is_asan": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-asan-rel/properties.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-asan-rel/properties.json
index dcef0ca..05e0f7c 100644
--- a/infra/config/generated/builders/ci/chromeos-amd64-generic-asan-rel/properties.json
+++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-asan-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/chromeos-amd64-generic-asan-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-cfi-thin-lto-rel/gn-args.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-cfi-thin-lto-rel/gn-args.json
new file mode 100644
index 0000000..70a452fb
--- /dev/null
+++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-cfi-thin-lto-rel/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic.gni",
+  "gn_args": {
+    "also_build_lacros_chrome_for_architecture": "amd64",
+    "dcheck_always_on": false,
+    "is_cfi": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_cfi_cast": true,
+    "use_remoteexec": true,
+    "use_thin_lto": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-cfi-thin-lto-rel/properties.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-cfi-thin-lto-rel/properties.json
index d5bbecd..dddbb72 100644
--- a/infra/config/generated/builders/ci/chromeos-amd64-generic-cfi-thin-lto-rel/properties.json
+++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-cfi-thin-lto-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/chromeos-amd64-generic-cfi-thin-lto-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-dbg/gn-args.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-dbg/gn-args.json
new file mode 100644
index 0000000..e484fa7
--- /dev/null
+++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-dbg/gn-args.json
@@ -0,0 +1,10 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic.gni",
+  "gn_args": {
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_debug": true,
+    "ozone_platform_headless": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-dbg/properties.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-dbg/properties.json
index 963a0a3..6e0435a 100644
--- a/infra/config/generated/builders/ci/chromeos-amd64-generic-dbg/properties.json
+++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-dbg/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/chromeos-amd64-generic-dbg/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-lacros-dbg/gn-args.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-lacros-dbg/gn-args.json
new file mode 100644
index 0000000..5f38a1f5
--- /dev/null
+++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-lacros-dbg/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_component_build": false,
+    "is_debug": true,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-lacros-dbg/properties.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-lacros-dbg/properties.json
index 534d1355..3698f2fa 100644
--- a/infra/config/generated/builders/ci/chromeos-amd64-generic-lacros-dbg/properties.json
+++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-lacros-dbg/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/chromeos-amd64-generic-lacros-dbg/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-rel-renamed/gn-args.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-rel-renamed/gn-args.json
new file mode 100644
index 0000000..13ca3b7
--- /dev/null
+++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-rel-renamed/gn-args.json
@@ -0,0 +1,11 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
+  "gn_args": {
+    "also_build_lacros_chrome_for_architecture": "amd64",
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_real_dbus_clients": false,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-rel-renamed/properties.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-rel-renamed/properties.json
index fcdde042..55c2350 100644
--- a/infra/config/generated/builders/ci/chromeos-amd64-generic-rel-renamed/properties.json
+++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-rel-renamed/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/chromeos-amd64-generic-rel-renamed/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-rel/gn-args.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-rel/gn-args.json
new file mode 100644
index 0000000..13ca3b7
--- /dev/null
+++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-rel/gn-args.json
@@ -0,0 +1,11 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
+  "gn_args": {
+    "also_build_lacros_chrome_for_architecture": "amd64",
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_real_dbus_clients": false,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/chromeos-amd64-generic-rel/properties.json b/infra/config/generated/builders/ci/chromeos-amd64-generic-rel/properties.json
index f3514d60..dee9084ff 100644
--- a/infra/config/generated/builders/ci/chromeos-amd64-generic-rel/properties.json
+++ b/infra/config/generated/builders/ci/chromeos-amd64-generic-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/chromeos-amd64-generic-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/chromeos-arm-generic-dbg/gn-args.json b/infra/config/generated/builders/ci/chromeos-arm-generic-dbg/gn-args.json
new file mode 100644
index 0000000..982f4c56
--- /dev/null
+++ b/infra/config/generated/builders/ci/chromeos-arm-generic-dbg/gn-args.json
@@ -0,0 +1,10 @@
+{
+  "args_file": "//build/args/chromeos/arm-generic.gni",
+  "gn_args": {
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_debug": true,
+    "ozone_platform_headless": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/chromeos-arm-generic-dbg/properties.json b/infra/config/generated/builders/ci/chromeos-arm-generic-dbg/properties.json
index 9d8bc59..8628359 100644
--- a/infra/config/generated/builders/ci/chromeos-arm-generic-dbg/properties.json
+++ b/infra/config/generated/builders/ci/chromeos-arm-generic-dbg/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/chromeos-arm-generic-dbg/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/chromeos-arm-generic-rel/gn-args.json b/infra/config/generated/builders/ci/chromeos-arm-generic-rel/gn-args.json
new file mode 100644
index 0000000..bd801090
--- /dev/null
+++ b/infra/config/generated/builders/ci/chromeos-arm-generic-rel/gn-args.json
@@ -0,0 +1,9 @@
+{
+  "args_file": "//build/args/chromeos/arm-generic.gni",
+  "gn_args": {
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/chromeos-arm-generic-rel/properties.json b/infra/config/generated/builders/ci/chromeos-arm-generic-rel/properties.json
index 6955ac17..fe534fb8 100644
--- a/infra/config/generated/builders/ci/chromeos-arm-generic-rel/properties.json
+++ b/infra/config/generated/builders/ci/chromeos-arm-generic-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/chromeos-arm-generic-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/chromeos-arm64-generic-rel/gn-args.json b/infra/config/generated/builders/ci/chromeos-arm64-generic-rel/gn-args.json
new file mode 100644
index 0000000..5eda11b4
--- /dev/null
+++ b/infra/config/generated/builders/ci/chromeos-arm64-generic-rel/gn-args.json
@@ -0,0 +1,9 @@
+{
+  "args_file": "//build/args/chromeos/arm64-generic.gni",
+  "gn_args": {
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/chromeos-arm64-generic-rel/properties.json b/infra/config/generated/builders/ci/chromeos-arm64-generic-rel/properties.json
index b8d25d1..459a0cf4 100644
--- a/infra/config/generated/builders/ci/chromeos-arm64-generic-rel/properties.json
+++ b/infra/config/generated/builders/ci/chromeos-arm64-generic-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/chromeos-arm64-generic-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/chromeos-jacuzzi-rel/gn-args.json b/infra/config/generated/builders/ci/chromeos-jacuzzi-rel/gn-args.json
new file mode 100644
index 0000000..ba7fbcc
--- /dev/null
+++ b/infra/config/generated/builders/ci/chromeos-jacuzzi-rel/gn-args.json
@@ -0,0 +1,9 @@
+{
+  "args_file": "//build/args/chromeos/jacuzzi.gni",
+  "gn_args": {
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/chromeos-jacuzzi-rel/properties.json b/infra/config/generated/builders/ci/chromeos-jacuzzi-rel/properties.json
index ae2f35f..b77a9c8 100644
--- a/infra/config/generated/builders/ci/chromeos-jacuzzi-rel/properties.json
+++ b/infra/config/generated/builders/ci/chromeos-jacuzzi-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/chromeos-jacuzzi-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/chromeos-octopus-rel/gn-args.json b/infra/config/generated/builders/ci/chromeos-octopus-rel/gn-args.json
new file mode 100644
index 0000000..5ceb701
--- /dev/null
+++ b/infra/config/generated/builders/ci/chromeos-octopus-rel/gn-args.json
@@ -0,0 +1,9 @@
+{
+  "args_file": "//build/args/chromeos/octopus.gni",
+  "gn_args": {
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/chromeos-octopus-rel/properties.json b/infra/config/generated/builders/ci/chromeos-octopus-rel/properties.json
index 47d98f5..52d9be8 100644
--- a/infra/config/generated/builders/ci/chromeos-octopus-rel/properties.json
+++ b/infra/config/generated/builders/ci/chromeos-octopus-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/chromeos-octopus-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/lacros-amd64-generic-rel-non-skylab/gn-args.json b/infra/config/generated/builders/ci/lacros-amd64-generic-rel-non-skylab/gn-args.json
new file mode 100644
index 0000000..9483033
--- /dev/null
+++ b/infra/config/generated/builders/ci/lacros-amd64-generic-rel-non-skylab/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_debug": false,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/lacros-amd64-generic-rel-non-skylab/properties.json b/infra/config/generated/builders/ci/lacros-amd64-generic-rel-non-skylab/properties.json
index 9c6bb0e9..08435ab 100644
--- a/infra/config/generated/builders/ci/lacros-amd64-generic-rel-non-skylab/properties.json
+++ b/infra/config/generated/builders/ci/lacros-amd64-generic-rel-non-skylab/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/lacros-amd64-generic-rel-non-skylab/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/lacros-amd64-generic-rel/gn-args.json b/infra/config/generated/builders/ci/lacros-amd64-generic-rel/gn-args.json
new file mode 100644
index 0000000..736fd35
--- /dev/null
+++ b/infra/config/generated/builders/ci/lacros-amd64-generic-rel/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_debug": false,
+    "is_skylab": true,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/lacros-amd64-generic-rel/properties.json b/infra/config/generated/builders/ci/lacros-amd64-generic-rel/properties.json
index 95b97ac..779a08fa 100644
--- a/infra/config/generated/builders/ci/lacros-amd64-generic-rel/properties.json
+++ b/infra/config/generated/builders/ci/lacros-amd64-generic-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/lacros-amd64-generic-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/lacros-arm-generic-rel-skylab/gn-args.json b/infra/config/generated/builders/ci/lacros-arm-generic-rel-skylab/gn-args.json
new file mode 100644
index 0000000..fd9348f9
--- /dev/null
+++ b/infra/config/generated/builders/ci/lacros-arm-generic-rel-skylab/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "args_file": "//build/args/chromeos/arm-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_debug": false,
+    "is_skylab": true,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/lacros-arm-generic-rel-skylab/properties.json b/infra/config/generated/builders/ci/lacros-arm-generic-rel-skylab/properties.json
index dc34631..45bd139 100644
--- a/infra/config/generated/builders/ci/lacros-arm-generic-rel-skylab/properties.json
+++ b/infra/config/generated/builders/ci/lacros-arm-generic-rel-skylab/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/lacros-arm-generic-rel-skylab/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/lacros-arm-generic-rel/gn-args.json b/infra/config/generated/builders/ci/lacros-arm-generic-rel/gn-args.json
new file mode 100644
index 0000000..0b4ff5c
--- /dev/null
+++ b/infra/config/generated/builders/ci/lacros-arm-generic-rel/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "args_file": "//build/args/chromeos/arm-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_debug": false,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/lacros-arm-generic-rel/properties.json b/infra/config/generated/builders/ci/lacros-arm-generic-rel/properties.json
index 386c36dd..ebacc17 100644
--- a/infra/config/generated/builders/ci/lacros-arm-generic-rel/properties.json
+++ b/infra/config/generated/builders/ci/lacros-arm-generic-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/lacros-arm-generic-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab/gn-args.json b/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab/gn-args.json
new file mode 100644
index 0000000..4d95ed1
--- /dev/null
+++ b/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "args_file": "//build/args/chromeos/arm64-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_debug": false,
+    "is_skylab": true,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab/properties.json b/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab/properties.json
index dd0b986c..b343fc7f 100644
--- a/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab/properties.json
+++ b/infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/lacros-arm64-generic-rel-skylab/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/lacros-arm64-generic-rel/gn-args.json b/infra/config/generated/builders/ci/lacros-arm64-generic-rel/gn-args.json
new file mode 100644
index 0000000..07f603dd
--- /dev/null
+++ b/infra/config/generated/builders/ci/lacros-arm64-generic-rel/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "args_file": "//build/args/chromeos/arm64-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_debug": false,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/lacros-arm64-generic-rel/properties.json b/infra/config/generated/builders/ci/lacros-arm64-generic-rel/properties.json
index 983c9983..c4007a2 100644
--- a/infra/config/generated/builders/ci/lacros-arm64-generic-rel/properties.json
+++ b/infra/config/generated/builders/ci/lacros-arm64-generic-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/lacros-arm64-generic-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/linux-ash-chromium-generator-rel/gn-args.json b/infra/config/generated/builders/ci/linux-ash-chromium-generator-rel/gn-args.json
new file mode 100644
index 0000000..eab4743
--- /dev/null
+++ b/infra/config/generated/builders/ci/linux-ash-chromium-generator-rel/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "gn_args": {
+    "dcheck_always_on": false,
+    "ffmpeg_branding": "ChromeOS",
+    "is_component_build": false,
+    "is_debug": false,
+    "proprietary_codecs": true,
+    "target_os": "chromeos",
+    "use_cups": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-cfm-rel/gn-args.json b/infra/config/generated/builders/ci/linux-cfm-rel/gn-args.json
new file mode 100644
index 0000000..202faf1c
--- /dev/null
+++ b/infra/config/generated/builders/ci/linux-cfm-rel/gn-args.json
@@ -0,0 +1,10 @@
+{
+  "gn_args": {
+    "dcheck_always_on": false,
+    "is_cfm": true,
+    "is_component_build": false,
+    "is_debug": false,
+    "target_os": "chromeos",
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-cfm-rel/properties.json b/infra/config/generated/builders/ci/linux-cfm-rel/properties.json
index 4ce26d2..0fe30329 100644
--- a/infra/config/generated/builders/ci/linux-cfm-rel/properties.json
+++ b/infra/config/generated/builders/ci/linux-cfm-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/linux-cfm-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/linux-chromeos-dbg/gn-args.json b/infra/config/generated/builders/ci/linux-chromeos-dbg/gn-args.json
new file mode 100644
index 0000000..143093c
--- /dev/null
+++ b/infra/config/generated/builders/ci/linux-chromeos-dbg/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "gn_args": {
+    "ffmpeg_branding": "ChromeOS",
+    "is_component_build": true,
+    "is_debug": true,
+    "proprietary_codecs": true,
+    "symbol_level": 1,
+    "target_os": "chromeos",
+    "use_cups": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-chromeos-dbg/properties.json b/infra/config/generated/builders/ci/linux-chromeos-dbg/properties.json
index be5e1b2..160953d1 100644
--- a/infra/config/generated/builders/ci/linux-chromeos-dbg/properties.json
+++ b/infra/config/generated/builders/ci/linux-chromeos-dbg/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/linux-chromeos-dbg/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/linux-chromeos-rel/gn-args.json b/infra/config/generated/builders/ci/linux-chromeos-rel/gn-args.json
new file mode 100644
index 0000000..5fd2b39
--- /dev/null
+++ b/infra/config/generated/builders/ci/linux-chromeos-rel/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "gn_args": {
+    "also_build_lacros_chrome": true,
+    "dcheck_always_on": false,
+    "ffmpeg_branding": "ChromeOS",
+    "is_component_build": false,
+    "is_debug": false,
+    "proprietary_codecs": true,
+    "target_os": "chromeos",
+    "use_cups": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json b/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json
index f2ce0c7..1ee734d 100644
--- a/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json
+++ b/infra/config/generated/builders/ci/linux-chromeos-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/linux-chromeos-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/linux-lacros-builder-rel/gn-args.json b/infra/config/generated/builders/ci/linux-lacros-builder-rel/gn-args.json
new file mode 100644
index 0000000..4566fba
--- /dev/null
+++ b/infra/config/generated/builders/ci/linux-lacros-builder-rel/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "gn_args": {
+    "also_build_ash_chrome": true,
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": false,
+    "is_component_build": false,
+    "is_debug": false,
+    "target_os": "chromeos",
+    "use_cups": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-lacros-builder-rel/properties.json b/infra/config/generated/builders/ci/linux-lacros-builder-rel/properties.json
index 4211204..21a1ba3 100644
--- a/infra/config/generated/builders/ci/linux-lacros-builder-rel/properties.json
+++ b/infra/config/generated/builders/ci/linux-lacros-builder-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/linux-lacros-builder-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/ci/linux-lacros-dbg/gn-args.json b/infra/config/generated/builders/ci/linux-lacros-dbg/gn-args.json
new file mode 100644
index 0000000..fcad2ad
--- /dev/null
+++ b/infra/config/generated/builders/ci/linux-lacros-dbg/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "gn_args": {
+    "also_build_ash_chrome": true,
+    "chromeos_is_browser_only": true,
+    "is_component_build": true,
+    "is_debug": true,
+    "symbol_level": 1,
+    "target_os": "chromeos",
+    "use_cups": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/linux-lacros-dbg/properties.json b/infra/config/generated/builders/ci/linux-lacros-dbg/properties.json
index 2d1825e..2d0544d 100644
--- a/infra/config/generated/builders/ci/linux-lacros-dbg/properties.json
+++ b/infra/config/generated/builders/ci/linux-lacros-dbg/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/ci/linux-lacros-dbg/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/gn_args_locations.json b/infra/config/generated/builders/gn_args_locations.json
index ca35944..e5233bf 100644
--- a/infra/config/generated/builders/gn_args_locations.json
+++ b/infra/config/generated/builders/gn_args_locations.json
@@ -41,6 +41,31 @@
     "android-pie-x86-rel": "ci/android-pie-x86-rel/gn-args.json",
     "android-x86-rel": "ci/android-x86-rel/gn-args.json"
   },
+  "chromium.chromiumos": {
+    "chromeos-amd64-generic-asan-rel": "ci/chromeos-amd64-generic-asan-rel/gn-args.json",
+    "chromeos-amd64-generic-cfi-thin-lto-rel": "ci/chromeos-amd64-generic-cfi-thin-lto-rel/gn-args.json",
+    "chromeos-amd64-generic-dbg": "ci/chromeos-amd64-generic-dbg/gn-args.json",
+    "chromeos-amd64-generic-lacros-dbg": "ci/chromeos-amd64-generic-lacros-dbg/gn-args.json",
+    "chromeos-amd64-generic-rel": "ci/chromeos-amd64-generic-rel/gn-args.json",
+    "chromeos-amd64-generic-rel-renamed": "ci/chromeos-amd64-generic-rel-renamed/gn-args.json",
+    "chromeos-arm-generic-dbg": "ci/chromeos-arm-generic-dbg/gn-args.json",
+    "chromeos-arm-generic-rel": "ci/chromeos-arm-generic-rel/gn-args.json",
+    "chromeos-arm64-generic-rel": "ci/chromeos-arm64-generic-rel/gn-args.json",
+    "chromeos-jacuzzi-rel": "ci/chromeos-jacuzzi-rel/gn-args.json",
+    "chromeos-octopus-rel": "ci/chromeos-octopus-rel/gn-args.json",
+    "lacros-amd64-generic-rel": "ci/lacros-amd64-generic-rel/gn-args.json",
+    "lacros-amd64-generic-rel-non-skylab": "ci/lacros-amd64-generic-rel-non-skylab/gn-args.json",
+    "lacros-arm-generic-rel": "ci/lacros-arm-generic-rel/gn-args.json",
+    "lacros-arm-generic-rel-skylab": "ci/lacros-arm-generic-rel-skylab/gn-args.json",
+    "lacros-arm64-generic-rel": "ci/lacros-arm64-generic-rel/gn-args.json",
+    "lacros-arm64-generic-rel-skylab": "ci/lacros-arm64-generic-rel-skylab/gn-args.json",
+    "linux-ash-chromium-generator-rel": "ci/linux-ash-chromium-generator-rel/gn-args.json",
+    "linux-cfm-rel": "ci/linux-cfm-rel/gn-args.json",
+    "linux-chromeos-dbg": "ci/linux-chromeos-dbg/gn-args.json",
+    "linux-chromeos-rel": "ci/linux-chromeos-rel/gn-args.json",
+    "linux-lacros-builder-rel": "ci/linux-lacros-builder-rel/gn-args.json",
+    "linux-lacros-dbg": "ci/linux-lacros-dbg/gn-args.json"
+  },
   "chromium.clang": {
     "CFI Linux CF": "ci/CFI Linux CF/gn-args.json",
     "CFI Linux ToT": "ci/CFI Linux ToT/gn-args.json",
@@ -239,6 +264,33 @@
     "android_compile_x86_dbg": "try/android_compile_x86_dbg/gn-args.json",
     "android_cronet": "try/android_cronet/gn-args.json"
   },
+  "tryserver.chromium.chromiumos": {
+    "chromeos-amd64-generic-asan-rel": "try/chromeos-amd64-generic-asan-rel/gn-args.json",
+    "chromeos-amd64-generic-cfi-thin-lto-rel": "try/chromeos-amd64-generic-cfi-thin-lto-rel/gn-args.json",
+    "chromeos-amd64-generic-dbg": "try/chromeos-amd64-generic-dbg/gn-args.json",
+    "chromeos-amd64-generic-lacros-dbg": "try/chromeos-amd64-generic-lacros-dbg/gn-args.json",
+    "chromeos-amd64-generic-rel": "try/chromeos-amd64-generic-rel/gn-args.json",
+    "chromeos-amd64-generic-rel-gtest": "try/chromeos-amd64-generic-rel-gtest/gn-args.json",
+    "chromeos-amd64-generic-rel-gtest-and-tast": "try/chromeos-amd64-generic-rel-gtest-and-tast/gn-args.json",
+    "chromeos-amd64-generic-rel-renamed": "try/chromeos-amd64-generic-rel-renamed/gn-args.json",
+    "chromeos-arm-generic-dbg": "try/chromeos-arm-generic-dbg/gn-args.json",
+    "chromeos-arm-generic-rel": "try/chromeos-arm-generic-rel/gn-args.json",
+    "chromeos-arm64-generic-rel": "try/chromeos-arm64-generic-rel/gn-args.json",
+    "chromeos-jacuzzi-rel": "try/chromeos-jacuzzi-rel/gn-args.json",
+    "chromeos-octopus-rel": "try/chromeos-octopus-rel/gn-args.json",
+    "lacros-amd64-generic-rel": "try/lacros-amd64-generic-rel/gn-args.json",
+    "lacros-amd64-generic-rel-non-skylab": "try/lacros-amd64-generic-rel-non-skylab/gn-args.json",
+    "lacros-arm-generic-rel": "try/lacros-arm-generic-rel/gn-args.json",
+    "lacros-arm-generic-rel-skylab": "try/lacros-arm-generic-rel-skylab/gn-args.json",
+    "lacros-arm64-generic-rel": "try/lacros-arm64-generic-rel/gn-args.json",
+    "lacros-arm64-generic-rel-skylab": "try/lacros-arm64-generic-rel-skylab/gn-args.json",
+    "linux-cfm-rel": "try/linux-cfm-rel/gn-args.json",
+    "linux-chromeos-compile-dbg": "try/linux-chromeos-compile-dbg/gn-args.json",
+    "linux-chromeos-dbg": "try/linux-chromeos-dbg/gn-args.json",
+    "linux-chromeos-rel": "try/linux-chromeos-rel/gn-args.json",
+    "linux-lacros-dbg": "try/linux-lacros-dbg/gn-args.json",
+    "linux-lacros-rel": "try/linux-lacros-rel/gn-args.json"
+  },
   "tryserver.chromium.dawn": {
     "android-dawn-arm-rel": "try/android-dawn-arm-rel/gn-args.json",
     "android-dawn-arm64-rel": "try/android-dawn-arm64-rel/gn-args.json",
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-asan-rel/gn-args.json b/infra/config/generated/builders/try/chromeos-amd64-generic-asan-rel/gn-args.json
new file mode 100644
index 0000000..42bb990
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-asan-rel/gn-args.json
@@ -0,0 +1,10 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic.gni",
+  "gn_args": {
+    "dcheck_always_on": false,
+    "is_asan": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-asan-rel/properties.json b/infra/config/generated/builders/try/chromeos-amd64-generic-asan-rel/properties.json
index 2f61320..976a349 100644
--- a/infra/config/generated/builders/try/chromeos-amd64-generic-asan-rel/properties.json
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-asan-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-amd64-generic-asan-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-cfi-thin-lto-rel/gn-args.json b/infra/config/generated/builders/try/chromeos-amd64-generic-cfi-thin-lto-rel/gn-args.json
new file mode 100644
index 0000000..70a452fb
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-cfi-thin-lto-rel/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic.gni",
+  "gn_args": {
+    "also_build_lacros_chrome_for_architecture": "amd64",
+    "dcheck_always_on": false,
+    "is_cfi": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_cfi_cast": true,
+    "use_remoteexec": true,
+    "use_thin_lto": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-cfi-thin-lto-rel/properties.json b/infra/config/generated/builders/try/chromeos-amd64-generic-cfi-thin-lto-rel/properties.json
index bc1ceda..08015147 100644
--- a/infra/config/generated/builders/try/chromeos-amd64-generic-cfi-thin-lto-rel/properties.json
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-cfi-thin-lto-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-amd64-generic-cfi-thin-lto-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-dbg/gn-args.json b/infra/config/generated/builders/try/chromeos-amd64-generic-dbg/gn-args.json
new file mode 100644
index 0000000..16e3b03
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-dbg/gn-args.json
@@ -0,0 +1,11 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic.gni",
+  "gn_args": {
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_debug": true,
+    "ozone_platform_headless": true,
+    "use_dummy_lastchange": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-dbg/properties.json b/infra/config/generated/builders/try/chromeos-amd64-generic-dbg/properties.json
index 36d97ec..3a220d6 100644
--- a/infra/config/generated/builders/try/chromeos-amd64-generic-dbg/properties.json
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-dbg/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-amd64-generic-dbg/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-lacros-dbg/gn-args.json b/infra/config/generated/builders/try/chromeos-amd64-generic-lacros-dbg/gn-args.json
new file mode 100644
index 0000000..5f38a1f5
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-lacros-dbg/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_component_build": false,
+    "is_debug": true,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-lacros-dbg/properties.json b/infra/config/generated/builders/try/chromeos-amd64-generic-lacros-dbg/properties.json
index 6b17064..b40a243 100644
--- a/infra/config/generated/builders/try/chromeos-amd64-generic-lacros-dbg/properties.json
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-lacros-dbg/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-amd64-generic-lacros-dbg/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-compilator/properties.json b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-compilator/properties.json
index 4f1933e..66440ce 100644
--- a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-compilator/properties.json
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-compilator/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-amd64-generic-rel-renamed/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-and-tast-compilator/properties.json b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-and-tast-compilator/properties.json
index 46b7449..c2daa6f 100644
--- a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-and-tast-compilator/properties.json
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-and-tast-compilator/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-and-tast/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-and-tast/gn-args.json b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-and-tast/gn-args.json
new file mode 100644
index 0000000..7a830b21
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-and-tast/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
+  "gn_args": {
+    "also_build_lacros_chrome_for_architecture": "amd64",
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_dummy_lastchange": true,
+    "use_real_dbus_clients": false,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-and-tast/properties.json b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-and-tast/properties.json
index fa512c6b..f69ffb3 100644
--- a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-and-tast/properties.json
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-and-tast/properties.json
@@ -5,6 +5,9 @@
   },
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-and-tast/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-compilator/properties.json b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-compilator/properties.json
index e8670139..ff9dcf6 100644
--- a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-compilator/properties.json
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest-compilator/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest/gn-args.json b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest/gn-args.json
new file mode 100644
index 0000000..7a830b21
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
+  "gn_args": {
+    "also_build_lacros_chrome_for_architecture": "amd64",
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_dummy_lastchange": true,
+    "use_real_dbus_clients": false,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest/properties.json b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest/properties.json
index 09c546e..0078e293 100644
--- a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest/properties.json
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest/properties.json
@@ -5,6 +5,9 @@
   },
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-amd64-generic-rel-gtest/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-renamed/gn-args.json b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-renamed/gn-args.json
new file mode 100644
index 0000000..7a830b21
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-renamed/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
+  "gn_args": {
+    "also_build_lacros_chrome_for_architecture": "amd64",
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_dummy_lastchange": true,
+    "use_real_dbus_clients": false,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-renamed/properties.json b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-renamed/properties.json
index 22c6e92b..4848423 100644
--- a/infra/config/generated/builders/try/chromeos-amd64-generic-rel-renamed/properties.json
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-rel-renamed/properties.json
@@ -5,6 +5,9 @@
   },
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-amd64-generic-rel-renamed/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-rel/gn-args.json b/infra/config/generated/builders/try/chromeos-amd64-generic-rel/gn-args.json
new file mode 100644
index 0000000..7a830b21
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-rel/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
+  "gn_args": {
+    "also_build_lacros_chrome_for_architecture": "amd64",
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_dummy_lastchange": true,
+    "use_real_dbus_clients": false,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-rel/properties.json b/infra/config/generated/builders/try/chromeos-amd64-generic-rel/properties.json
index 4b6babf..df1a393 100644
--- a/infra/config/generated/builders/try/chromeos-amd64-generic-rel/properties.json
+++ b/infra/config/generated/builders/try/chromeos-amd64-generic-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-amd64-generic-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-arm-generic-dbg/gn-args.json b/infra/config/generated/builders/try/chromeos-arm-generic-dbg/gn-args.json
new file mode 100644
index 0000000..982f4c56
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-arm-generic-dbg/gn-args.json
@@ -0,0 +1,10 @@
+{
+  "args_file": "//build/args/chromeos/arm-generic.gni",
+  "gn_args": {
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_debug": true,
+    "ozone_platform_headless": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-arm-generic-dbg/properties.json b/infra/config/generated/builders/try/chromeos-arm-generic-dbg/properties.json
index f8c5e21..0ad21d14 100644
--- a/infra/config/generated/builders/try/chromeos-arm-generic-dbg/properties.json
+++ b/infra/config/generated/builders/try/chromeos-arm-generic-dbg/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-arm-generic-dbg/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-arm-generic-rel/gn-args.json b/infra/config/generated/builders/try/chromeos-arm-generic-rel/gn-args.json
new file mode 100644
index 0000000..0debe17
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-arm-generic-rel/gn-args.json
@@ -0,0 +1,10 @@
+{
+  "args_file": "//build/args/chromeos/arm-generic.gni",
+  "gn_args": {
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_dummy_lastchange": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-arm-generic-rel/properties.json b/infra/config/generated/builders/try/chromeos-arm-generic-rel/properties.json
index e884188..12cac51 100644
--- a/infra/config/generated/builders/try/chromeos-arm-generic-rel/properties.json
+++ b/infra/config/generated/builders/try/chromeos-arm-generic-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-arm-generic-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-arm64-generic-rel/gn-args.json b/infra/config/generated/builders/try/chromeos-arm64-generic-rel/gn-args.json
new file mode 100644
index 0000000..5eda11b4
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-arm64-generic-rel/gn-args.json
@@ -0,0 +1,9 @@
+{
+  "args_file": "//build/args/chromeos/arm64-generic.gni",
+  "gn_args": {
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-arm64-generic-rel/properties.json b/infra/config/generated/builders/try/chromeos-arm64-generic-rel/properties.json
index 28eeb74f..5094cab 100644
--- a/infra/config/generated/builders/try/chromeos-arm64-generic-rel/properties.json
+++ b/infra/config/generated/builders/try/chromeos-arm64-generic-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-arm64-generic-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-jacuzzi-rel/gn-args.json b/infra/config/generated/builders/try/chromeos-jacuzzi-rel/gn-args.json
new file mode 100644
index 0000000..ba7fbcc
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-jacuzzi-rel/gn-args.json
@@ -0,0 +1,9 @@
+{
+  "args_file": "//build/args/chromeos/jacuzzi.gni",
+  "gn_args": {
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-jacuzzi-rel/properties.json b/infra/config/generated/builders/try/chromeos-jacuzzi-rel/properties.json
index 5ddb97b..a7f764fd 100644
--- a/infra/config/generated/builders/try/chromeos-jacuzzi-rel/properties.json
+++ b/infra/config/generated/builders/try/chromeos-jacuzzi-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-jacuzzi-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/chromeos-octopus-rel/gn-args.json b/infra/config/generated/builders/try/chromeos-octopus-rel/gn-args.json
new file mode 100644
index 0000000..5ceb701
--- /dev/null
+++ b/infra/config/generated/builders/try/chromeos-octopus-rel/gn-args.json
@@ -0,0 +1,9 @@
+{
+  "args_file": "//build/args/chromeos/octopus.gni",
+  "gn_args": {
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "ozone_platform_headless": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/chromeos-octopus-rel/properties.json b/infra/config/generated/builders/try/chromeos-octopus-rel/properties.json
index ddcde43a..475c63200 100644
--- a/infra/config/generated/builders/try/chromeos-octopus-rel/properties.json
+++ b/infra/config/generated/builders/try/chromeos-octopus-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/chromeos-octopus-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/lacros-amd64-generic-rel-compilator/properties.json b/infra/config/generated/builders/try/lacros-amd64-generic-rel-compilator/properties.json
index b5f7103..26e70ba9 100644
--- a/infra/config/generated/builders/try/lacros-amd64-generic-rel-compilator/properties.json
+++ b/infra/config/generated/builders/try/lacros-amd64-generic-rel-compilator/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/lacros-amd64-generic-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/lacros-amd64-generic-rel-non-skylab/gn-args.json b/infra/config/generated/builders/try/lacros-amd64-generic-rel-non-skylab/gn-args.json
new file mode 100644
index 0000000..a492cde39
--- /dev/null
+++ b/infra/config/generated/builders/try/lacros-amd64-generic-rel-non-skylab/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "is_debug": false,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_dummy_lastchange": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/lacros-amd64-generic-rel-non-skylab/properties.json b/infra/config/generated/builders/try/lacros-amd64-generic-rel-non-skylab/properties.json
index d172c4df..63e63d99 100644
--- a/infra/config/generated/builders/try/lacros-amd64-generic-rel-non-skylab/properties.json
+++ b/infra/config/generated/builders/try/lacros-amd64-generic-rel-non-skylab/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/lacros-amd64-generic-rel-non-skylab/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/lacros-amd64-generic-rel/gn-args.json b/infra/config/generated/builders/try/lacros-amd64-generic-rel/gn-args.json
new file mode 100644
index 0000000..501041d
--- /dev/null
+++ b/infra/config/generated/builders/try/lacros-amd64-generic-rel/gn-args.json
@@ -0,0 +1,14 @@
+{
+  "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "is_debug": false,
+    "is_skylab": true,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_dummy_lastchange": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/lacros-amd64-generic-rel/properties.json b/infra/config/generated/builders/try/lacros-amd64-generic-rel/properties.json
index d1c6521..916f39e 100644
--- a/infra/config/generated/builders/try/lacros-amd64-generic-rel/properties.json
+++ b/infra/config/generated/builders/try/lacros-amd64-generic-rel/properties.json
@@ -5,6 +5,9 @@
   },
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/lacros-amd64-generic-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/lacros-arm-generic-rel-skylab/gn-args.json b/infra/config/generated/builders/try/lacros-arm-generic-rel-skylab/gn-args.json
new file mode 100644
index 0000000..fd9348f9
--- /dev/null
+++ b/infra/config/generated/builders/try/lacros-arm-generic-rel-skylab/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "args_file": "//build/args/chromeos/arm-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_debug": false,
+    "is_skylab": true,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/lacros-arm-generic-rel-skylab/properties.json b/infra/config/generated/builders/try/lacros-arm-generic-rel-skylab/properties.json
index a6d862a2..9306281 100644
--- a/infra/config/generated/builders/try/lacros-arm-generic-rel-skylab/properties.json
+++ b/infra/config/generated/builders/try/lacros-arm-generic-rel-skylab/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/lacros-arm-generic-rel-skylab/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/lacros-arm-generic-rel/gn-args.json b/infra/config/generated/builders/try/lacros-arm-generic-rel/gn-args.json
new file mode 100644
index 0000000..2231274
--- /dev/null
+++ b/infra/config/generated/builders/try/lacros-arm-generic-rel/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "args_file": "//build/args/chromeos/arm-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "is_debug": false,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_dummy_lastchange": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/lacros-arm-generic-rel/properties.json b/infra/config/generated/builders/try/lacros-arm-generic-rel/properties.json
index 01fafbac..2766c37 100644
--- a/infra/config/generated/builders/try/lacros-arm-generic-rel/properties.json
+++ b/infra/config/generated/builders/try/lacros-arm-generic-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/lacros-arm-generic-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/lacros-arm64-generic-rel-skylab/gn-args.json b/infra/config/generated/builders/try/lacros-arm64-generic-rel-skylab/gn-args.json
new file mode 100644
index 0000000..4d95ed1
--- /dev/null
+++ b/infra/config/generated/builders/try/lacros-arm64-generic-rel-skylab/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "args_file": "//build/args/chromeos/arm64-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": false,
+    "is_chromeos_device": true,
+    "is_debug": false,
+    "is_skylab": true,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/lacros-arm64-generic-rel-skylab/properties.json b/infra/config/generated/builders/try/lacros-arm64-generic-rel-skylab/properties.json
index 0a6cdd12..c6364dd 100644
--- a/infra/config/generated/builders/try/lacros-arm64-generic-rel-skylab/properties.json
+++ b/infra/config/generated/builders/try/lacros-arm64-generic-rel-skylab/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/lacros-arm64-generic-rel-skylab/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/lacros-arm64-generic-rel/gn-args.json b/infra/config/generated/builders/try/lacros-arm64-generic-rel/gn-args.json
new file mode 100644
index 0000000..2150314d
--- /dev/null
+++ b/infra/config/generated/builders/try/lacros-arm64-generic-rel/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "args_file": "//build/args/chromeos/arm64-generic-crostoolchain.gni",
+  "gn_args": {
+    "chromeos_is_browser_only": true,
+    "dcheck_always_on": true,
+    "is_chromeos_device": true,
+    "is_debug": false,
+    "ozone_platform_headless": true,
+    "target_os": "chromeos",
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/lacros-arm64-generic-rel/properties.json b/infra/config/generated/builders/try/lacros-arm64-generic-rel/properties.json
index 5d1155a7..043b01c 100644
--- a/infra/config/generated/builders/try/lacros-arm64-generic-rel/properties.json
+++ b/infra/config/generated/builders/try/lacros-arm64-generic-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/lacros-arm64-generic-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/linux-cfm-rel/gn-args.json b/infra/config/generated/builders/try/linux-cfm-rel/gn-args.json
new file mode 100644
index 0000000..0c5f630e
--- /dev/null
+++ b/infra/config/generated/builders/try/linux-cfm-rel/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "gn_args": {
+    "dcheck_always_on": true,
+    "is_cfm": true,
+    "is_component_build": false,
+    "is_debug": false,
+    "symbol_level": 0,
+    "target_os": "chromeos",
+    "use_dummy_lastchange": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux-cfm-rel/properties.json b/infra/config/generated/builders/try/linux-cfm-rel/properties.json
index 60ebdcd4..1cfecf3a 100644
--- a/infra/config/generated/builders/try/linux-cfm-rel/properties.json
+++ b/infra/config/generated/builders/try/linux-cfm-rel/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/linux-cfm-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/linux-chromeos-compile-dbg/gn-args.json b/infra/config/generated/builders/try/linux-chromeos-compile-dbg/gn-args.json
new file mode 100644
index 0000000..5e765cf
--- /dev/null
+++ b/infra/config/generated/builders/try/linux-chromeos-compile-dbg/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "gn_args": {
+    "ffmpeg_branding": "ChromeOS",
+    "is_component_build": true,
+    "is_debug": true,
+    "proprietary_codecs": true,
+    "symbol_level": 0,
+    "target_os": "chromeos",
+    "use_cups": true,
+    "use_dummy_lastchange": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux-chromeos-compile-dbg/properties.json b/infra/config/generated/builders/try/linux-chromeos-compile-dbg/properties.json
index a685624..e6a13992 100644
--- a/infra/config/generated/builders/try/linux-chromeos-compile-dbg/properties.json
+++ b/infra/config/generated/builders/try/linux-chromeos-compile-dbg/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/linux-chromeos-compile-dbg/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/linux-chromeos-dbg/gn-args.json b/infra/config/generated/builders/try/linux-chromeos-dbg/gn-args.json
new file mode 100644
index 0000000..0e73baaf
--- /dev/null
+++ b/infra/config/generated/builders/try/linux-chromeos-dbg/gn-args.json
@@ -0,0 +1,13 @@
+{
+  "gn_args": {
+    "ffmpeg_branding": "ChromeOS",
+    "is_component_build": true,
+    "is_debug": true,
+    "proprietary_codecs": true,
+    "symbol_level": 1,
+    "target_os": "chromeos",
+    "use_cups": true,
+    "use_dummy_lastchange": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux-chromeos-dbg/properties.json b/infra/config/generated/builders/try/linux-chromeos-dbg/properties.json
index 5bff296..8ccf034 100644
--- a/infra/config/generated/builders/try/linux-chromeos-dbg/properties.json
+++ b/infra/config/generated/builders/try/linux-chromeos-dbg/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/linux-chromeos-dbg/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/linux-chromeos-rel-compilator/properties.json b/infra/config/generated/builders/try/linux-chromeos-rel-compilator/properties.json
index ca6972f..ea7f9d8 100644
--- a/infra/config/generated/builders/try/linux-chromeos-rel-compilator/properties.json
+++ b/infra/config/generated/builders/try/linux-chromeos-rel-compilator/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/linux-chromeos-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/linux-chromeos-rel/gn-args.json b/infra/config/generated/builders/try/linux-chromeos-rel/gn-args.json
new file mode 100644
index 0000000..f82fc1b
--- /dev/null
+++ b/infra/config/generated/builders/try/linux-chromeos-rel/gn-args.json
@@ -0,0 +1,20 @@
+{
+  "gn_args": {
+    "also_build_lacros_chrome": true,
+    "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
+    "dcheck_always_on": true,
+    "enable_backup_ref_ptr_feature_flag": true,
+    "enable_dangling_raw_ptr_checks": true,
+    "enable_dangling_raw_ptr_feature_flag": true,
+    "ffmpeg_branding": "ChromeOS",
+    "is_component_build": false,
+    "is_debug": false,
+    "proprietary_codecs": true,
+    "symbol_level": 0,
+    "target_os": "chromeos",
+    "use_clang_coverage": true,
+    "use_cups": true,
+    "use_dummy_lastchange": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux-chromeos-rel/properties.json b/infra/config/generated/builders/try/linux-chromeos-rel/properties.json
index 1bc54afc..5aeca9c3 100644
--- a/infra/config/generated/builders/try/linux-chromeos-rel/properties.json
+++ b/infra/config/generated/builders/try/linux-chromeos-rel/properties.json
@@ -5,6 +5,9 @@
   },
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/linux-chromeos-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/linux-lacros-dbg/gn-args.json b/infra/config/generated/builders/try/linux-lacros-dbg/gn-args.json
new file mode 100644
index 0000000..fcad2ad
--- /dev/null
+++ b/infra/config/generated/builders/try/linux-lacros-dbg/gn-args.json
@@ -0,0 +1,12 @@
+{
+  "gn_args": {
+    "also_build_ash_chrome": true,
+    "chromeos_is_browser_only": true,
+    "is_component_build": true,
+    "is_debug": true,
+    "symbol_level": 1,
+    "target_os": "chromeos",
+    "use_cups": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux-lacros-dbg/properties.json b/infra/config/generated/builders/try/linux-lacros-dbg/properties.json
index 9c3a1c2..bad8657 100644
--- a/infra/config/generated/builders/try/linux-lacros-dbg/properties.json
+++ b/infra/config/generated/builders/try/linux-lacros-dbg/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/linux-lacros-dbg/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/linux-lacros-rel-compilator/properties.json b/infra/config/generated/builders/try/linux-lacros-rel-compilator/properties.json
index 577c04a..24a6c120 100644
--- a/infra/config/generated/builders/try/linux-lacros-rel-compilator/properties.json
+++ b/infra/config/generated/builders/try/linux-lacros-rel-compilator/properties.json
@@ -1,6 +1,9 @@
 {
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/linux-lacros-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/builders/try/linux-lacros-rel/gn-args.json b/infra/config/generated/builders/try/linux-lacros-rel/gn-args.json
new file mode 100644
index 0000000..2045401
--- /dev/null
+++ b/infra/config/generated/builders/try/linux-lacros-rel/gn-args.json
@@ -0,0 +1,17 @@
+{
+  "gn_args": {
+    "also_build_ash_chrome": true,
+    "chromeos_is_browser_only": true,
+    "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
+    "dcheck_always_on": true,
+    "is_clang": true,
+    "is_component_build": false,
+    "is_debug": false,
+    "symbol_level": 0,
+    "target_os": "chromeos",
+    "use_clang_coverage": true,
+    "use_cups": true,
+    "use_dummy_lastchange": true,
+    "use_remoteexec": true
+  }
+}
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/linux-lacros-rel/properties.json b/infra/config/generated/builders/try/linux-lacros-rel/properties.json
index dacf93b2..02416ae 100644
--- a/infra/config/generated/builders/try/linux-lacros-rel/properties.json
+++ b/infra/config/generated/builders/try/linux-lacros-rel/properties.json
@@ -5,6 +5,9 @@
   },
   "$build/chromium_tests_builder_config": {
     "builder_config": {
+      "additional_exclusions": [
+        "infra/config/generated/builders/try/linux-lacros-rel/gn-args.json"
+      ],
       "builder_db": {
         "entries": [
           {
diff --git a/infra/config/generated/health-specs/health-specs.json b/infra/config/generated/health-specs/health-specs.json
index 6dc9132..c5a26a1c 100644
--- a/infra/config/generated/health-specs/health-specs.json
+++ b/infra/config/generated/health-specs/health-specs.json
@@ -734,7 +734,14 @@
       "Mac ASAN Release": {
         "contact_team_email": "chrome-sanitizer-builder-owners@google.com",
         "thresholds": {
-          "_default": "_default"
+          "build_time": {},
+          "fail_rate": {
+            "average": 0.2
+          },
+          "infra_fail_rate": {
+            "average": 0.05
+          },
+          "pending_time": {}
         }
       },
       "Mac ASAN Release Media": {
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 67880f1c..71d13d1 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -42295,6 +42295,9 @@
         '  },'
         '  "$build/chromium_tests_builder_config": {'
         '    "builder_config": {'
+        '      "additional_exclusions": ['
+        '        "infra/config/generated/builders/ci/linux-ash-chromium-generator-rel/gn-args.json"'
+        '      ],'
         '      "builder_db": {'
         '        "entries": ['
         '          {'
diff --git a/infra/config/generated/luci/realms.cfg b/infra/config/generated/luci/realms.cfg
index e0a014f..f16a52e 100644
--- a/infra/config/generated/luci/realms.cfg
+++ b/infra/config/generated/luci/realms.cfg
@@ -333,6 +333,10 @@
     principals: "user:chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
   }
   bindings {
+    role: "role/buildbucket.reader"
+    principals: "group:all"
+  }
+  bindings {
     role: "role/resultdb.invocationCreator"
     principals: "user:chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
     principals: "user:chromium-try-gpu-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -638,6 +642,10 @@
     principals: "user:infra-try-recipes-tester@chops-service-accounts.iam.gserviceaccount.com"
   }
   bindings {
+    role: "role/buildbucket.reader"
+    principals: "group:all"
+  }
+  bindings {
     role: "role/resultdb.invocationCreator"
     principals: "group:project-chromium-try-task-accounts"
     principals: "group:project-chromium-tryjob-access"
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl
index 564338ca..4e0180e0 100644
--- a/infra/config/generated/testing/variants.pyl
+++ b/infra/config/generated/testing/variants.pyl
@@ -70,16 +70,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'identifier': 'Lacros version skew testing ash canary',
-    'description': 'Run with ash-chrome version 121.0.6129.0',
+    'description': 'Run with ash-chrome version 121.0.6130.0',
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome',
     ],
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v121.0.6129.0',
-          'revision': 'version:121.0.6129.0',
+          'location': 'lacros_version_skew_tests_v121.0.6130.0',
+          'revision': 'version:121.0.6130.0',
         },
       ],
     },
diff --git a/infra/config/gn_args/gn_args.star b/infra/config/gn_args/gn_args.star
index 31003c9..0261b3f 100644
--- a/infra/config/gn_args/gn_args.star
+++ b/infra/config/gn_args/gn_args.star
@@ -14,6 +14,13 @@
 )
 
 gn_args.config(
+    "also_build_lacros_chrome",
+    args = {
+        "also_build_lacros_chrome": True,
+    },
+)
+
+gn_args.config(
     "also_build_lacros_chrome_for_architecture_amd64",
     args = {
         "also_build_lacros_chrome_for_architecture": "amd64",
@@ -21,43 +28,60 @@
 )
 
 gn_args.config(
+    "amd64-generic",
+    args_file = "//build/args/chromeos/amd64-generic.gni",
+)
+
+gn_args.config(
+    "amd64-generic-crostoolchain",
+    args_file = "//build/args/chromeos/amd64-generic-crostoolchain.gni",
+)
+
+gn_args.config(
     "amd64-generic-vm",
     args_file = "//build/args/chromeos/amd64-generic-vm.gni",
 )
 
+gn_args.config(
+    name = "android",
+    args = {
+        "target_os": "android",
+    },
+)
+
 # We build Android with codecs on most bots to ensure maximum test
-# coverage, but use 'android_without_codecs' on bots responsible for
+# coverage, but use 'android_builder_without_codecs' on bots responsible for
 # building publicly advertised non-Official Android builds --
 # which are not allowed to have proprietary codecs enabled.
 gn_args.config(
-    "android",
+    "android_builder",
     configs = [
-        "android_without_codecs",
+        "android_builder_without_codecs",
         "chrome_with_codecs",
     ],
 )
 
-# It's significantly faster to build without static analysis checks.
-gn_args.config(
-    "android_fastbuild",
-    args = {
-        "android_static_analysis": "off",
-    },
-)
-
 # Builders never have a use for android:debuggable="true". They do not use
 # JWDP (java debugger), and do not need it to access application files
 # since they always use userdebug OS builds (which have root access).
 # android:debuggable="true" causes ART to run more slowly, so tests run
 # faster without it. https://crbug.com/1276429
 gn_args.config(
-    "android_without_codecs",
+    "android_builder_without_codecs",
+    configs = ["android"],
     args = {
-        "target_os": "android",
         "debuggable_apks": False,
     },
 )
 
+# It's significantly faster to build without static analysis checks.
+gn_args.config(
+    "android_fastbuild",
+    args = {
+        "android_static_analysis": "off",
+    },
+)
+
 gn_args.config(
     "arm",
     args = {
@@ -66,6 +90,16 @@
 )
 
 gn_args.config(
+    "arm-generic",
+    args_file = "//build/args/chromeos/arm-generic.gni",
+)
+
+gn_args.config(
+    "arm-generic-crostoolchain",
+    args_file = "//build/args/chromeos/arm-generic-crostoolchain.gni",
+)
+
+gn_args.config(
     "arm64",
     args = {
         "target_cpu": "arm64",
@@ -73,6 +107,16 @@
 )
 
 gn_args.config(
+    "arm64-generic",
+    args_file = "//build/args/chromeos/arm64-generic.gni",
+)
+
+gn_args.config(
+    "arm64-generic-crostoolchain",
+    args_file = "//build/args/chromeos/arm64-generic-crostoolchain.gni",
+)
+
+gn_args.config(
     "arm64_host",
     args = {
         "test_host_cpu": "arm64",
@@ -163,6 +207,13 @@
 )
 
 gn_args.config(
+    "cfm",
+    args = {
+        "is_cfm": True,
+    },
+)
+
+gn_args.config(
     "chrome_with_codecs",
     args = {
         "proprietary_codecs": True,
@@ -190,6 +241,14 @@
 )
 
 gn_args.config(
+    "chromeos_with_codecs",
+    configs = [
+        "chromeos",
+        "chromeos_codecs",
+    ],
+)
+
+gn_args.config(
     "chromeos_device",
     args = {
         "is_chromeos_device": True,
@@ -478,6 +537,26 @@
 )
 
 gn_args.config(
+    "is_skylab",
+    args = {
+        "is_skylab": True,
+    },
+)
+
+gn_args.config(
+    "jacuzzi",
+    args_file = "//build/args/chromeos/jacuzzi.gni",
+)
+
+gn_args.config(
+    "lacros",
+    args = {
+        "target_os": "chromeos",
+        "chromeos_is_browser_only": True,
+    },
+)
+
+gn_args.config(
     "lacros_on_linux",
     args = {
         "chromeos_is_browser_only": True,
@@ -583,6 +662,11 @@
 )
 
 gn_args.config(
+    "octopus",
+    args_file = "//build/args/chromeos/octopus.gni",
+)
+
+gn_args.config(
     "official_optimize",
     args = {
         "is_official_build": True,
@@ -789,6 +873,13 @@
 )
 
 gn_args.config(
+    "use_cups",
+    args = {
+        "use_cups": True,
+    },
+)
+
+gn_args.config(
     "use_dummy_lastchange",
     args = {
         "use_dummy_lastchange": True,
diff --git a/infra/config/subprojects/chromium/ci.star b/infra/config/subprojects/chromium/ci.star
index 59a9cb7..7f6cfa5 100644
--- a/infra/config/subprojects/chromium/ci.star
+++ b/infra/config/subprojects/chromium/ci.star
@@ -82,6 +82,14 @@
                 ci.gpu.SHADOW_SERVICE_ACCOUNT,
             ],
         ),
+        # TODO(crbug.com/1501383): Remove this binding after shadow bucket
+        # could inherit the view permission from the actual bucket.
+        luci.binding(
+            roles = "role/buildbucket.reader",
+            groups = [
+                "all",
+            ],
+        ),
         # Allow ci builders to create invocations in their own builds.
         luci.binding(
             roles = "role/resultdb.invocationCreator",
diff --git a/infra/config/subprojects/chromium/ci/chromium.android.star b/infra/config/subprojects/chromium/ci/chromium.android.star
index 77c4113..3fee113 100644
--- a/infra/config/subprojects/chromium/ci/chromium.android.star
+++ b/infra/config/subprojects/chromium/ci/chromium.android.star
@@ -81,7 +81,7 @@
     execution_timeout = 8 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "clang",
             "asan",
             "debug_builder",
@@ -203,7 +203,7 @@
     execution_timeout = 4 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android_without_codecs",
+            "android_builder_without_codecs",
             "debug_builder",
             "reclient",
         ],
@@ -249,7 +249,7 @@
     execution_timeout = 7 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "debug_static_builder",
             "reclient",
             "arm64",
@@ -302,7 +302,7 @@
     execution_timeout = 7 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "debug_static_builder",
             "reclient",
             "arm64",
@@ -329,7 +329,7 @@
     execution_timeout = 7 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "debug_static_builder",
             "reclient",
             "x64",
@@ -375,7 +375,7 @@
     execution_timeout = 7 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "debug_static_builder",
             "reclient",
             "x64",
@@ -417,7 +417,7 @@
     execution_timeout = 6 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "debug_static_builder",
             "reclient",
             "x86",
@@ -455,7 +455,7 @@
     contact_team_email = "woa-engprod@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_builder",
             "reclient",
             "minimal_symbols",
@@ -531,7 +531,7 @@
     contact_team_email = "clank-engprod@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cast_android",
             "cast_receiver",
             "clang",
@@ -554,7 +554,7 @@
     execution_timeout = 7 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android_without_codecs",
+            "android_builder_without_codecs",
             "release_builder",
             "reclient",
             "minimal_symbols",
@@ -578,7 +578,7 @@
     execution_timeout = 6 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "debug_builder",
             "reclient",
         ],
@@ -653,7 +653,7 @@
     contact_team_email = "clank-engprod@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_builder",
             "reclient",
             "minimal_symbols",
@@ -730,7 +730,7 @@
     execution_timeout = 8 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_builder",
             "reclient",
             "minimal_symbols",
@@ -767,7 +767,7 @@
     execution_timeout = 4 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_builder",
             "reclient",
             "minimal_symbols",
@@ -793,7 +793,7 @@
     contact_team_email = "clank-engprod@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "chrome_with_codecs",
             "reclient",
             "minimal_symbols",
@@ -840,7 +840,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "debug_static_builder",
             "reclient",
@@ -886,7 +886,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "official_optimize",
             "release_builder",
@@ -927,7 +927,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "debug_static_builder",
             "reclient",
@@ -965,7 +965,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "official_optimize",
             "release_builder",
@@ -1005,7 +1005,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "release_builder",
             "reclient",
@@ -1048,7 +1048,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "debug_static_builder",
             "reclient",
@@ -1088,7 +1088,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "official_optimize",
             "release_builder",
@@ -1136,7 +1136,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "debug_static_builder",
             "reclient",
@@ -1176,7 +1176,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "official_optimize",
             "release_builder",
@@ -1205,7 +1205,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "official_optimize",
             "release_builder",
@@ -1247,7 +1247,7 @@
     contact_team_email = "cronet-sheriff@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "debug_static_builder",
             "reclient",
@@ -1285,7 +1285,7 @@
     contact_team_email = "cronet-sheriff@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "official_optimize",
             "release_builder",
@@ -1331,7 +1331,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "debug_static_builder",
             "reclient",
@@ -1374,7 +1374,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "debug_static_builder",
             "reclient",
@@ -1764,7 +1764,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "official_optimize",
             "release_builder",
@@ -1805,7 +1805,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "official_optimize",
             "release_builder",
@@ -1846,7 +1846,7 @@
     execution_timeout = 4 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_builder",
             "reclient",
             "minimal_symbols",
@@ -1928,7 +1928,7 @@
     execution_timeout = 4 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_builder",
             "reclient",
             "minimal_symbols",
@@ -1971,7 +1971,7 @@
     contact_team_email = "clank-engprod@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_builder",
             "reclient",
             "minimal_symbols",
@@ -2019,7 +2019,7 @@
     execution_timeout = 4 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_builder",
             "reclient",
             "minimal_symbols",
@@ -2065,7 +2065,7 @@
     execution_timeout = 4 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_builder",
             "reclient",
             "minimal_symbols",
@@ -2115,7 +2115,7 @@
     execution_timeout = 4 * time.hour,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_builder",
             "reclient",
             "minimal_symbols",
diff --git a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
index b834966..62e6092 100644
--- a/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
+++ b/infra/config/subprojects/chromium/ci/chromium.chromiumos.star
@@ -10,6 +10,7 @@
 load("//lib/builders.star", "os", "reclient", "sheriff_rotations")
 load("//lib/ci.star", "ci")
 load("//lib/consoles.star", "consoles")
+load("//lib/gn_args.star", "gn_args")
 
 ci.defaults.set(
     executable = ci.DEFAULT_EXECUTABLE,
@@ -68,6 +69,14 @@
     # This builder gets triggered against multiple branches, so it shouldn't be
     # bootstrapped
     bootstrap = False,
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_with_codecs",
+            "release_builder",
+            "reclient",
+            "use_cups",
+        ],
+    ),
     notifies = ["chrome-lacros-engprod-alerts"],
     properties = {
         # The format of these properties is defined at archive/properties.proto
@@ -121,6 +130,16 @@
     ),
     main_console_view = "main",
     contact_team_email = "chrome-sanitizer-builder-owners@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "amd64-generic",
+            "ozone_headless",
+            "asan",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -155,6 +174,18 @@
     ),
     main_console_view = "main",
     contact_team_email = "chromeos-sw-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "amd64-generic",
+            "ozone_headless",
+            "cfi_full",
+            "thin_lto",
+            "also_build_lacros_chrome_for_architecture_amd64",
+        ],
+    ),
     health_spec = health_spec.modified_default(
         build_time = struct(
             p50_mins = 100,
@@ -195,6 +226,16 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chromeos-sw-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "amd64-generic",
+            "ozone_headless",
+            "debug",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -231,6 +272,18 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chrome-desktop-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "amd64-generic-crostoolchain",
+            "ozone_headless",
+            "lacros",
+            "debug",
+            "static",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -264,6 +317,17 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chromeos-sw-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "amd64-generic-vm",
+            "ozone_headless",
+            "use_fake_dbus_clients",
+            "also_build_lacros_chrome_for_architecture_amd64",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -298,6 +362,17 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chromeos-sw-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "amd64-generic-vm",
+            "ozone_headless",
+            "use_fake_dbus_clients",
+            "also_build_lacros_chrome_for_architecture_amd64",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -406,6 +481,16 @@
     ),
     main_console_view = "main",
     contact_team_email = "chromeos-sw-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "arm-generic",
+            "debug",
+            "ozone_headless",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -434,6 +519,15 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chromeos-sw-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "arm-generic",
+            "ozone_headless",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -461,6 +555,15 @@
     ),
     main_console_view = "main",
     contact_team_email = "chromeos-sw-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "reclient",
+            "arm64-generic",
+            "dcheck_always_on",
+            "ozone_headless",
+        ],
+    ),
 )
 
 ci.builder(
@@ -497,6 +600,15 @@
         short_name = "jcz",
     ),
     main_console_view = "main",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "reclient",
+            "jacuzzi",
+            "ozone_headless",
+            "dcheck_always_on",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -533,6 +645,15 @@
         short_name = "oct",
     ),
     main_console_view = "main",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "reclient",
+            "octopus",
+            "ozone_headless",
+            "dcheck_always_on",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -572,6 +693,18 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chrome-desktop-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "amd64-generic-crostoolchain",
+            "ozone_headless",
+            "lacros",
+            "release",
+            "is_skylab",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -611,6 +744,17 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chrome-desktop-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "amd64-generic-crostoolchain",
+            "ozone_headless",
+            "lacros",
+            "release",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -647,6 +791,18 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chrome-desktop-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "arm-generic-crostoolchain",
+            "ozone_headless",
+            "lacros",
+            "release",
+            "is_skylab",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -683,6 +839,18 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chrome-desktop-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "arm64-generic-crostoolchain",
+            "ozone_headless",
+            "lacros",
+            "release",
+            "is_skylab",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -722,6 +890,17 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chrome-desktop-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "arm-generic-crostoolchain",
+            "ozone_headless",
+            "lacros",
+            "release",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -761,6 +940,17 @@
     ),
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_device",
+            "dcheck_off",
+            "reclient",
+            "arm64-generic-crostoolchain",
+            "ozone_headless",
+            "lacros",
+            "release",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -792,6 +982,14 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chromeos-sw-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_with_codecs",
+            "debug_builder",
+            "reclient",
+            "use_cups",
+        ],
+    ),
     health_spec = health_spec.modified_default(
         build_time = struct(
             p50_mins = 150,
@@ -831,6 +1029,15 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chromeos-sw-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "chromeos_with_codecs",
+            "release_builder",
+            "reclient",
+            "use_cups",
+            "also_build_lacros_chrome",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -864,6 +1071,15 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chrome-desktop-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "lacros_on_linux",
+            "release_builder",
+            "reclient",
+            "also_build_ash_chrome",
+            "use_cups",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -931,6 +1147,15 @@
     main_console_view = "main",
     cq_mirrors_console_view = "mirrors",
     contact_team_email = "chrome-desktop-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "lacros_on_linux",
+            "debug_builder",
+            "reclient",
+            "also_build_ash_chrome",
+            "use_cups",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
 
@@ -961,5 +1186,13 @@
     ),
     main_console_view = "main",
     contact_team_email = "core-devices-eng@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "cfm",
+            "release_builder",
+            "reclient",
+            "chromeos",
+        ],
+    ),
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI,
 )
diff --git a/infra/config/subprojects/chromium/ci/chromium.clang.star b/infra/config/subprojects/chromium/ci/chromium.clang.star
index 9d2dff9e..9915f7f0 100644
--- a/infra/config/subprojects/chromium/ci/chromium.clang.star
+++ b/infra/config/subprojects/chromium/ci/chromium.clang.star
@@ -271,7 +271,7 @@
     contact_team_email = "lexan@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_builder",
             "minimal_symbols",
             "strip_debug_info",
@@ -308,7 +308,7 @@
     contact_team_email = "lexan@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android_without_codecs",
+            "android_builder_without_codecs",
             "clang_tot",
             "shared",
             "debug",
@@ -344,7 +344,7 @@
     contact_team_email = "lexan@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android_without_codecs",
+            "android_builder_without_codecs",
             "clang_tot",
             "shared",
             "release",
@@ -382,7 +382,7 @@
     contact_team_email = "lexan@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android_without_codecs",
+            "android_builder_without_codecs",
             "clang_tot",
             "shared",
             "release",
@@ -420,7 +420,7 @@
     contact_team_email = "lexan@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android_without_codecs",
+            "android_builder_without_codecs",
             "clang_tot",
             "shared",
             "release",
@@ -459,7 +459,7 @@
     contact_team_email = "lexan@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android_without_codecs",
+            "android_builder_without_codecs",
             "clang_tot",
             "release",
             "arm64",
@@ -495,7 +495,7 @@
     contact_team_email = "lexan@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android_without_codecs",
+            "android_builder_without_codecs",
             "clang_tot",
             "asan",
             "debug_builder",
@@ -532,7 +532,7 @@
     contact_team_email = "lexan@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_builder",
             "minimal_symbols",
             "official_optimize",
diff --git a/infra/config/subprojects/chromium/ci/chromium.dawn.star b/infra/config/subprojects/chromium/ci/chromium.dawn.star
index 69cd4d2..d71d5ab 100644
--- a/infra/config/subprojects/chromium/ci/chromium.dawn.star
+++ b/infra/config/subprojects/chromium/ci/chromium.dawn.star
@@ -143,7 +143,7 @@
     ),
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_try_builder",
             "minimal_symbols",
             "reclient",
@@ -231,7 +231,7 @@
     ),
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "arm64",
             "release_try_builder",
             "minimal_symbols",
@@ -363,7 +363,7 @@
     ),
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "release_try_builder",
             "minimal_symbols",
             "reclient",
@@ -454,7 +454,7 @@
     ),
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "arm64",
             "release_try_builder",
             "minimal_symbols",
diff --git a/infra/config/subprojects/chromium/ci/chromium.fuzz.star b/infra/config/subprojects/chromium/ci/chromium.fuzz.star
index d2c183f..14b50246 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fuzz.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fuzz.star
@@ -378,6 +378,11 @@
         short_name = "rel",
     ),
     contact_team_email = "chrome-sanitizer-builder-owners@google.com",
+    health_spec = health_spec.modified_default(
+        pending_time = struct(
+            p50_mins = None,  # exception added because this builder has a pool of 1 machine and 2 concurrent invocations
+        ),
+    ),
 )
 
 ci.builder(
diff --git a/infra/config/subprojects/chromium/try.star b/infra/config/subprojects/chromium/try.star
index b89924a..73c6329 100644
--- a/infra/config/subprojects/chromium/try.star
+++ b/infra/config/subprojects/chromium/try.star
@@ -83,6 +83,14 @@
                 "infra-try-recipes-tester@chops-service-accounts.iam.gserviceaccount.com",
             ],
         ),
+        # TODO(crbug.com/1501383): Remove this binding after shadow bucket
+        # could inherit the view permission from the actual bucket.
+        luci.binding(
+            roles = "role/buildbucket.reader",
+            groups = [
+                "all",
+            ],
+        ),
         # Allow try builders to create invocations in their own builds.
         luci.binding(
             roles = "role/resultdb.invocationCreator",
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
index f2af961..ee56bed 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.android.star
@@ -251,7 +251,7 @@
     ssd = True,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "chrome_with_codecs",
             "reclient",
             "minimal_symbols",
@@ -333,7 +333,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "debug_static_builder",
             "reclient",
@@ -626,7 +626,7 @@
     ],
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "debug_builder",
             "reclient",
             "arm64",
@@ -671,7 +671,7 @@
     cores = 16,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "debug_builder",
             "reclient",
             "arm64",
@@ -872,7 +872,7 @@
     ),
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "debug_builder",
             "reclient",
             "compile_only",
@@ -890,7 +890,7 @@
     ],
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "debug_builder",
             "reclient",
             "compile_only",
@@ -958,7 +958,7 @@
     ssd = True,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "debug_builder",
             "reclient",
             "compile_only",
@@ -1012,7 +1012,7 @@
     ssd = True,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "debug_builder",
             "reclient",
             "compile_only",
@@ -1062,7 +1062,7 @@
     ssd = True,
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "debug_builder",
             "reclient",
             "compile_only",
@@ -1098,7 +1098,7 @@
     contact_team_email = "cronet-team@google.com",
     gn_args = gn_args.config(
         configs = [
-            "android",
+            "android_builder",
             "cronet_android",
             "release_try_builder",
             "reclient",
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
index 86867a9..840bc5a 100644
--- a/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
+++ b/infra/config/subprojects/chromium/try/tryserver.chromium.chromiumos.star
@@ -9,6 +9,7 @@
 load("//lib/builders.star", "os", "reclient", "siso")
 load("//lib/try.star", "try_")
 load("//lib/consoles.star", "consoles")
+load("//lib/gn_args.star", "gn_args")
 load("//project.star", "settings")
 
 try_.defaults.set(
@@ -40,6 +41,7 @@
     mirrors = [
         "ci/chromeos-amd64-generic-asan-rel",
     ],
+    gn_args = "ci/chromeos-amd64-generic-asan-rel",
 )
 
 try_.builder(
@@ -47,6 +49,9 @@
     mirrors = [
         "ci/chromeos-amd64-generic-cfi-thin-lto-rel",
     ],
+    # TODO(crbug.com/913750): Enable DCHECKS on the two amd64-generic bots
+    # when the PFQ has it enabled.
+    gn_args = "ci/chromeos-amd64-generic-cfi-thin-lto-rel",
 )
 
 try_.builder(
@@ -55,6 +60,12 @@
     mirrors = [
         "ci/chromeos-amd64-generic-dbg",
     ],
+    gn_args = gn_args.config(
+        configs = [
+            "ci/chromeos-amd64-generic-dbg",
+            "use_dummy_lastchange",
+        ],
+    ),
     main_list_view = "try",
     tryjob = try_.job(
         location_filters = [
@@ -71,6 +82,13 @@
                        " This builder also build Lacros with alternative toolchain.",
     mirrors = ["ci/chromeos-amd64-generic-rel"],
     contact_team_email = "chromeos-sw-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "ci/chromeos-amd64-generic-rel",
+            "dcheck_always_on",
+            "use_dummy_lastchange",
+        ],
+    ),
     main_list_view = "try",
 )
 
@@ -89,6 +107,13 @@
     ],
     compilator = "chromeos-amd64-generic-rel-gtest-compilator",
     contact_team_email = "chromeos-sw-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "ci/chromeos-amd64-generic-rel",
+            "dcheck_always_on",
+            "use_dummy_lastchange",
+        ],
+    ),
     main_list_view = "try",
     tryjob = try_.job(
         equivalent_builder = "try/chromeos-amd64-generic-rel-gtest-and-tast",
@@ -119,6 +144,13 @@
     ],
     compilator = "chromeos-amd64-generic-rel-gtest-and-tast-compilator",
     contact_team_email = "chromeos-sw-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "ci/chromeos-amd64-generic-rel",
+            "dcheck_always_on",
+            "use_dummy_lastchange",
+        ],
+    ),
     main_list_view = "try",
     tryjob = try_.job(
         omit_from_luci_cv = True,
@@ -136,6 +168,13 @@
         # go/nplus1shardsproposal
         "chromium.add_one_test_shard": 10,
     },
+    gn_args = gn_args.config(
+        configs = [
+            "ci/chromeos-amd64-generic-rel-renamed",
+            "dcheck_always_on",
+            "use_dummy_lastchange",
+        ],
+    ),
     main_list_view = "try",
     tryjob = try_.job(),
 )
@@ -221,6 +260,7 @@
     mirrors = [
         "ci/chromeos-arm-generic-dbg",
     ],
+    gn_args = "ci/chromeos-arm-generic-dbg",
 )
 
 try_.builder(
@@ -228,6 +268,13 @@
     branch_selector = branches.selector.CROS_LTS_BRANCHES,
     mirrors = ["ci/chromeos-arm-generic-rel"],
     builderless = not settings.is_main,
+    gn_args = gn_args.config(
+        configs = [
+            "ci/chromeos-arm-generic-rel",
+            "dcheck_always_on",
+            "use_dummy_lastchange",
+        ],
+    ),
     main_list_view = "try",
     tryjob = try_.job(),
 )
@@ -236,6 +283,7 @@
     name = "chromeos-arm64-generic-rel",
     branch_selector = branches.selector.CROS_LTS_BRANCHES,
     mirrors = ["ci/chromeos-arm64-generic-rel"],
+    gn_args = "ci/chromeos-arm64-generic-rel",
 )
 
 try_.orchestrator_builder(
@@ -248,6 +296,13 @@
     ],
     compilator = "lacros-amd64-generic-rel-compilator",
     contact_team_email = "chrome-desktop-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "ci/lacros-amd64-generic-rel",
+            "dcheck_always_on",
+            "use_dummy_lastchange",
+        ],
+    ),
     main_list_view = "try",
     tryjob = try_.job(),
 )
@@ -268,6 +323,13 @@
         "ci/lacros-amd64-generic-rel-non-skylab",
     ],
     contact_team_email = "chrome-desktop-engprod@google.com",
+    gn_args = gn_args.config(
+        configs = [
+            "ci/lacros-amd64-generic-rel-non-skylab",
+            "dcheck_always_on",
+            "use_dummy_lastchange",
+        ],
+    ),
     main_list_view = "try",
 )
 
@@ -277,6 +339,7 @@
     mirrors = [
         "ci/chromeos-amd64-generic-lacros-dbg",
     ],
+    gn_args = "ci/chromeos-amd64-generic-lacros-dbg",
 )
 
 try_.builder(
@@ -286,6 +349,13 @@
         "ci/lacros-arm-generic-rel",
     ],
     builderless = not settings.is_main,
+    gn_args = gn_args.config(
+        configs = [
+            "ci/lacros-arm-generic-rel",
+            "dcheck_always_on",
+            "use_dummy_lastchange",
+        ],
+    ),
     main_list_view = "try",
     tryjob = try_.job(),
 )
@@ -297,6 +367,7 @@
         "ci/lacros-arm-generic-rel-skylab",
     ],
     contact_team_email = "chrome-desktop-engprod@google.com",
+    gn_args = "ci/lacros-arm-generic-rel-skylab",
     main_list_view = "try",
 )
 
@@ -306,6 +377,12 @@
     mirrors = [
         "ci/lacros-arm64-generic-rel",
     ],
+    gn_args = gn_args.config(
+        configs = [
+            "ci/lacros-arm64-generic-rel",
+            "dcheck_always_on",
+        ],
+    ),
     main_list_view = "try",
 )
 
@@ -316,6 +393,7 @@
         "ci/lacros-arm64-generic-rel-skylab",
     ],
     contact_team_email = "chrome-desktop-engprod@google.com",
+    gn_args = "ci/lacros-arm64-generic-rel-skylab",
     main_list_view = "try",
 )
 
@@ -330,6 +408,13 @@
         is_compile_only = True,
     ),
     builderless = not settings.is_main,
+    gn_args = gn_args.config(
+        configs = [
+            "ci/linux-chromeos-dbg",
+            "no_symbols",
+            "use_dummy_lastchange",
+        ],
+    ),
     main_list_view = "try",
     reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CQ,
     tryjob = try_.job(),
@@ -362,6 +447,12 @@
     mirrors = [
         "ci/chromeos-jacuzzi-rel",
     ],
+    gn_args = gn_args.config(
+        configs = [
+            "ci/chromeos-jacuzzi-rel",
+            "dcheck_always_on",
+        ],
+    ),
     main_list_view = "try",
 )
 
@@ -383,6 +474,7 @@
     mirrors = [
         "ci/chromeos-octopus-rel",
     ],
+    gn_args = "ci/chromeos-octopus-rel",
     main_list_view = "try",
 )
 
@@ -399,6 +491,17 @@
         "chromium.add_one_test_shard": 10,
         "chromium.pre_retry_shards_without_patch_compile": 100,
     },
+    gn_args = gn_args.config(
+        configs = [
+            "ci/linux-chromeos-rel",
+            "release_try_builder",
+            "no_symbols",
+            "use_clang_coverage",
+            "partial_code_coverage_instrumentation",
+            "enable_dangling_raw_ptr_feature_flag",
+            "enable_backup_ref_ptr_feature_flag",
+        ],
+    ),
     main_list_view = "try",
     tryjob = try_.job(),
     use_clang_coverage = True,
@@ -422,6 +525,7 @@
     mirrors = [
         "ci/linux-lacros-dbg",
     ],
+    gn_args = "ci/linux-lacros-dbg",
 )
 
 try_.orchestrator_builder(
@@ -437,6 +541,16 @@
         # go/nplus1shardsproposal
         "chromium.add_one_test_shard": 10,
     },
+    gn_args = gn_args.config(
+        configs = [
+            "ci/linux-lacros-builder-rel",
+            "release_try_builder",
+            "clang",
+            "use_clang_coverage",
+            "partial_code_coverage_instrumentation",
+            "use_dummy_lastchange",
+        ],
+    ),
     main_list_view = "try",
     tryjob = try_.job(),
     use_clang_coverage = True,
@@ -461,6 +575,12 @@
     mirrors = [
         "ci/linux-chromeos-dbg",
     ],
+    gn_args = gn_args.config(
+        configs = [
+            "ci/linux-chromeos-dbg",
+            "use_dummy_lastchange",
+        ],
+    ),
 )
 
 try_.builder(
@@ -475,6 +595,12 @@
     mirrors = [
         "ci/linux-cfm-rel",
     ],
+    gn_args = gn_args.config(
+        configs = [
+            "ci/linux-cfm-rel",
+            "release_try_builder",
+        ],
+    ),
     reclient_instance = reclient.instance.DEFAULT_UNTRUSTED,
     tryjob = try_.job(
         location_filters = [
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json
index 3946a27c..f2b694d 100644
--- a/infra/config/targets/lacros-version-skew-variants.json
+++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -1,16 +1,16 @@
 {
   "LACROS_VERSION_SKEW_CANARY": {
     "args": [
-      "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome"
+      "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome"
     ],
-    "description": "Run with ash-chrome version 121.0.6129.0",
+    "description": "Run with ash-chrome version 121.0.6130.0",
     "identifier": "Lacros version skew testing ash canary",
     "swarming": {
       "cipd_packages": [
         {
           "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-          "location": "lacros_version_skew_tests_v121.0.6129.0",
-          "revision": "version:121.0.6129.0"
+          "location": "lacros_version_skew_tests_v121.0.6130.0",
+          "revision": "version:121.0.6130.0"
         }
       ]
     }
diff --git a/ios/chrome/browser/autofill/BUILD.gn b/ios/chrome/browser/autofill/BUILD.gn
index a024ec6..a34ee33 100644
--- a/ios/chrome/browser/autofill/BUILD.gn
+++ b/ios/chrome/browser/autofill/BUILD.gn
@@ -156,7 +156,6 @@
     "autofill_controller_unittest.mm",
     "autofill_image_fetcher_impl_unittest.mm",
     "autofill_java_script_feature_unittest.mm",
-    "child_frame_registration_java_script_feature_unittest.mm",
     "form_input_accessory_view_handler_unittest.mm",
     "form_structure_browsertest.mm",
     "form_suggestion_controller_unittest.mm",
diff --git a/ios/chrome/browser/autofill/child_frame_registration_java_script_feature_unittest.mm b/ios/chrome/browser/autofill/child_frame_registration_java_script_feature_unittest.mm
deleted file mode 100644
index 3a6d874..0000000
--- a/ios/chrome/browser/autofill/child_frame_registration_java_script_feature_unittest.mm
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "components/autofill/ios/browser/child_frame_registration_java_script_feature.h"
-
-#import <Foundation/Foundation.h>
-
-#import "base/test/ios/wait_util.h"
-#import "base/test/scoped_feature_list.h"
-#import "components/autofill/core/common/autofill_constants.h"
-#import "components/autofill/core/common/autofill_features.h"
-#import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
-#import "ios/chrome/browser/web/model/chrome_web_client.h"
-#import "ios/web/public/js_messaging/web_frames_manager.h"
-#import "ios/web/public/test/js_test_util.h"
-#import "ios/web/public/test/scoped_testing_web_client.h"
-#import "ios/web/public/test/web_state_test_util.h"
-#import "ios/web/public/test/web_task_environment.h"
-#import "ios/web/public/web_state.h"
-#import "testing/gtest_mac.h"
-#import "testing/platform_test.h"
-
-namespace {
-
-using base::test::ios::kWaitForJSCompletionTimeout;
-using base::test::ios::WaitUntilConditionOrTimeout;
-
-// Text fixture to test ChildFrameRegistrationJavaScriptFeature.
-class ChildFrameRegistrationJavaScriptFeatureTest : public PlatformTest {
- protected:
-  ChildFrameRegistrationJavaScriptFeatureTest()
-      : web_client_(std::make_unique<ChromeWebClient>()) {
-    feature_list_.InitAndEnableFeature(
-        autofill::features::kAutofillAcrossIframesIos);
-
-    PlatformTest::SetUp();
-
-    browser_state_ = TestChromeBrowserState::Builder().Build();
-
-    web::WebState::CreateParams params(browser_state_.get());
-    web_state_ = web::WebState::Create(params);
-    web_state_->GetView();
-    web_state_->SetKeepRenderProcessAlive(true);
-  }
-
-  // Loads the given HTML and initializes the Autofill JS scripts.
-  void LoadHtml(NSString* html) {
-    web::test::LoadHtml(html, web_state());
-
-    __block web::WebFrame* main_frame = nullptr;
-    ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
-      main_frame = main_web_frame();
-      return main_frame != nullptr;
-    }));
-    ASSERT_TRUE(main_frame);
-  }
-
-  web::WebFrame* main_web_frame() {
-    web::WebFramesManager* frames_manager =
-        feature()->GetWebFramesManager(web_state());
-
-    return frames_manager->GetMainWebFrame();
-  }
-
-  autofill::ChildFrameRegistrationJavaScriptFeature* feature() {
-    return autofill::ChildFrameRegistrationJavaScriptFeature::GetInstance();
-  }
-
-  web::WebState* web_state() { return web_state_.get(); }
-
-  web::ScopedTestingWebClient web_client_;
-  web::WebTaskEnvironment task_environment_;
-  std::unique_ptr<TestChromeBrowserState> browser_state_;
-  std::unique_ptr<web::WebState> web_state_;
-
-  base::test::ScopedFeatureList feature_list_;
-};
-
-// Tests that the feature is created and injected, and that frame IDs are
-// successfully deserialized into {Local, Remote}FrameTokens.
-TEST_F(ChildFrameRegistrationJavaScriptFeatureTest, SmokeTest) {
-  LoadHtml(@"<body></body>");
-  ASSERT_TRUE(feature());
-
-  // Wait until something is in the map, and check that it's valid.
-  ASSERT_TRUE(WaitUntilConditionOrTimeout(kWaitForJSCompletionTimeout, ^bool {
-    return !feature()->lookup_map.empty();
-  }));
-  auto kv_pair = *feature()->lookup_map.begin();
-
-  // `first` is the LocalFrameToken, `second` is the RemoteFrameToken. Ensure
-  // neither is empty (i.e., uninitialized).
-  EXPECT_FALSE(kv_pair.first.is_empty());
-  EXPECT_FALSE(kv_pair.second.is_empty());
-}
-
-}  // namespace
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index 79035eb..ae127d04 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -1630,6 +1630,12 @@
      flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(
          autofill::features::kAutofillEnablePaymentsMandatoryReauth)},
+    {"autofill-enable-card-benefits",
+     flag_descriptions::kAutofillEnableCardBenefitsName,
+     flag_descriptions::kAutofillEnableCardBenefitsDescription,
+     flags_ui::kOsIos,
+     FEATURE_VALUE_TYPE(autofill::features::kAutofillEnableCardBenefits)},
+
 };
 
 bool SkipConditionalFeatureEntry(const flags_ui::FeatureEntry& entry) {
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index 0a91c2d..d7fa5185 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -50,6 +50,11 @@
     "When enabled, card product images (instead of network icons) will be "
     "shown in Payments Autofill UI.";
 
+const char kAutofillEnableCardBenefitsName[] = "Enable showing card benefits";
+const char kAutofillEnableCardBenefitsDescription[] =
+    "When enabled, card benefits offered by issuers will be shown in "
+    "Payments Autofill UI.";
+
 const char kAutofillEnableMerchantDomainInUnmaskCardRequestName[] =
     "Enable sending merchant domain in server card unmask requests";
 const char kAutofillEnableMerchantDomainInUnmaskCardRequestDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
index f2762e49..a2ddcb5 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -46,6 +46,11 @@
 extern const char kAutofillEnableCardArtImageName[];
 extern const char kAutofillEnableCardArtImageDescription[];
 
+// Title and description for the flag to enable card benefits for autofill
+// Payments UI.
+extern const char kAutofillEnableCardBenefitsName[];
+extern const char kAutofillEnableCardBenefitsDescription[];
+
 // Title and description for the flag to send merchant_domain as a top-level
 // parameter in card unmask requests.
 extern const char kAutofillEnableMerchantDomainInUnmaskCardRequestName[];
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
index eb10bc9..b3325ff 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_controller.mm
@@ -373,8 +373,6 @@
       leadingPadding += CGRectGetMinX(omniboxFrame);
     }
 
-    self.tableView.contentInset =
-        UIEdgeInsetsMakeDirected(0, leadingPadding, kBottomPadding, 0);
     self.tableView.directionalLayoutMargins =
         NSDirectionalEdgeInsetsMake(0, leadingPadding, kBottomPadding, 0);
   }
diff --git a/ios/chrome/browser/web/chrome_web_client.mm b/ios/chrome/browser/web/chrome_web_client.mm
index 39b346e5..d8491a4 100644
--- a/ios/chrome/browser/web/chrome_web_client.mm
+++ b/ios/chrome/browser/web/chrome_web_client.mm
@@ -14,9 +14,7 @@
 #import "base/no_destructor.h"
 #import "base/strings/stringprintf.h"
 #import "base/strings/sys_string_conversions.h"
-#import "components/autofill/core/common/autofill_features.cc"
 #import "components/autofill/ios/browser/autofill_java_script_feature.h"
-#import "components/autofill/ios/browser/child_frame_registration_java_script_feature.h"
 #import "components/autofill/ios/browser/suggestion_controller_java_script_feature.h"
 #import "components/autofill/ios/form_util/form_handlers_java_script_feature.h"
 #import "components/dom_distiller/core/url_constants.h"
@@ -346,11 +344,6 @@
   features.push_back(
       autofill::SuggestionControllerJavaScriptFeature::GetInstance());
   features.push_back(AutofillBottomSheetJavaScriptFeature::GetInstance());
-  if (base::FeatureList::IsEnabled(
-          autofill::features::kAutofillAcrossIframesIos)) {
-    features.push_back(
-        autofill::ChildFrameRegistrationJavaScriptFeature::GetInstance());
-  }
   features.push_back(FontSizeJavaScriptFeature::GetInstance());
   features.push_back(ImageFetchJavaScriptFeature::GetInstance());
   features.push_back(
diff --git a/ios/web/js_messaging/web_frame_impl.mm b/ios/web/js_messaging/web_frame_impl.mm
index 68b671b5..bae77f6d 100644
--- a/ios/web/js_messaging/web_frame_impl.mm
+++ b/ios/web/js_messaging/web_frame_impl.mm
@@ -50,7 +50,7 @@
                            GURL security_origin,
                            web::WebState* web_state)
     : frame_info_(frame_info),
-      frame_id_(frame_id),
+      frame_id_(base::ToLowerASCII(frame_id)),
       is_main_frame_(is_main_frame),
       security_origin_(security_origin),
       web_state_(web_state) {
diff --git a/ios/web/js_messaging/web_frames_manager_impl.mm b/ios/web/js_messaging/web_frames_manager_impl.mm
index 9fe2217..6b8fc01 100644
--- a/ios/web/js_messaging/web_frames_manager_impl.mm
+++ b/ios/web/js_messaging/web_frames_manager_impl.mm
@@ -100,7 +100,8 @@
   if (frame_id.empty()) {
     return nullptr;
   }
-  auto web_frames_it = web_frames_.find(frame_id);
+
+  auto web_frames_it = web_frames_.find(base::ToLowerASCII(frame_id));
   return web_frames_it == web_frames_.end() ? nullptr
                                             : web_frames_it->second.get();
 }
diff --git a/ios/web/js_messaging/web_frames_manager_impl_unittest.mm b/ios/web/js_messaging/web_frames_manager_impl_unittest.mm
index 074d025..ad7d7563 100644
--- a/ios/web/js_messaging/web_frames_manager_impl_unittest.mm
+++ b/ios/web/js_messaging/web_frames_manager_impl_unittest.mm
@@ -16,6 +16,9 @@
 
 namespace {
 
+const std::string kLowercaseFrameId = "abba1234beef1234cafe1234deed1234";
+const std::string kUppercaseFrameId = "ABBA1234BEEF1234CAFE1234DEED1234";
+
 class FakeWebFramesManagerObserver : public WebFramesManagerImpl::Observer {
  public:
   // The current available frames as tracked by the WebFramesManage Observer
@@ -218,4 +221,39 @@
   EXPECT_EQ(main_frame, observed_main_frame);
 }
 
+// Tests that frame lookup is not case-sensitive.
+TEST_F(WebFramesManagerImplTest, CaseInsensitiveLookup) {
+  auto frame = FakeWebFrame::Create(kLowercaseFrameId,
+                                    /*is_main_frame=*/true,
+                                    GURL("https://www.main.test"));
+  SendFrameBecameAvailableMessage(std::move(frame));
+
+  EXPECT_EQ(1ul, GetPageWorldWebFramesManager().GetAllWebFrames().size());
+
+  WebFrame* frame_by_uppercase_id =
+      GetPageWorldWebFramesManager().GetFrameWithId(kUppercaseFrameId);
+  EXPECT_TRUE(frame_by_uppercase_id);
+
+  WebFrame* frame_by_lowercase_id =
+      GetPageWorldWebFramesManager().GetFrameWithId(kLowercaseFrameId);
+  EXPECT_TRUE(frame_by_lowercase_id);
+
+  EXPECT_EQ(frame_by_uppercase_id, frame_by_lowercase_id);
+}
+
+// By convention, the frame ID should be stored in lowercase internally, even if
+// it was passed as uppercase at construct-time.
+TEST_F(WebFramesManagerImplTest, CaseInsensitiveConstruct) {
+  auto frame_with_uppercase_id = FakeWebFrame::Create(
+      kUppercaseFrameId, /*is_main_frame=*/true, GURL("https://www.main.test"));
+
+  SendFrameBecameAvailableMessage(std::move(frame_with_uppercase_id));
+
+  WebFrame* frame_by_lowercase_id =
+      GetPageWorldWebFramesManager().GetFrameWithId(kLowercaseFrameId);
+  ASSERT_TRUE(frame_by_lowercase_id);
+
+  EXPECT_EQ(frame_by_lowercase_id->GetFrameId(), kLowercaseFrameId);
+}
+
 }  // namespace web
diff --git a/ios/web/test/fakes/fake_web_frame_impl.mm b/ios/web/test/fakes/fake_web_frame_impl.mm
index cc00e63..08971f0 100644
--- a/ios/web/test/fakes/fake_web_frame_impl.mm
+++ b/ios/web/test/fakes/fake_web_frame_impl.mm
@@ -10,6 +10,7 @@
 #import "base/functional/bind.h"
 #import "base/functional/callback.h"
 #import "base/json/json_writer.h"
+#import "base/strings/string_util.h"
 #import "base/strings/utf_string_conversions.h"
 #import "base/values.h"
 #import "ios/web/public/thread/web_task_traits.h"
@@ -48,7 +49,7 @@
 FakeWebFrameImpl::FakeWebFrameImpl(const std::string& frame_id,
                                    bool is_main_frame,
                                    GURL security_origin)
-    : frame_id_(frame_id),
+    : frame_id_(base::ToLowerASCII(frame_id)),
       is_main_frame_(is_main_frame),
       security_origin_(security_origin) {}
 
diff --git a/ios_internal b/ios_internal
index 7dd4f69..26f33f9 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit 7dd4f693cac89c32dd5001e682b2f6e9e3efcee5
+Subproject commit 26f33f95250902dbd2a39dba186ac5998d41dbf1
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
index b34788f..140dd66 100644
--- a/media/base/media_switches.cc
+++ b/media/base/media_switches.cc
@@ -424,13 +424,6 @@
              "UseDecoderStreamForWebRTC",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// If enabled, element capture will be performed instead of region capture. Used
-// for testing until the restrictTo API is finished.
-// TODO(https://crbug.com/1473342): remove once restrictTo API is in place.
-BASE_FEATURE(kUseElementInsteadOfRegionCapture,
-             "UseElementInsteadOfRegionCapture",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
 // If enabled, when RTCVideoDecoderAdapter is used then SW decoders will be
 // exposed directly to WebRTC.
 BASE_FEATURE(kExposeSwDecodersToWebRTC,
diff --git a/media/base/media_switches.h b/media/base/media_switches.h
index febb7b5..e24524b5 100644
--- a/media/base/media_switches.h
+++ b/media/base/media_switches.h
@@ -319,7 +319,6 @@
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kUnifiedAutoplay);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseAndroidOverlayForSecureOnly);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseDecoderStreamForWebRTC);
-MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseElementInsteadOfRegionCapture);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseFakeDeviceForMediaStream);
 MEDIA_EXPORT BASE_DECLARE_FEATURE(kUseMediaHistoryStore);
 #if BUILDFLAG(IS_LINUX)
diff --git a/media/filters/demuxer_perftest.cc b/media/filters/demuxer_perftest.cc
index 70274b8..7240043 100644
--- a/media/filters/demuxer_perftest.cc
+++ b/media/filters/demuxer_perftest.cc
@@ -6,15 +6,13 @@
 #include <stdint.h>
 #include <memory>
 
-#include "base/at_exit.h"
 #include "base/functional/bind.h"
 #include "base/run_loop.h"
-#include "base/strings/string_number_conversions.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/test/task_environment.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
-#include "media/base/media.h"
+#include "media/base/decoder_buffer.h"
 #include "media/base/media_tracks.h"
 #include "media/base/media_util.h"
 #include "media/base/test_data_util.h"
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
index dc705534..25b4fbc 100644
--- a/media/filters/ffmpeg_demuxer.cc
+++ b/media/filters/ffmpeg_demuxer.cc
@@ -927,6 +927,9 @@
   // there are no outstanding WeakPtrs by the time we reach here.
   DCHECK(!weak_factory_.HasWeakPtrs());
 
+  // Clear `streams_` before `glue_` below since they may reference it.
+  streams_.clear();
+
   // There may be outstanding tasks in the blocking pool which are trying to use
   // these members, so release them in sequence with any outstanding calls. The
   // earlier call to Abort() on |data_source_| prevents further access to it.
diff --git a/media/filters/ffmpeg_demuxer.h b/media/filters/ffmpeg_demuxer.h
index 3173497..7238916d 100644
--- a/media/filters/ffmpeg_demuxer.h
+++ b/media/filters/ffmpeg_demuxer.h
@@ -27,16 +27,15 @@
 
 #include <memory>
 #include <string>
-#include <utility>
 #include <vector>
 
+#include "base/containers/flat_map.h"
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
 #include "media/base/audio_decoder_config.h"
-#include "media/base/decoder_buffer.h"
 #include "media/base/decoder_buffer_queue.h"
 #include "media/base/demuxer.h"
 #include "media/base/media_log.h"
@@ -409,7 +408,8 @@
 
   const MediaTracksUpdatedCB media_tracks_updated_cb_;
 
-  std::map<MediaTrack::Id, FFmpegDemuxerStream*> track_id_to_demux_stream_map_;
+  base::flat_map<MediaTrack::Id, FFmpegDemuxerStream*>
+      track_id_to_demux_stream_map_;
 
   const bool is_local_file_;
 
diff --git a/net/base/features.cc b/net/base/features.cc
index 56fdc046..ea57851 100644
--- a/net/base/features.cc
+++ b/net/base/features.cc
@@ -95,10 +95,9 @@
              "EncryptedClientHelloQuic",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
-// TODO(crbug.com/795089): Enable this feature.
 BASE_FEATURE(kRSAKeyUsageForLocalAnchors,
              "RSAKeyUsageForLocalAnchors",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 BASE_FEATURE(kNetworkQualityEstimator,
              "NetworkQualityEstimator",
diff --git a/net/proxy_resolution/proxy_list.cc b/net/proxy_resolution/proxy_list.cc
index f299819..a9c6f06 100644
--- a/net/proxy_resolution/proxy_list.cc
+++ b/net/proxy_resolution/proxy_list.cc
@@ -33,15 +33,7 @@
 
 ProxyList& ProxyList::operator=(ProxyList&& other) = default;
 
-ProxyList::~ProxyList() {
-#if DCHECK_IS_ON()
-  // Validate that the result of `UpdateProxyServers()` is equivalent to the
-  // incremental updates made in other methods.
-  auto proxy_servers = std::move(proxy_servers_);
-  UpdateProxyServers();
-  CHECK(proxy_servers == proxy_servers_);
-#endif
-}
+ProxyList::~ProxyList() = default;
 
 void ProxyList::Set(const std::string& proxy_uri_list) {
   Clear();
@@ -66,11 +58,6 @@
 void ProxyList::AddProxyChain(const ProxyChain& proxy_chain) {
   // Silently discard malformed inputs.
   if (proxy_chain.IsValid()) {
-    if (!proxy_chain.is_multi_proxy() && proxy_servers_.has_value()) {
-      proxy_servers_->push_back(proxy_chain.proxy_server());
-    } else {
-      proxy_servers_ = absl::nullopt;
-    }
     proxy_chains_.push_back(proxy_chain);
   }
 }
@@ -107,8 +94,6 @@
   proxy_chains_.swap(good_chains);
   proxy_chains_.insert(proxy_chains_.end(), bad_chains_to_try.begin(),
                        bad_chains_to_try.end());
-
-  UpdateProxyServers();
 }
 
 void ProxyList::RemoveProxiesWithoutScheme(int scheme_bit_field) {
@@ -121,13 +106,10 @@
                          return !(scheme_bit_field & server.scheme());
                        });
   });
-
-  UpdateProxyServers();
 }
 
 void ProxyList::Clear() {
   proxy_chains_.clear();
-  UpdateProxyServers();
 }
 
 bool ProxyList::IsEmpty() const {
@@ -142,13 +124,13 @@
 bool ProxyList::Equals(const ProxyList& other) const {
   if (size() != other.size())
     return false;
-  // `proxy_servers_` is just a cache, so is not part of the comparison.
   return proxy_chains_ == other.proxy_chains_;
 }
 
 const ProxyServer& ProxyList::Get() const {
   CHECK(!proxy_chains_.empty());
-  return proxy_servers_->front();
+  const auto& proxy_chain = First();
+  return proxy_chain.proxy_server();
 }
 
 const ProxyChain& ProxyList::First() const {
@@ -156,10 +138,12 @@
   return proxy_chains_[0];
 }
 
-const std::vector<ProxyServer>& ProxyList::GetAll() const {
-  CHECK(proxy_servers_.has_value())
-      << "ProxyList contains multi-proxy ProxyChains";
-  return *proxy_servers_;
+std::vector<ProxyServer> ProxyList::GetAll() const {
+  std::vector<ProxyServer> proxy_servers;
+  for (const auto& proxy_chain : AllChains()) {
+    proxy_servers.push_back(proxy_chain.proxy_server());
+  }
+  return proxy_servers;
 }
 
 const std::vector<ProxyChain>& ProxyList::AllChains() const {
@@ -183,8 +167,6 @@
   if (proxy_chains_.empty()) {
     proxy_chains_.push_back(ProxyChain::Direct());
   }
-
-  UpdateProxyServers();
 }
 
 std::string ProxyList::ToPacString() const {
@@ -229,7 +211,6 @@
 
   // Remove this proxy from our list.
   proxy_chains_.erase(proxy_chains_.begin());
-  UpdateProxyServers();
   return !proxy_chains_.empty();
 }
 
@@ -286,21 +267,4 @@
   }
 }
 
-void ProxyList::UpdateProxyServers() {
-  if (proxy_chains_.empty()) {
-    proxy_servers_ = std::vector<ProxyServer>();
-    return;
-  }
-
-  std::vector<ProxyServer> proxy_servers;
-  for (auto& it : proxy_chains_) {
-    if (it.is_multi_proxy()) {
-      proxy_servers_.reset();
-      return;
-    }
-    proxy_servers.push_back(it.proxy_server());
-  }
-  proxy_servers_ = std::move(proxy_servers);
-}
-
 }  // namespace net
diff --git a/net/proxy_resolution/proxy_list.h b/net/proxy_resolution/proxy_list.h
index 1c4c554..bca422b 100644
--- a/net/proxy_resolution/proxy_list.h
+++ b/net/proxy_resolution/proxy_list.h
@@ -92,7 +92,7 @@
   // Returns all proxy servers in the list. It is only valid to call this
   // if no chain in the list is multi-proxy.
   // TODO(crbug.com/1491092): Remove this method in favor of `AllChains()`.
-  const std::vector<ProxyServer>& GetAll() const;
+  std::vector<ProxyServer> GetAll() const;
 
   // Returns all proxy chains in the list.
   const std::vector<ProxyChain>& AllChains() const;
@@ -152,17 +152,8 @@
                                 int net_error,
                                 const NetLogWithSource& net_log) const;
 
-  // Update `proxy_servers_` based on `proxy_chains_`.
-  void UpdateProxyServers();
-
   // List of proxy chains.
   std::vector<ProxyChain> proxy_chains_;
-
-  // List of ProxyServers, or nullopt if any chains in `proxy_chains_` are
-  // multi-proxy. This is kept in sync with `proxy_chains_`. This begins as an
-  // empty vector and becomes `nullopt` when a multi-proxy chain is added.
-  absl::optional<std::vector<ProxyServer>> proxy_servers_ =
-      std::vector<ProxyServer>();
 };
 
 }  // namespace net
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index 047ea83..8a215ea 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -1156,8 +1156,6 @@
     return HandleVerifyResult();
   }
 
-  start_cert_verification_time_ = base::TimeTicks::Now();
-
   base::StringPiece ech_name_override = GetECHNameOverride();
   if (!ech_name_override.empty()) {
     // If ECH was offered but not negotiated, BoringSSL will ask to verify a
@@ -1236,16 +1234,6 @@
 
   cert_verifier_request_.reset();
 
-  if (!start_cert_verification_time_.is_null()) {
-    base::TimeDelta verify_time =
-        base::TimeTicks::Now() - start_cert_verification_time_;
-    if (result == OK) {
-      UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTime", verify_time);
-    } else {
-      UMA_HISTOGRAM_TIMES("Net.SSLCertVerificationTimeError", verify_time);
-    }
-  }
-
   // Enforce keyUsage extension for RSA leaf certificates chaining up to known
   // roots unconditionally. Enforcement for local anchors is, for now,
   // conditional on feature flags and external configuration. See
diff --git a/net/socket/ssl_client_socket_impl.h b/net/socket/ssl_client_socket_impl.h
index fc74870..43fb3c0 100644
--- a/net/socket/ssl_client_socket_impl.h
+++ b/net/socket/ssl_client_socket_impl.h
@@ -17,7 +17,6 @@
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
-#include "base/time/time.h"
 #include "net/base/completion_once_callback.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/io_buffer.h"
@@ -255,7 +254,6 @@
   const raw_ptr<SSLClientContext> context_;
 
   std::unique_ptr<CertVerifier::Request> cert_verifier_request_;
-  base::TimeTicks start_cert_verification_time_;
 
   // Result from Cert Verifier.
   int cert_verification_result_;
diff --git a/sandbox/policy/mac/gpu.sb b/sandbox/policy/mac/gpu.sb
index 27d7574a..34f5f16 100644
--- a/sandbox/policy/mac/gpu.sb
+++ b/sandbox/policy/mac/gpu.sb
@@ -4,9 +4,6 @@
 
 ; --- The contents of common.sb implicitly included here. ---
 
-(deny default (with partial-symbolication))
-(debug deny)
-
 ; Allow cf prefs to work.
 (allow user-preference-read)
 
diff --git a/services/accessibility/features/automation_internal_bindings.cc b/services/accessibility/features/automation_internal_bindings.cc
index b16296a..a56dad1 100644
--- a/services/accessibility/features/automation_internal_bindings.cc
+++ b/services/accessibility/features/automation_internal_bindings.cc
@@ -190,22 +190,4 @@
   // automation_client_remote_->PerformAction(action_data);
 }
 
-void AutomationInternalBindings::DispatchAccessibilityEvents(
-    const ui::AXTreeID& tree_id,
-    const std::vector<ui::AXTreeUpdate>& updates,
-    const gfx::Point& mouse_location,
-    const std::vector<ui::AXEvent>& events) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  OnAccessibilityEvents(tree_id, events, updates, mouse_location,
-                        /*is_active_profile=*/true);
-}
-
-void AutomationInternalBindings::DispatchAccessibilityLocationChange(
-    const ui::AXTreeID& tree_id,
-    int node_id,
-    const ui::AXRelativeBounds& bounds) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  OnAccessibilityLocationChange(tree_id, node_id, bounds);
-}
-
 }  // namespace ax
diff --git a/services/accessibility/features/automation_internal_bindings.h b/services/accessibility/features/automation_internal_bindings.h
index f7732cc..8aafd4b0 100644
--- a/services/accessibility/features/automation_internal_bindings.h
+++ b/services/accessibility/features/automation_internal_bindings.h
@@ -98,18 +98,6 @@
  private:
   friend class AutomationInternalBindingsTest;
 
-  // TODO(crbug.com/1355633): Remove these and implement them in
-  // ui::AutomationTreeManagerOwner:
-  void DispatchAccessibilityEvents(
-      const ui::AXTreeID& tree_id,
-      const std::vector<ui::AXTreeUpdate>& updates,
-      const gfx::Point& mouse_location,
-      const std::vector<ui::AXEvent>& events) override;
-  void DispatchAccessibilityLocationChange(
-      const ui::AXTreeID& tree_id,
-      int node_id,
-      const ui::AXRelativeBounds& bounds) override;
-
   // Used during object template creation.
   raw_ptr<v8::Local<v8::ObjectTemplate>, ExperimentalAsh> template_;
 
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 0b8d8dcf..dfa20c31 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -6093,9 +6093,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6129.0",
+        "description": "Run with ash-chrome version 121.0.6130.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -6105,8 +6105,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6129.0",
-              "revision": "version:121.0.6129.0"
+              "location": "lacros_version_skew_tests_v121.0.6130.0",
+              "revision": "version:121.0.6130.0"
             }
           ],
           "dimensions": {
@@ -6243,9 +6243,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6129.0",
+        "description": "Run with ash-chrome version 121.0.6130.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -6255,8 +6255,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6129.0",
-              "revision": "version:121.0.6129.0"
+              "location": "lacros_version_skew_tests_v121.0.6130.0",
+              "revision": "version:121.0.6130.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json
index 98a19672..0d3f07e2f 100644
--- a/testing/buildbot/chromium.coverage.json
+++ b/testing/buildbot/chromium.coverage.json
@@ -20442,9 +20442,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6129.0",
+        "description": "Run with ash-chrome version 121.0.6130.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -20454,8 +20454,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6129.0",
-              "revision": "version:121.0.6129.0"
+              "location": "lacros_version_skew_tests_v121.0.6130.0",
+              "revision": "version:121.0.6130.0"
             }
           ],
           "dimensions": {
@@ -20592,9 +20592,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6129.0",
+        "description": "Run with ash-chrome version 121.0.6130.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -20604,8 +20604,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6129.0",
-              "revision": "version:121.0.6129.0"
+              "location": "lacros_version_skew_tests_v121.0.6130.0",
+              "revision": "version:121.0.6130.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 5fa477c4..ba8c8ddc 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -43585,9 +43585,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6129.0",
+        "description": "Run with ash-chrome version 121.0.6130.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43596,8 +43596,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6129.0",
-              "revision": "version:121.0.6129.0"
+              "location": "lacros_version_skew_tests_v121.0.6130.0",
+              "revision": "version:121.0.6130.0"
             }
           ],
           "dimensions": {
@@ -43735,9 +43735,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6129.0",
+        "description": "Run with ash-chrome version 121.0.6130.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43746,8 +43746,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6129.0",
-              "revision": "version:121.0.6129.0"
+              "location": "lacros_version_skew_tests_v121.0.6130.0",
+              "revision": "version:121.0.6130.0"
             }
           ],
           "dimensions": {
@@ -45044,9 +45044,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6129.0",
+        "description": "Run with ash-chrome version 121.0.6130.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -45055,8 +45055,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6129.0",
-              "revision": "version:121.0.6129.0"
+              "location": "lacros_version_skew_tests_v121.0.6130.0",
+              "revision": "version:121.0.6130.0"
             }
           ],
           "dimensions": {
@@ -45194,9 +45194,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6129.0",
+        "description": "Run with ash-chrome version 121.0.6130.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -45205,8 +45205,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6129.0",
-              "revision": "version:121.0.6129.0"
+              "location": "lacros_version_skew_tests_v121.0.6130.0",
+              "revision": "version:121.0.6130.0"
             }
           ],
           "dimensions": {
@@ -45889,9 +45889,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 121.0.6129.0",
+        "description": "Run with ash-chrome version 121.0.6130.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -45900,8 +45900,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6129.0",
-              "revision": "version:121.0.6129.0"
+              "location": "lacros_version_skew_tests_v121.0.6130.0",
+              "revision": "version:121.0.6130.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 4880fa9..a99ae0f 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -16151,12 +16151,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 121.0.6129.0",
+        "description": "Run with ash-chrome version 121.0.6130.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -16166,8 +16166,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6129.0",
-              "revision": "version:121.0.6129.0"
+              "location": "lacros_version_skew_tests_v121.0.6130.0",
+              "revision": "version:121.0.6130.0"
             }
           ],
           "dimensions": {
@@ -16321,12 +16321,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter;../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 121.0.6129.0",
+        "description": "Run with ash-chrome version 121.0.6130.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -16336,8 +16336,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v121.0.6129.0",
-              "revision": "version:121.0.6129.0"
+              "location": "lacros_version_skew_tests_v121.0.6130.0",
+              "revision": "version:121.0.6130.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 564338ca..4e0180e0 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -70,16 +70,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'identifier': 'Lacros version skew testing ash canary',
-    'description': 'Run with ash-chrome version 121.0.6129.0',
+    'description': 'Run with ash-chrome version 121.0.6130.0',
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6129.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v121.0.6130.0/test_ash_chrome',
     ],
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v121.0.6129.0',
-          'revision': 'version:121.0.6129.0',
+          'location': 'lacros_version_skew_tests_v121.0.6130.0',
+          'revision': 'version:121.0.6130.0',
         },
       ],
     },
diff --git a/testing/flake_suppressor_common/expectations.py b/testing/flake_suppressor_common/expectations.py
index 18a27f1f..de6ec36 100644
--- a/testing/flake_suppressor_common/expectations.py
+++ b/testing/flake_suppressor_common/expectations.py
@@ -5,7 +5,6 @@
 
 import base64
 import collections
-import datetime
 from datetime import timedelta
 import os
 import posixpath
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 626aab22..af16363 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -4855,29 +4855,6 @@
             ]
         }
     ],
-    "CssPaintingForSpellingGrammarErrors": [
-        {
-            "platforms": [
-                "android",
-                "android_webview",
-                "chromeos",
-                "chromeos_lacros",
-                "fuchsia",
-                "ios",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Disabled_EmergencyKillSwitch",
-                    "disable_features": [
-                        "CssPaintingForSpellingGrammarErrors"
-                    ]
-                }
-            ]
-        }
-    ],
     "CursiveManagedStylusPreinstall": [
         {
             "platforms": [
@@ -7765,6 +7742,27 @@
             ]
         }
     ],
+    "HappinessTrackingBluetoothAudio": [
+        {
+            "platforms": [
+                "chromeos"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled_20231030",
+                    "params": {
+                        "prob": "0.05",
+                        "survey_cycle_length": "7",
+                        "survey_start_date_ms": "1698332400000",
+                        "trigger_id": "9ymFQS2qm0jBnuKU19R0UaKeWPaL"
+                    },
+                    "enable_features": [
+                        "HappinessTrackingBluetoothAudio"
+                    ]
+                }
+            ]
+        }
+    ],
     "HappinessTrackingBorealisGames": [
         {
             "platforms": [
@@ -11865,6 +11863,27 @@
             ]
         }
     ],
+    "OnePassRasterInvalidation": [
+        {
+            "platforms": [
+                "android",
+                "android_webview",
+                "chromeos",
+                "chromeos_lacros",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "OnePassRasterInvalidation"
+                    ]
+                }
+            ]
+        }
+    ],
     "OneTimePermission": [
         {
             "platforms": [
@@ -14186,27 +14205,6 @@
             ]
         }
     ],
-    "RSAKeyUsageForLocalAnchors": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "chromeos_lacros",
-                "ios",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "RSAKeyUsageForLocalAnchors"
-                    ]
-                }
-            ]
-        }
-    ],
     "RawDrawAndDrDc": [
         {
             "platforms": [
@@ -17952,6 +17950,26 @@
             ]
         }
     ],
+    "SuspiciousSiteDetectionRTLookups": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "chromeos_lacros",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "SuspiciousSiteDetectionRTLookups"
+                    ]
+                }
+            ]
+        }
+    ],
     "SyncAndroidLimitNTPPromoImpressions": [
         {
             "platforms": [
diff --git a/third_party/angle b/third_party/angle
index eb6d1a8..c5eb810 160000
--- a/third_party/angle
+++ b/third_party/angle
@@ -1 +1 @@
-Subproject commit eb6d1a82313c5852999968d6d678d7c04c6cf8c4
+Subproject commit c5eb810b941fff42bd4d1a8c884bf33e733b4626
diff --git a/third_party/blink/common/user_agent/user_agent_metadata.cc b/third_party/blink/common/user_agent/user_agent_metadata.cc
index 04889e14b..d327adda 100644
--- a/third_party/blink/common/user_agent/user_agent_metadata.cc
+++ b/third_party/blink/common/user_agent/user_agent_metadata.cc
@@ -2,8 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <algorithm>
+
 #include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
 
+#include "base/containers/contains.h"
 #include "base/pickle.h"
 #include "net/http/structured_headers.h"
 #include "third_party/blink/public/common/features.h"
@@ -11,7 +14,7 @@
 namespace blink {
 
 namespace {
-constexpr uint32_t kVersion = 2u;
+constexpr uint32_t kVersion = 3u;
 }  // namespace
 
 UserAgentBrandVersion::UserAgentBrandVersion(const std::string& ua_brand,
@@ -50,21 +53,32 @@
   return SerializeBrandVersionList(brand_version_list);
 }
 
+const std::string UserAgentMetadata::SerializeFormFactor() {
+  net::structured_headers::List structured;
+  for (auto& ff : form_factor) {
+    structured.push_back(net::structured_headers::ParameterizedMember(
+        net::structured_headers::Item(ff), {}));
+  }
+  return SerializeList(structured).value_or("");
+}
+
 // static
 absl::optional<std::string> UserAgentMetadata::Marshal(
     const absl::optional<UserAgentMetadata>& in) {
-  if (!in)
+  if (!in) {
     return absl::nullopt;
+  }
   base::Pickle out;
   out.WriteUInt32(kVersion);
 
-  out.WriteUInt32(in->brand_version_list.size());
+  out.WriteUInt32(base::checked_cast<uint32_t>(in->brand_version_list.size()));
   for (const auto& brand_version : in->brand_version_list) {
     out.WriteString(brand_version.brand);
     out.WriteString(brand_version.version);
   }
 
-  out.WriteUInt32(in->brand_full_version_list.size());
+  out.WriteUInt32(
+      base::checked_cast<uint32_t>(in->brand_full_version_list.size()));
   for (const auto& brand_version : in->brand_full_version_list) {
     out.WriteString(brand_version.brand);
     out.WriteString(brand_version.version);
@@ -78,7 +92,11 @@
   out.WriteBool(in->mobile);
   out.WriteString(in->bitness);
   out.WriteBool(in->wow64);
-  out.WriteString(in->form_factor);
+
+  out.WriteUInt32(base::checked_cast<uint32_t>(in->form_factor.size()));
+  for (const auto& form_factor : in->form_factor) {
+    out.WriteString(form_factor);
+  }
   return std::string(reinterpret_cast<const char*>(out.data()), out.size());
 }
 
@@ -136,9 +154,18 @@
     return absl::nullopt;
   if (!in.ReadBool(&out.wow64))
     return absl::nullopt;
-  if (!in.ReadString(&out.form_factor)) {
+  uint32_t form_factor_size;
+  if (!in.ReadUInt32(&form_factor_size)) {
     return absl::nullopt;
   }
+  std::string form_factor;
+  form_factor.reserve(form_factor_size);
+  for (uint32_t i = 0; i < form_factor_size; i++) {
+    if (!in.ReadString(&form_factor)) {
+      return absl::nullopt;
+    }
+    out.form_factor.push_back(std::move(form_factor));
+  }
   return absl::make_optional(std::move(out));
 }
 
diff --git a/third_party/blink/common/user_agent/user_agent_metadata_unittest.cc b/third_party/blink/common/user_agent/user_agent_metadata_unittest.cc
index 6f1d5595..94ba759b 100644
--- a/third_party/blink/common/user_agent/user_agent_metadata_unittest.cc
+++ b/third_party/blink/common/user_agent/user_agent_metadata_unittest.cc
@@ -28,7 +28,7 @@
   to_encode.mobile = false;
   to_encode.bitness = "8";
   to_encode.wow64 = true;
-  to_encode.form_factor = "tubular";
+  to_encode.form_factor = {"tubular"};
   return to_encode;
 }
 
@@ -45,12 +45,42 @@
   blink::UserAgentMetadata to_encode = MakeToEncode();
   EXPECT_EQ(to_encode, UserAgentMetadata::Demarshal(
                            UserAgentMetadata::Marshal(to_encode)));
+}
 
+TEST(UserAgentMetaDataTest, Mobile) {
+  blink::UserAgentMetadata to_encode = MakeToEncode();
   to_encode.mobile = true;
   EXPECT_EQ(to_encode, UserAgentMetadata::Demarshal(
                            UserAgentMetadata::Marshal(to_encode)));
 }
 
+TEST(UserAgentMetaDataTest, EmptyFormFactor) {
+  blink::UserAgentMetadata to_encode = MakeToEncode();
+  to_encode.form_factor = {};
+  EXPECT_EQ(to_encode, UserAgentMetadata::Demarshal(
+                           UserAgentMetadata::Marshal(to_encode)));
+}
+
+TEST(UserAgentMetaDataTest, MultiFormFactor) {
+  blink::UserAgentMetadata to_encode = MakeToEncode();
+  to_encode.form_factor = {"a", "b"};
+  EXPECT_EQ(to_encode, UserAgentMetadata::Demarshal(
+                           UserAgentMetadata::Marshal(to_encode)));
+}
+
+TEST(UserAgentMetaDataTest, SerializeFormFactor) {
+  UserAgentMetadata uam;
+
+  uam.form_factor = {};
+  ASSERT_EQ(uam.SerializeFormFactor(), "") << "empty";
+
+  uam.form_factor = {"Desktop"};
+  ASSERT_EQ(uam.SerializeFormFactor(), "\"Desktop\"") << "empty";
+
+  uam.form_factor = {"Desktop", "Tablet"};
+  ASSERT_EQ(uam.SerializeFormFactor(), "\"Desktop\", \"Tablet\"") << "empty";
+}
+
 TEST(UserAgentMetaDataTest, MojoTraits) {
   blink::UserAgentMetadata to_encode = MakeToEncode();
   blink::UserAgentMetadata copied;
diff --git a/third_party/blink/common/user_agent/user_agent_mojom_traits.cc b/third_party/blink/common/user_agent/user_agent_mojom_traits.cc
index 47579423..55ba560 100644
--- a/third_party/blink/common/user_agent/user_agent_mojom_traits.cc
+++ b/third_party/blink/common/user_agent/user_agent_mojom_traits.cc
@@ -63,10 +63,9 @@
   out->bitness = string;
   out->wow64 = data.wow64();
 
-  if (!data.ReadFormFactor(&string)) {
+  if (!data.ReadFormFactor(&out->form_factor)) {
     return false;
   }
-  out->form_factor = string;
 
   return true;
 }
diff --git a/third_party/blink/public/common/user_agent/user_agent_metadata.h b/third_party/blink/public/common/user_agent/user_agent_metadata.h
index 5cac56de..d610939 100644
--- a/third_party/blink/public/common/user_agent/user_agent_metadata.h
+++ b/third_party/blink/public/common/user_agent/user_agent_metadata.h
@@ -13,6 +13,18 @@
 
 namespace blink {
 
+// Values for the Sec-CH-UA-Form-Factor header.
+// https://wicg.github.io/ua-client-hints/#sec-ch-ua-form-factor
+// LINT.IfChange
+inline constexpr char kDesktopFormFactor[] = "Desktop";
+inline constexpr char kAutomotiveFormFactor[] = "Automotive";
+inline constexpr char kMobileFormFactor[] = "Mobile";
+inline constexpr char kTabletFormFactor[] = "Tablet";
+inline constexpr char kXRFormFactor[] = "XR";
+inline constexpr char kEInkFormFactor[] = "EInk";
+inline constexpr char kWatchFormFactor[] = "Watch";
+// LINT.ThenChange(/android_webview/java/src/org/chromium/android_webview/client_hints/AwUserAgentMetadata.java)
+
 struct BLINK_COMMON_EXPORT UserAgentBrandVersion {
   UserAgentBrandVersion() = default;
   UserAgentBrandVersion(const std::string& ua_brand,
@@ -44,6 +56,7 @@
   // version.
   const std::string SerializeBrandFullVersionList();
   const std::string SerializeBrandMajorVersionList();
+  const std::string SerializeFormFactor();
 
   static absl::optional<UserAgentMetadata> Demarshal(
       const absl::optional<std::string>& encoded);
@@ -60,7 +73,11 @@
   bool mobile = false;
   std::string bitness;
   bool wow64 = false;
-  std::string form_factor;
+
+  // The form-factor list. It is up to the embedder to ensure that this is
+  // compliant with the w3c draft spec:
+  // https://wicg.github.io/ua-client-hints/#sec-ch-ua-form-factor.
+  std::vector<std::string> form_factor;
 };
 
 // Used when customizing the sent User-Agent and Sec-CH-UA-* for
diff --git a/third_party/blink/public/common/user_agent/user_agent_mojom_traits.h b/third_party/blink/public/common/user_agent/user_agent_mojom_traits.h
index 1b42956..96848381 100644
--- a/third_party/blink/public/common/user_agent/user_agent_mojom_traits.h
+++ b/third_party/blink/public/common/user_agent/user_agent_mojom_traits.h
@@ -76,7 +76,7 @@
     return data.wow64;
   }
 
-  static const std::string& form_factor(
+  static const std::vector<std::string>& form_factor(
       const ::blink::UserAgentMetadata& data) {
     return data.form_factor;
   }
diff --git a/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom b/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
index 65f379f..3652bed 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/css_property_id.mojom
@@ -821,7 +821,7 @@
     kPositionFallbackBounds = 765,
     kTransitionBehavior = 766,
     kTextAutospace = 767,
-    kNavigationTrigger = 768,
+    kNavigation = 768,
     kDynamicRangeLimit = 769,
     kFieldSizing = 770,
     kTextSpacingTrim = 771,
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
index d6acbdc..aea75b8 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -3962,7 +3962,7 @@
   kV8RTCEncodedVideoFrame_SetMetadata_Method = 4623,
   kV8RTCEncodedVideoFrame_SetTimestamp_Method = 4624,
   kV8RTCEncodedAudioFrame_SetTimestamp_Method = 4625,
-  kCSSAtRuleViewTransitions = 4626,
+  kCSSAtRuleViewTransition = 4626,
   kSharedDictionaryUsedWithSharedBrotli = 4627,
   kSharedDictionaryUsedWithSharedZstd = 4628,
   kZstdContentEncoding = 4629,
diff --git a/third_party/blink/public/mojom/user_agent/user_agent_metadata.mojom b/third_party/blink/public/mojom/user_agent/user_agent_metadata.mojom
index f95a61f..9f04422 100644
--- a/third_party/blink/public/mojom/user_agent/user_agent_metadata.mojom
+++ b/third_party/blink/public/mojom/user_agent/user_agent_metadata.mojom
@@ -23,7 +23,7 @@
   bool mobile;
   string bitness;
   bool wow64;
-  string form_factor;
+  array<string> form_factor;
 };
 
 // See UserAgentOverride in
diff --git a/third_party/blink/public/web/web_settings.h b/third_party/blink/public/web/web_settings.h
index 6248aee..d2c76e5 100644
--- a/third_party/blink/public/web/web_settings.h
+++ b/third_party/blink/public/web/web_settings.h
@@ -268,12 +268,12 @@
   virtual void SetLazyFrameLoadingDistanceThresholdPx2G(int) = 0;
   virtual void SetLazyFrameLoadingDistanceThresholdPx3G(int) = 0;
   virtual void SetLazyFrameLoadingDistanceThresholdPx4G(int) = 0;
-  virtual void SetLazyImageLoadingDistanceThresholdPxUnknown(int) = 0;
-  virtual void SetLazyImageLoadingDistanceThresholdPxOffline(int) = 0;
-  virtual void SetLazyImageLoadingDistanceThresholdPxSlow2G(int) = 0;
-  virtual void SetLazyImageLoadingDistanceThresholdPx2G(int) = 0;
-  virtual void SetLazyImageLoadingDistanceThresholdPx3G(int) = 0;
-  virtual void SetLazyImageLoadingDistanceThresholdPx4G(int) = 0;
+  virtual void SetLazyLoadingImageMarginPxUnknown(int) = 0;
+  virtual void SetLazyLoadingImageMarginPxOffline(int) = 0;
+  virtual void SetLazyLoadingImageMarginPxSlow2G(int) = 0;
+  virtual void SetLazyLoadingImageMarginPx2G(int) = 0;
+  virtual void SetLazyLoadingImageMarginPx3G(int) = 0;
+  virtual void SetLazyLoadingImageMarginPx4G(int) = 0;
   virtual void SetForceDarkModeEnabled(bool) = 0;
   virtual void SetPreferredColorScheme(blink::mojom::PreferredColorScheme) = 0;
   virtual void SetPreferredContrast(mojom::PreferredContrast) = 0;
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni
index 97f2546..e9d9234 100644
--- a/third_party/blink/renderer/bindings/generated_in_core.gni
+++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -797,8 +797,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_unparsed_value.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_variable_reference_value.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_variable_reference_value.h",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_view_transitions_rule.cc",
-  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_view_transitions_rule.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_view_transition_rule.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_view_transition_rule.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_custom_element_registry.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_custom_element_registry.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_custom_event.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_core.gni b/third_party/blink/renderer/bindings/idl_in_core.gni
index e08e316..0b0b762 100644
--- a/third_party/blink/renderer/bindings/idl_in_core.gni
+++ b/third_party/blink/renderer/bindings/idl_in_core.gni
@@ -62,7 +62,7 @@
   "//third_party/blink/renderer/core/css/css_style_sheet_init.idl",
   "//third_party/blink/renderer/core/css/css_supports_rule.idl",
   "//third_party/blink/renderer/core/css/css_try_rule.idl",
-  "//third_party/blink/renderer/core/css/css_view_transitions_rule.idl",
+  "//third_party/blink/renderer/core/css/css_view_transition_rule.idl",
   "//third_party/blink/renderer/core/css/cssom/css_color_value.idl",
   "//third_party/blink/renderer/core/css/cssom/css_hsl.idl",
   "//third_party/blink/renderer/core/css/cssom/css_hwb.idl",
diff --git a/third_party/blink/renderer/core/css/build.gni b/third_party/blink/renderer/core/css/build.gni
index 33705a91..fc783bb 100644
--- a/third_party/blink/renderer/core/css/build.gni
+++ b/third_party/blink/renderer/core/css/build.gni
@@ -71,8 +71,8 @@
   "counter_style_map.cc",
   "counter_style_map.h",
   "css_anchor_query_enums.h",
-  "css_view_transitions_rule.cc",
-  "css_view_transitions_rule.h",
+  "css_view_transition_rule.cc",
+  "css_view_transition_rule.h",
   "css_axis_value.cc",
   "css_axis_value.h",
   "css_basic_shape_values.cc",
@@ -691,8 +691,8 @@
   "style_request.h",
   "style_rule.cc",
   "style_rule.h",
-  "style_rule_view_transitions.cc",
-  "style_rule_view_transitions.h",
+  "style_rule_view_transition.cc",
+  "style_rule_view_transition.h",
   "style_rule_counter_style.cc",
   "style_rule_counter_style.h",
   "style_rule_css_style_declaration.cc",
diff --git a/third_party/blink/renderer/core/css/css_default_style_sheets.cc b/third_party/blink/renderer/core/css/css_default_style_sheets.cc
index 572fcda..dc566b0 100644
--- a/third_party/blink/renderer/core/css/css_default_style_sheets.cc
+++ b/third_party/blink/renderer/core/css/css_default_style_sheets.cc
@@ -200,8 +200,8 @@
                                                 ScreenEval());
   default_print_style_->AddRulesFromSheet(DefaultStyleSheet(), PrintEval());
 
-  CHECK(default_html_style_->ViewTransitionsRules().empty())
-      << "@view-transitions is not implemented for the UA stylesheet.";
+  CHECK(default_html_style_->ViewTransitionRules().empty())
+      << "@view-transition is not implemented for the UA stylesheet.";
 
   VerifyUniversalRuleCount();
 }
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index 67c444ba..0168c5c 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -6918,7 +6918,7 @@
       is_property: false,
     },
     {
-      name: "navigation-trigger",
+      name: "navigation",
       is_descriptor: true,
       is_property: false,
       runtime_flag: "ViewTransitionOnNavigation",
diff --git a/third_party/blink/renderer/core/css/css_property_equality.cc b/third_party/blink/renderer/core/css/css_property_equality.cc
index ac9f49a6..b28b27a 100644
--- a/third_party/blink/renderer/core/css/css_property_equality.cc
+++ b/third_party/blink/renderer/core/css/css_property_equality.cc
@@ -1306,7 +1306,7 @@
     case CSSPropertyID::kInherits:
     case CSSPropertyID::kInitialValue:
     case CSSPropertyID::kLineGapOverride:
-    case CSSPropertyID::kNavigationTrigger:
+    case CSSPropertyID::kNavigation:
     case CSSPropertyID::kNegative:
     case CSSPropertyID::kOverrideColors:
     case CSSPropertyID::kPad:
diff --git a/third_party/blink/renderer/core/css/css_rule.h b/third_party/blink/renderer/core/css/css_rule.h
index def5944..2eedae5 100644
--- a/third_party/blink/renderer/core/css/css_rule.h
+++ b/third_party/blink/renderer/core/css/css_rule.h
@@ -80,7 +80,7 @@
     kTryRule = 23,
     kFontFeatureRule = 24,
     kStartingStyleRule = 25,
-    kViewTransitionsRule = 26,
+    kViewTransitionRule = 26,
   };
 
   virtual Type GetType() const = 0;
diff --git a/third_party/blink/renderer/core/css/css_value_keywords.json5 b/third_party/blink/renderer/core/css/css_value_keywords.json5
index fb049c1..f382fc49 100644
--- a/third_party/blink/renderer/core/css/css_value_keywords.json5
+++ b/third_party/blink/renderer/core/css/css_value_keywords.json5
@@ -1736,8 +1736,8 @@
     "inverted",
     // none
 
-    // navigation-trigger
-    "cross-document-same-origin",
+    // @view-transition navigation
+    // auto
     // none
 
     // container-type
diff --git a/third_party/blink/renderer/core/css/css_view_transitions_rule.cc b/third_party/blink/renderer/core/css/css_view_transition_rule.cc
similarity index 64%
rename from third_party/blink/renderer/core/css/css_view_transitions_rule.cc
rename to third_party/blink/renderer/core/css/css_view_transition_rule.cc
index c6a40f0..6180ca6 100644
--- a/third_party/blink/renderer/core/css/css_view_transitions_rule.cc
+++ b/third_party/blink/renderer/core/css/css_view_transition_rule.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 "third_party/blink/renderer/core/css/css_view_transitions_rule.h"
+#include "third_party/blink/renderer/core/css/css_view_transition_rule.h"
 
 #include "third_party/blink/renderer/core/css/css_identifier_value.h"
 #include "third_party/blink/renderer/core/css/css_rule.h"
@@ -12,27 +12,27 @@
 #include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
 #include "third_party/blink/renderer/core/css/style_engine.h"
 #include "third_party/blink/renderer/core/css/style_rule.h"
-#include "third_party/blink/renderer/core/css/style_rule_view_transitions.h"
+#include "third_party/blink/renderer/core/css/style_rule_view_transition.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
 namespace blink {
 
-CSSViewTransitionsRule::CSSViewTransitionsRule(
-    StyleRuleViewTransitions* initial_rule,
+CSSViewTransitionRule::CSSViewTransitionRule(
+    StyleRuleViewTransition* initial_rule,
     CSSStyleSheet* parent)
-    : CSSRule(parent), view_transitions_rule_(initial_rule) {}
+    : CSSRule(parent), view_transition_rule_(initial_rule) {}
 
-String CSSViewTransitionsRule::cssText() const {
+String CSSViewTransitionRule::cssText() const {
   StringBuilder result;
 
-  result.Append("@view-transitions { ");
+  result.Append("@view-transition { ");
 
-  String navigation_trigger = navigationTrigger();
-  if (!navigation_trigger.empty()) {
-    result.Append("navigation-trigger: ");
-    result.Append(navigation_trigger);
+  String navigation_value = navigation();
+  if (!navigation_value.empty()) {
+    result.Append("navigation: ");
+    result.Append(navigation_value);
     result.Append("; ");
   }
 
@@ -41,15 +41,15 @@
   return result.ReleaseString();
 }
 
-String CSSViewTransitionsRule::navigationTrigger() const {
-  if (const CSSValue* value = view_transitions_rule_->GetNavigationTrigger()) {
+String CSSViewTransitionRule::navigation() const {
+  if (const CSSValue* value = view_transition_rule_->GetNavigation()) {
     return value->CssText();
   }
 
   return String();
 }
 
-void CSSViewTransitionsRule::setNavigationTrigger(
+void CSSViewTransitionRule::setNavigation(
     const ExecutionContext* execution_context,
     const String& text) {
   CSSStyleSheet* style_sheet = parentStyleSheet();
@@ -58,34 +58,34 @@
   CSSTokenizer tokenizer(text);
   auto tokens = tokenizer.TokenizeToEOF();
   CSSParserTokenRange token_range(tokens);
-  AtRuleDescriptorID descriptor_id = AtRuleDescriptorID::NavigationTrigger;
+  AtRuleDescriptorID descriptor_id = AtRuleDescriptorID::Navigation;
   CSSValue* new_value =
-      AtRuleDescriptorParser::ParseAtViewTransitionsDescriptor(
+      AtRuleDescriptorParser::ParseAtViewTransitionDescriptor(
           descriptor_id, token_range, context);
   if (!new_value) {
     return;
   }
 
   const auto* id = DynamicTo<CSSIdentifierValue>(new_value);
-  if (!id || (id->GetValueID() != CSSValueID::kCrossDocumentSameOrigin &&
+  if (!id || (id->GetValueID() != CSSValueID::kAuto &&
               id->GetValueID() != CSSValueID::kNone)) {
     return;
   }
 
-  view_transitions_rule_->SetNavigationTrigger(new_value);
+  view_transition_rule_->SetNavigation(new_value);
 
   if (Document* document = style_sheet->OwnerDocument()) {
-    document->GetStyleEngine().UpdateViewTransitionsOptIn();
+    document->GetStyleEngine().UpdateViewTransitionOptIn();
   }
 }
 
-void CSSViewTransitionsRule::Reattach(StyleRuleBase* rule) {
+void CSSViewTransitionRule::Reattach(StyleRuleBase* rule) {
   CHECK(rule);
-  view_transitions_rule_ = To<StyleRuleViewTransitions>(rule);
+  view_transition_rule_ = To<StyleRuleViewTransition>(rule);
 }
 
-void CSSViewTransitionsRule::Trace(Visitor* visitor) const {
-  visitor->Trace(view_transitions_rule_);
+void CSSViewTransitionRule::Trace(Visitor* visitor) const {
+  visitor->Trace(view_transition_rule_);
   CSSRule::Trace(visitor);
 }
 
diff --git a/third_party/blink/renderer/core/css/css_view_transition_rule.h b/third_party/blink/renderer/core/css/css_view_transition_rule.h
new file mode 100644
index 0000000..c2e72da9
--- /dev/null
+++ b/third_party/blink/renderer/core/css/css_view_transition_rule.h
@@ -0,0 +1,48 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_VIEW_TRANSITION_RULE_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_VIEW_TRANSITION_RULE_H_
+
+#include "third_party/blink/renderer/core/css/css_rule.h"
+#include "third_party/blink/renderer/platform/heap/member.h"
+#include "third_party/blink/renderer/platform/wtf/casting.h"
+
+namespace blink {
+
+class ExecutionContext;
+class StyleRuleViewTransition;
+
+class CSSViewTransitionRule final : public CSSRule {
+  DEFINE_WRAPPERTYPEINFO();
+
+ public:
+  CSSViewTransitionRule(StyleRuleViewTransition*, CSSStyleSheet*);
+  ~CSSViewTransitionRule() override = default;
+
+  String cssText() const override;
+  void Reattach(StyleRuleBase*) override;
+
+  void Trace(Visitor*) const override;
+
+  String navigation() const;
+
+  void setNavigation(const ExecutionContext*, const String&);
+
+ private:
+  CSSRule::Type GetType() const override { return kViewTransitionRule; }
+
+  Member<StyleRuleViewTransition> view_transition_rule_;
+};
+
+template <>
+struct DowncastTraits<CSSViewTransitionRule> {
+  static bool AllowFrom(const CSSRule& rule) {
+    return rule.GetType() == CSSRule::kViewTransitionRule;
+  }
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_VIEW_TRANSITION_RULE_H_
diff --git a/third_party/blink/renderer/core/css/css_view_transitions_rule.idl b/third_party/blink/renderer/core/css/css_view_transition_rule.idl
similarity index 81%
rename from third_party/blink/renderer/core/css/css_view_transitions_rule.idl
rename to third_party/blink/renderer/core/css/css_view_transition_rule.idl
index 1e983ad..91be473f 100644
--- a/third_party/blink/renderer/core/css/css_view_transitions_rule.idl
+++ b/third_party/blink/renderer/core/css/css_view_transition_rule.idl
@@ -5,7 +5,7 @@
 [
   Exposed=Window,
   RuntimeEnabled=ViewTransitionOnNavigation
-] interface CSSViewTransitionsRule : CSSRule {
-  [SetterCallWith=ExecutionContext] attribute CSSOMString navigationTrigger;
+] interface CSSViewTransitionRule : CSSRule {
+  [SetterCallWith=ExecutionContext] attribute CSSOMString navigation;
 };
 
diff --git a/third_party/blink/renderer/core/css/css_view_transitions_rule.h b/third_party/blink/renderer/core/css/css_view_transitions_rule.h
deleted file mode 100644
index c5b657a..0000000
--- a/third_party/blink/renderer/core/css/css_view_transitions_rule.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_VIEW_TRANSITIONS_RULE_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_VIEW_TRANSITIONS_RULE_H_
-
-#include "third_party/blink/renderer/core/css/css_rule.h"
-#include "third_party/blink/renderer/platform/heap/member.h"
-#include "third_party/blink/renderer/platform/wtf/casting.h"
-
-namespace blink {
-
-class ExecutionContext;
-class StyleRuleViewTransitions;
-
-class CSSViewTransitionsRule final : public CSSRule {
-  DEFINE_WRAPPERTYPEINFO();
-
- public:
-  CSSViewTransitionsRule(StyleRuleViewTransitions*, CSSStyleSheet*);
-  ~CSSViewTransitionsRule() override = default;
-
-  String cssText() const override;
-  void Reattach(StyleRuleBase*) override;
-
-  void Trace(Visitor*) const override;
-
-  String navigationTrigger() const;
-
-  void setNavigationTrigger(const ExecutionContext*, const String&);
-
- private:
-  CSSRule::Type GetType() const override { return kViewTransitionsRule; }
-
-  Member<StyleRuleViewTransitions> view_transitions_rule_;
-};
-
-template <>
-struct DowncastTraits<CSSViewTransitionsRule> {
-  static bool AllowFrom(const CSSRule& rule) {
-    return rule.GetType() == CSSRule::kViewTransitionsRule;
-  }
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_CSS_VIEW_TRANSITIONS_RULE_H_
diff --git a/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc b/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc
index 1bab5dcd..b73b52c 100644
--- a/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc
+++ b/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.cc
@@ -278,8 +278,8 @@
       return Parser::ParseAtPropertyDescriptor(id, tokenized_value, context);
     case StyleRule::kCounterStyle:
       return Parser::ParseAtCounterStyleDescriptor(id, range, context);
-    case StyleRule::kViewTransitions:
-      return Parser::ParseAtViewTransitionsDescriptor(id, range, context);
+    case StyleRule::kViewTransition:
+      return Parser::ParseAtViewTransitionDescriptor(id, range, context);
     case StyleRule::kCharset:
     case StyleRule::kContainer:
     case StyleRule::kStyle:
@@ -467,17 +467,17 @@
   return parsed_value;
 }
 
-CSSValue* AtRuleDescriptorParser::ParseAtViewTransitionsDescriptor(
+CSSValue* AtRuleDescriptorParser::ParseAtViewTransitionDescriptor(
     AtRuleDescriptorID id,
     CSSParserTokenRange& range,
     const CSSParserContext& context) {
   CSSValue* parsed_value = nullptr;
   switch (id) {
-    case AtRuleDescriptorID::NavigationTrigger:
+    case AtRuleDescriptorID::Navigation:
       range.ConsumeWhitespace();
       parsed_value =
-          css_parsing_utils::ConsumeIdent<CSSValueID::kCrossDocumentSameOrigin,
-                                          CSSValueID::kNone>(range);
+          css_parsing_utils::ConsumeIdent<CSSValueID::kAuto, CSSValueID::kNone>(
+              range);
       break;
     default:
       break;
diff --git a/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h b/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h
index f6d75105..28cac5f 100644
--- a/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h
+++ b/third_party/blink/renderer/core/css/parser/at_rule_descriptor_parser.h
@@ -46,9 +46,9 @@
   static CSSValue* ParseAtFontPaletteValuesDescriptor(AtRuleDescriptorID,
                                                       CSSParserTokenRange&,
                                                       const CSSParserContext&);
-  static CSSValue* ParseAtViewTransitionsDescriptor(AtRuleDescriptorID,
-                                                    CSSParserTokenRange&,
-                                                    const CSSParserContext&);
+  static CSSValue* ParseAtViewTransitionDescriptor(AtRuleDescriptorID,
+                                                   CSSParserTokenRange&,
+                                                   const CSSParserContext&);
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/parser/at_rule_names.json5 b/third_party/blink/renderer/core/css/parser/at_rule_names.json5
index 8564c7e..07a6848 100644
--- a/third_party/blink/renderer/core/css/parser/at_rule_names.json5
+++ b/third_party/blink/renderer/core/css/parser/at_rule_names.json5
@@ -76,7 +76,7 @@
       name: "range",
     },
     {
-      name: "navigation-trigger",
+      name: "navigation",
     },
     {
       name: "size-adjust",
diff --git a/third_party/blink/renderer/core/css/parser/css_at_rule_id.cc b/third_party/blink/renderer/core/css/parser/css_at_rule_id.cc
index 8fbb35c..136d154 100644
--- a/third_party/blink/renderer/core/css/parser/css_at_rule_id.cc
+++ b/third_party/blink/renderer/core/css/parser/css_at_rule_id.cc
@@ -13,9 +13,9 @@
 namespace blink {
 
 CSSAtRuleID CssAtRuleID(StringView name) {
-  if (EqualIgnoringASCIICase(name, "view-transitions")) {
+  if (EqualIgnoringASCIICase(name, "view-transition")) {
     if (RuntimeEnabledFeatures::ViewTransitionOnNavigationEnabled()) {
-      return CSSAtRuleID::kCSSAtRuleViewTransitions;
+      return CSSAtRuleID::kCSSAtRuleViewTransition;
     }
     return CSSAtRuleID::kCSSAtRuleInvalid;
   }
@@ -112,8 +112,8 @@
   switch (rule_id) {
     case CSSAtRuleID::kCSSAtRuleAnnotation:
       return WebFeature::kCSSAtRuleAnnotation;
-    case CSSAtRuleID::kCSSAtRuleViewTransitions:
-      return WebFeature::kCSSAtRuleViewTransitions;
+    case CSSAtRuleID::kCSSAtRuleViewTransition:
+      return WebFeature::kCSSAtRuleViewTransition;
     case CSSAtRuleID::kCSSAtRuleCharset:
       return WebFeature::kCSSAtRuleCharset;
     case CSSAtRuleID::kCSSAtRuleCharacterVariant:
diff --git a/third_party/blink/renderer/core/css/parser/css_at_rule_id.h b/third_party/blink/renderer/core/css/parser/css_at_rule_id.h
index 91e64b4..01107cd 100644
--- a/third_party/blink/renderer/core/css/parser/css_at_rule_id.h
+++ b/third_party/blink/renderer/core/css/parser/css_at_rule_id.h
@@ -13,7 +13,7 @@
 
 enum class CSSAtRuleID {
   kCSSAtRuleInvalid,
-  kCSSAtRuleViewTransitions,
+  kCSSAtRuleViewTransition,
   kCSSAtRuleCharset,
   kCSSAtRuleFontFace,
   kCSSAtRuleFontPaletteValues,
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
index 225829c..c6b0b1e 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
+++ b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
@@ -721,7 +721,7 @@
         id != CSSAtRuleID::kCSSAtRuleLayer &&      // [css-cascade-5]
         id != CSSAtRuleID::kCSSAtRuleScope &&      // [css-cascade-6]
         id != CSSAtRuleID::kCSSAtRuleStartingStyle &&
-        id != CSSAtRuleID::kCSSAtRuleViewTransitions) {
+        id != CSSAtRuleID::kCSSAtRuleViewTransition) {
       ConsumeErroneousAtRule(stream, id);
       return nullptr;
     }
@@ -779,8 +779,8 @@
     DCHECK_LE(allowed_rules, kRegularRules);
 
     switch (id) {
-      case CSSAtRuleID::kCSSAtRuleViewTransitions:
-        return ConsumeViewTransitionsRule(stream);
+      case CSSAtRuleID::kCSSAtRuleViewTransition:
+        return ConsumeViewTransitionRule(stream);
       case CSSAtRuleID::kCSSAtRuleContainer:
         return ConsumeContainerRule(stream, nesting_type,
                                     parent_rule_for_nesting);
@@ -1685,7 +1685,7 @@
   return MakeGarbageCollected<StyleRuleScope>(*style_scope, std::move(rules));
 }
 
-StyleRuleViewTransitions* CSSParserImpl::ConsumeViewTransitionsRule(
+StyleRuleViewTransition* CSSParserImpl::ConsumeViewTransitionRule(
     CSSParserTokenStream& stream) {
   CHECK(RuntimeEnabledFeatures::ViewTransitionOnNavigationEnabled());
   wtf_size_t prelude_offset_start = stream.LookAheadOffset();
@@ -1696,23 +1696,23 @@
   }
 
   if (!prelude.AtEnd()) {
-    return nullptr;  // Parse error; @view-transitions prelude should be empty
+    return nullptr;  // Parse error; @view-transition prelude should be empty
   }
 
   CSSParserTokenStream::BlockGuard guard(stream);
 
   if (observer_) {
-    observer_->StartRuleHeader(StyleRule::kViewTransitions,
+    observer_->StartRuleHeader(StyleRule::kViewTransition,
                                prelude_offset_start);
     observer_->EndRuleHeader(prelude_offset_end);
   }
 
-  ConsumeDeclarationList(stream, StyleRule::kViewTransitions,
+  ConsumeDeclarationList(stream, StyleRule::kViewTransition,
                          CSSNestingType::kNone,
                          /*parent_rule_for_nesting=*/nullptr,
                          /*child_rules=*/nullptr);
 
-  return MakeGarbageCollected<StyleRuleViewTransitions>(
+  return MakeGarbageCollected<StyleRuleViewTransition>(
       *CreateCSSPropertyValueSet(parsed_properties_, context_->Mode()));
 }
 
@@ -2154,7 +2154,7 @@
       rule_type == StyleRule::kCounterStyle ||
       rule_type == StyleRule::kFontPaletteValues ||
       rule_type == StyleRule::kKeyframe || rule_type == StyleRule::kScope ||
-      rule_type == StyleRule::kViewTransitions || rule_type == StyleRule::kTry;
+      rule_type == StyleRule::kViewTransition || rule_type == StyleRule::kTry;
   bool use_observer = observer_ && is_observer_rule_type;
   if (use_observer) {
     observer_->StartRuleBody(stream.Offset());
@@ -2374,7 +2374,7 @@
                             rule_type == StyleRule::kFontPaletteValues ||
                             rule_type == StyleRule::kProperty ||
                             rule_type == StyleRule::kCounterStyle ||
-                            rule_type == StyleRule::kViewTransitions;
+                            rule_type == StyleRule::kViewTransition;
 
   uint64_t id = parsing_descriptor
                     ? static_cast<uint64_t>(lhs.ParseAsAtRuleDescriptorID())
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_impl.h b/third_party/blink/renderer/core/css/parser/css_parser_impl.h
index 13368f3..97a6cb2 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_impl.h
+++ b/third_party/blink/renderer/core/css/parser/css_parser_impl.h
@@ -31,7 +31,7 @@
 class CSSParserObserver;
 class CSSParserTokenStream;
 class StyleRule;
-class StyleRuleViewTransitions;
+class StyleRuleViewTransition;
 class StyleRuleBase;
 class StyleRuleCharset;
 class StyleRuleCounterStyle;
@@ -238,7 +238,7 @@
   StyleRuleBase* ConsumeScopeRule(CSSParserTokenStream&,
                                   CSSNestingType,
                                   StyleRule* parent_rule_for_nesting);
-  StyleRuleViewTransitions* ConsumeViewTransitionsRule(
+  StyleRuleViewTransition* ConsumeViewTransitionRule(
       CSSParserTokenStream& stream);
   StyleRuleContainer* ConsumeContainerRule(CSSParserTokenStream& stream,
                                            CSSNestingType,
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
index bbd1c7f..551d038 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.cc
@@ -1837,15 +1837,13 @@
 }  // namespace
 
 CSSValue* ConsumeColorContrast(CSSParserTokenRange& range,
-                               const CSSParserContext& context,
-                               bool accept_quirky_colors) {
+                               const CSSParserContext& context) {
   DCHECK_EQ(range.Peek().FunctionId(), CSSValueID::kColorContrast);
 
   CSSParserTokenRange range_copy = range;
   CSSParserTokenRange args = ConsumeFunction(range_copy);
 
-  CSSValue* background_color =
-      ConsumeColor(args, context, accept_quirky_colors);
+  CSSValue* background_color = ConsumeColor(args, context);
   if (!background_color) {
     return nullptr;
   }
@@ -1856,7 +1854,7 @@
 
   VectorOf<CSSValue> colors_to_compare_against;
   do {
-    CSSValue* color = ConsumeColor(args, context, accept_quirky_colors);
+    CSSValue* color = ConsumeColor(args, context);
     if (!color) {
       return nullptr;
     }
@@ -1939,7 +1937,7 @@
                        AllowedColorKeywords allowed_keywords) {
   if (RuntimeEnabledFeatures::CSSColorContrastEnabled() &&
       range.Peek().FunctionId() == CSSValueID::kColorContrast) {
-    return ConsumeColorContrast(range, context, accept_quirky_colors);
+    return ConsumeColorContrast(range, context);
   }
 
   if (range.Peek().FunctionId() == CSSValueID::kColorMix) {
@@ -5815,7 +5813,6 @@
   }
 
   bool is_subgrid_track_list =
-      RuntimeEnabledFeatures::LayoutNGSubgridEnabled() &&
       track_list_type == TrackListType::kGridTemplateSubgrid;
 
   CSSValueList* values = CSSValueList::CreateSpaceSeparated();
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
index 925772e..99cd130 100644
--- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -1443,16 +1443,14 @@
   auto* curr_value = values.begin();
   bool is_subgrid = false;
 
-  if (RuntimeEnabledFeatures::LayoutNGSubgridEnabled()) {
-    auto* identifier_value = DynamicTo<CSSIdentifierValue>(curr_value->Get());
-    if (identifier_value &&
-        identifier_value->GetValueID() == CSSValueID::kSubgrid) {
-      state.GetDocument().CountUse(WebFeature::kCSSSubgridLayout);
-      computed_grid_track_list.axis_type = GridAxisType::kSubgriddedAxis;
-      track_list.SetAxisType(GridAxisType::kSubgriddedAxis);
-      is_subgrid = true;
-      ++curr_value;
-    }
+  auto* identifier_value = DynamicTo<CSSIdentifierValue>(curr_value->Get());
+  if (identifier_value &&
+      identifier_value->GetValueID() == CSSValueID::kSubgrid) {
+    state.GetDocument().CountUse(WebFeature::kCSSSubgridLayout);
+    computed_grid_track_list.axis_type = GridAxisType::kSubgriddedAxis;
+    track_list.SetAxisType(GridAxisType::kSubgriddedAxis);
+    is_subgrid = true;
+    ++curr_value;
   }
 
   for (; curr_value != values.end(); ++curr_value) {
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
index fd1f7bf..6cf9855 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -2913,6 +2913,10 @@
                    absl::nullopt);
     PROPAGATE_FROM(document_element_style, ForcedColorAdjust,
                    SetForcedColorAdjust, EForcedColorAdjust::kAuto);
+    if (RuntimeEnabledFeatures::UsedColorSchemeRootScrollbarsEnabled()) {
+      PROPAGATE_FROM(document_element_style, ColorSchemeFlagsIsNormal,
+                     SetColorSchemeFlagsIsNormal, false);
+    }
   }
 
   // scroll-start
diff --git a/third_party/blink/renderer/core/css/rule_set.cc b/third_party/blink/renderer/core/css/rule_set.cc
index 8fef60c..ec0c1fc 100644
--- a/third_party/blink/renderer/core/css/rule_set.cc
+++ b/third_party/blink/renderer/core/css/rule_set.cc
@@ -702,9 +702,9 @@
   position_fallback_rules_.push_back(rule);
 }
 
-void RuleSet::AddViewTransitionsRule(StyleRuleViewTransitions* rule) {
+void RuleSet::AddViewTransitionRule(StyleRuleViewTransition* rule) {
   need_compaction_ = true;
-  view_transitions_rules_.push_back(rule);
+  view_transition_rules_.push_back(rule);
 }
 
 void RuleSet::AddChildRules(const HeapVector<Member<StyleRuleBase>>& rules,
@@ -749,10 +749,10 @@
                    DynamicTo<StyleRuleCounterStyle>(rule)) {
       counter_style_rule->SetCascadeLayer(cascade_layer);
       AddCounterStyleRule(counter_style_rule);
-    } else if (auto* view_transitions_rule =
-                   DynamicTo<StyleRuleViewTransitions>(rule)) {
-      view_transitions_rule->SetCascadeLayer(cascade_layer);
-      AddViewTransitionsRule(view_transitions_rule);
+    } else if (auto* view_transition_rule =
+                   DynamicTo<StyleRuleViewTransition>(rule)) {
+      view_transition_rule->SetCascadeLayer(cascade_layer);
+      AddViewTransitionRule(view_transition_rule);
     } else if (auto* position_fallback_rule =
                    DynamicTo<StyleRulePositionFallback>(rule)) {
       position_fallback_rule->SetCascadeLayer(cascade_layer);
@@ -1287,7 +1287,7 @@
   counter_style_rules_.shrink_to_fit();
   position_fallback_rules_.shrink_to_fit();
   layer_intervals_.shrink_to_fit();
-  view_transitions_rules_.shrink_to_fit();
+  view_transition_rules_.shrink_to_fit();
   bloom_hash_backing_.shrink_to_fit();
 
 #if EXPENSIVE_DCHECKS_ARE_ON()
@@ -1402,7 +1402,7 @@
   visitor->Trace(font_face_rules_);
   visitor->Trace(font_palette_values_rules_);
   visitor->Trace(font_feature_values_rules_);
-  visitor->Trace(view_transitions_rules_);
+  visitor->Trace(view_transition_rules_);
   visitor->Trace(keyframes_rules_);
   visitor->Trace(property_rules_);
   visitor->Trace(counter_style_rules_);
diff --git a/third_party/blink/renderer/core/css/rule_set.h b/third_party/blink/renderer/core/css/rule_set.h
index 07ce1d48..e955b93 100644
--- a/third_party/blink/renderer/core/css/rule_set.h
+++ b/third_party/blink/renderer/core/css/rule_set.h
@@ -38,7 +38,7 @@
 #include "third_party/blink/renderer/core/css/style_rule_counter_style.h"
 #include "third_party/blink/renderer/core/css/style_rule_font_feature_values.h"
 #include "third_party/blink/renderer/core/css/style_rule_font_palette_values.h"
-#include "third_party/blink/renderer/core/css/style_rule_view_transitions.h"
+#include "third_party/blink/renderer/core/css/style_rule_view_transition.h"
 #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_map.h"
 #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h"
 #include "third_party/blink/renderer/platform/heap/collection_support/heap_linked_stack.h"
@@ -465,9 +465,9 @@
       const {
     return font_feature_values_rules_;
   }
-  const HeapVector<Member<StyleRuleViewTransitions>>& ViewTransitionsRules()
+  const HeapVector<Member<StyleRuleViewTransition>>& ViewTransitionRules()
       const {
-    return view_transitions_rules_;
+    return view_transition_rules_;
   }
   const HeapVector<Member<StyleRulePositionFallback>>& PositionFallbackRules()
       const {
@@ -592,7 +592,7 @@
   void AddFontPaletteValuesRule(StyleRuleFontPaletteValues*);
   void AddFontFeatureValuesRule(StyleRuleFontFeatureValues*);
   void AddPositionFallbackRule(StyleRulePositionFallback*);
-  void AddViewTransitionsRule(StyleRuleViewTransitions*);
+  void AddViewTransitionRule(StyleRuleViewTransition*);
 
   bool MatchMediaForAddRules(const MediaQueryEvaluator& evaluator,
                              const MediaQuerySet* media_queries);
@@ -701,7 +701,7 @@
   HeapVector<Member<StyleRuleFontFace>> font_face_rules_;
   HeapVector<Member<StyleRuleFontPaletteValues>> font_palette_values_rules_;
   HeapVector<Member<StyleRuleFontFeatureValues>> font_feature_values_rules_;
-  HeapVector<Member<StyleRuleViewTransitions>> view_transitions_rules_;
+  HeapVector<Member<StyleRuleViewTransition>> view_transition_rules_;
   HeapVector<Member<StyleRuleKeyframes>> keyframes_rules_;
   HeapVector<Member<StyleRuleProperty>> property_rules_;
   HeapVector<Member<StyleRuleCounterStyle>> counter_style_rules_;
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc
index 60dd2df..f0aee909 100644
--- a/third_party/blink/renderer/core/css/style_engine.cc
+++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -141,7 +141,7 @@
   kFontPaletteValuesRules = 1 << 6,
   kPositionFallbackRules = 1 << 7,
   kFontFeatureValuesRules = 1 << 8,
-  kViewTransitionsRules = 1 << 9
+  kViewTransitionRules = 1 << 9
 };
 
 const unsigned kRuleSetFlagsAll = ~0u;
@@ -173,8 +173,8 @@
     if (!rule_set->PositionFallbackRules().empty()) {
       flags |= kPositionFallbackRules;
     }
-    if (!rule_set->ViewTransitionsRules().empty()) {
-      flags |= kViewTransitionsRules;
+    if (!rule_set->ViewTransitionRules().empty()) {
+      flags |= kViewTransitionRules;
     }
   }
   return flags;
@@ -2371,16 +2371,15 @@
       CSSDefaultStyleSheets::ScreenEval());
 }
 
-void StyleEngine::UpdateViewTransitionsOptIn() {
+void StyleEngine::UpdateViewTransitionOptIn() {
   bool cross_document_enabled = false;
 
   // TODO(https://crbug.com/1463966): This will likely need to change to a
   // CSSValueList if we want to support multiple tokens as a trigger.
-  if (view_transitions_rule_) {
-    if (const CSSValue* value =
-            view_transitions_rule_->GetNavigationTrigger()) {
-      cross_document_enabled = To<CSSIdentifierValue>(value)->GetValueID() ==
-                               CSSValueID::kCrossDocumentSameOrigin;
+  if (view_transition_rule_) {
+    if (const CSSValue* value = view_transition_rule_->GetNavigation()) {
+      cross_document_enabled =
+          To<CSSIdentifierValue>(value)->GetValueID() == CSSValueID::kAuto;
     }
   }
 
@@ -2796,11 +2795,11 @@
     MarkPositionFallbackStylesDirty();
   }
 
-  if (changed_rule_flags & kViewTransitionsRules) {
+  if (changed_rule_flags & kViewTransitionRules) {
     // Since a shadow-tree isn't an independent navigable, @view-transition
     // doesn't apply within one.
     if (tree_scope.RootNode().IsDocumentNode()) {
-      AddViewTransitionsRules(new_style_sheets);
+      AddViewTransitionRules(new_style_sheets);
     }
   }
 
@@ -3051,16 +3050,15 @@
                                          new_rule->GetCascadeLayer()) <= 0;
 }
 
-void StyleEngine::AddViewTransitionsRules(
-    const ActiveStyleSheetVector& sheets) {
+void StyleEngine::AddViewTransitionRules(const ActiveStyleSheetVector& sheets) {
   if (!RuntimeEnabledFeatures::ViewTransitionOnNavigationEnabled()) {
     return;
   }
-  view_transitions_rule_.Clear();
+  view_transition_rule_.Clear();
 
   for (const ActiveStyleSheet& active_sheet : sheets) {
     RuleSet* rule_set = active_sheet.second;
-    if (!rule_set || rule_set->ViewTransitionsRules().empty()) {
+    if (!rule_set || rule_set->ViewTransitionRules().empty()) {
       continue;
     }
 
@@ -3068,17 +3066,16 @@
         document_->GetScopedStyleResolver()
             ? document_->GetScopedStyleResolver()->GetCascadeLayerMap()
             : nullptr;
-    for (auto& rule : rule_set->ViewTransitionsRules()) {
-      if (!view_transitions_rule_ || !layer_map ||
-          layer_map->CompareLayerOrder(
-              view_transitions_rule_->GetCascadeLayer(),
-              rule->GetCascadeLayer()) <= 0) {
-        view_transitions_rule_ = rule;
+    for (auto& rule : rule_set->ViewTransitionRules()) {
+      if (!view_transition_rule_ || !layer_map ||
+          layer_map->CompareLayerOrder(view_transition_rule_->GetCascadeLayer(),
+                                       rule->GetCascadeLayer()) <= 0) {
+        view_transition_rule_ = rule;
       }
     }
   }
 
-  UpdateViewTransitionsOptIn();
+  UpdateViewTransitionOptIn();
 }
 
 void StyleEngine::AddFontPaletteValuesRules(const RuleSet& rule_set) {
@@ -4188,7 +4185,7 @@
   visitor->Trace(text_tracks_);
   visitor->Trace(vtt_originating_element_);
   visitor->Trace(parent_for_detached_subtree_);
-  visitor->Trace(view_transitions_rule_);
+  visitor->Trace(view_transition_rule_);
   visitor->Trace(style_image_cache_);
   visitor->Trace(fill_or_clip_path_uri_value_cache_);
   visitor->Trace(style_containment_scope_tree_);
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h
index 9c66c1b..25721cb 100644
--- a/third_party/blink/renderer/core/css/style_engine.h
+++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -684,7 +684,7 @@
   const char* NameInHeapSnapshot() const override { return "StyleEngine"; }
 
   RuleSet* DefaultViewTransitionStyle() const;
-  void UpdateViewTransitionsOptIn();
+  void UpdateViewTransitionOptIn();
 
   const ActiveStyleSheetVector& ActiveUserStyleSheets() const {
     return active_user_style_sheets_;
@@ -816,7 +816,7 @@
   bool UserKeyframeStyleShouldOverride(
       const StyleRuleKeyframes* new_rule,
       const StyleRuleKeyframes* existing_rule) const;
-  void AddViewTransitionsRules(const ActiveStyleSheetVector& sheets);
+  void AddViewTransitionRules(const ActiveStyleSheetVector& sheets);
 
   CounterStyleMap& EnsureUserCounterStyleMap();
 
@@ -1047,8 +1047,8 @@
   // generated during a ViewTransition.
   Vector<AtomicString> view_transition_names_;
 
-  // The @view-transitions rule currently applying to the document.
-  Member<StyleRuleViewTransitions> view_transitions_rule_;
+  // The @view-transition rule currently applying to the document.
+  Member<StyleRuleViewTransition> view_transition_rule_;
 
   // Cache for sharing ImageResourceContent between CSSValues referencing the
   // same URL.
diff --git a/third_party/blink/renderer/core/css/style_rule.cc b/third_party/blink/renderer/core/css/style_rule.cc
index 1912267e..cbfef4f 100644
--- a/third_party/blink/renderer/core/css/style_rule.cc
+++ b/third_party/blink/renderer/core/css/style_rule.cc
@@ -43,7 +43,7 @@
 #include "third_party/blink/renderer/core/css/css_style_sheet.h"
 #include "third_party/blink/renderer/core/css/css_supports_rule.h"
 #include "third_party/blink/renderer/core/css/css_try_rule.h"
-#include "third_party/blink/renderer/core/css/css_view_transitions_rule.h"
+#include "third_party/blink/renderer/core/css/css_view_transition_rule.h"
 #include "third_party/blink/renderer/core/css/parser/container_query_parser.h"
 #include "third_party/blink/renderer/core/css/parser/css_parser.h"
 #include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
@@ -58,7 +58,7 @@
 #include "third_party/blink/renderer/core/css/style_rule_import.h"
 #include "third_party/blink/renderer/core/css/style_rule_keyframe.h"
 #include "third_party/blink/renderer/core/css/style_rule_namespace.h"
-#include "third_party/blink/renderer/core/css/style_rule_view_transitions.h"
+#include "third_party/blink/renderer/core/css/style_rule_view_transition.h"
 #include "third_party/blink/renderer/core/css/style_sheet_contents.h"
 #include "third_party/blink/renderer/platform/wtf/size_assertions.h"
 
@@ -149,8 +149,8 @@
     case kStartingStyle:
       To<StyleRuleStartingStyle>(this)->TraceAfterDispatch(visitor);
       return;
-    case kViewTransitions:
-      To<StyleRuleViewTransitions>(this)->TraceAfterDispatch(visitor);
+    case kViewTransition:
+      To<StyleRuleViewTransition>(this)->TraceAfterDispatch(visitor);
       return;
   }
   NOTREACHED();
@@ -224,8 +224,8 @@
     case kStartingStyle:
       To<StyleRuleStartingStyle>(this)->~StyleRuleStartingStyle();
       return;
-    case kViewTransitions:
-      To<StyleRuleViewTransitions>(this)->~StyleRuleViewTransitions();
+    case kViewTransition:
+      To<StyleRuleViewTransition>(this)->~StyleRuleViewTransition();
       return;
   }
   NOTREACHED();
@@ -277,8 +277,8 @@
       return To<StyleRulePositionFallback>(this)->Copy();
     case kStartingStyle:
       return To<StyleRuleStartingStyle>(this)->Copy();
-    case kViewTransitions:
-      return To<StyleRuleViewTransitions>(this)->Copy();
+    case kViewTransition:
+      return To<StyleRuleViewTransition>(this)->Copy();
     case kTry:
       return To<StyleRuleTry>(this)->Copy();
   }
@@ -364,9 +364,9 @@
       rule = MakeGarbageCollected<CSSStartingStyleRule>(
           To<StyleRuleStartingStyle>(self), parent_sheet);
       break;
-    case kViewTransitions:
-      rule = MakeGarbageCollected<CSSViewTransitionsRule>(
-          To<StyleRuleViewTransitions>(self), parent_sheet);
+    case kViewTransition:
+      rule = MakeGarbageCollected<CSSViewTransitionRule>(
+          To<StyleRuleViewTransition>(self), parent_sheet);
       break;
     case kTry:
       // @try rules must be child rules of @position-fallback.
@@ -524,7 +524,7 @@
     case kTry:
     case kKeyframe:
     case kCharset:
-    case kViewTransitions:
+    case kViewTransition:
       // Cannot have any child rules.
       break;
   }
diff --git a/third_party/blink/renderer/core/css/style_rule.h b/third_party/blink/renderer/core/css/style_rule.h
index 19cee7b..cc3a8f1 100644
--- a/third_party/blink/renderer/core/css/style_rule.h
+++ b/third_party/blink/renderer/core/css/style_rule.h
@@ -70,7 +70,7 @@
     kPositionFallback,
     kTry,
     kStartingStyle,
-    kViewTransitions,
+    kViewTransition,
   };
 
   // Name of a cascade layer as given by an @layer rule, split at '.' into a
@@ -107,7 +107,7 @@
   bool IsPositionFallbackRule() const { return GetType() == kPositionFallback; }
   bool IsTryRule() const { return GetType() == kTry; }
   bool IsStartingStyleRule() const { return GetType() == kStartingStyle; }
-  bool IsViewTransitionsRule() const { return GetType() == kViewTransitions; }
+  bool IsViewTransitionRule() const { return GetType() == kViewTransition; }
   bool IsConditionRule() const {
     return GetType() == kContainer || GetType() == kMedia ||
            GetType() == kSupports || GetType() == kStartingStyle;
diff --git a/third_party/blink/renderer/core/css/style_rule_view_transition.cc b/third_party/blink/renderer/core/css/style_rule_view_transition.cc
new file mode 100644
index 0000000..4296777c
--- /dev/null
+++ b/third_party/blink/renderer/core/css/style_rule_view_transition.cc
@@ -0,0 +1,40 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/css/style_rule_view_transition.h"
+
+#include "base/auto_reset.h"
+#include "base/memory/values_equivalent.h"
+#include "third_party/blink/renderer/core/css/cascade_layer.h"
+#include "third_party/blink/renderer/core/css/css_identifier_value.h"
+#include "third_party/blink/renderer/core/css/css_value_list.h"
+
+namespace blink {
+
+StyleRuleViewTransition::StyleRuleViewTransition(
+    CSSPropertyValueSet& properties)
+    : StyleRuleBase(kViewTransition),
+      navigation_(properties.GetPropertyCSSValue(CSSPropertyID::kNavigation)) {}
+
+StyleRuleViewTransition::StyleRuleViewTransition(
+    const StyleRuleViewTransition&) = default;
+
+StyleRuleViewTransition::~StyleRuleViewTransition() = default;
+
+const CSSValue* StyleRuleViewTransition::GetNavigation() const {
+  return navigation_.Get();
+}
+
+void StyleRuleViewTransition::SetNavigation(const CSSValue* new_value) {
+  navigation_ = new_value;
+}
+
+void StyleRuleViewTransition::TraceAfterDispatch(
+    blink::Visitor* visitor) const {
+  visitor->Trace(layer_);
+  visitor->Trace(navigation_);
+  StyleRuleBase::TraceAfterDispatch(visitor);
+}
+
+}  // namespace blink
diff --git a/third_party/blink/renderer/core/css/style_rule_view_transition.h b/third_party/blink/renderer/core/css/style_rule_view_transition.h
new file mode 100644
index 0000000..7556242
--- /dev/null
+++ b/third_party/blink/renderer/core/css/style_rule_view_transition.h
@@ -0,0 +1,45 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_RULE_VIEW_TRANSITION_H_
+#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_RULE_VIEW_TRANSITION_H_
+
+#include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/core/css/style_rule.h"
+
+namespace blink {
+
+class CORE_EXPORT StyleRuleViewTransition : public StyleRuleBase {
+ public:
+  explicit StyleRuleViewTransition(CSSPropertyValueSet&);
+  StyleRuleViewTransition(const StyleRuleViewTransition&);
+  ~StyleRuleViewTransition();
+
+  const CSSValue* GetNavigation() const;
+  void SetNavigation(const CSSValue* new_value);
+
+  StyleRuleViewTransition* Copy() const {
+    return MakeGarbageCollected<StyleRuleViewTransition>(*this);
+  }
+
+  void SetCascadeLayer(const CascadeLayer* layer) { layer_ = layer; }
+  const CascadeLayer* GetCascadeLayer() const { return layer_.Get(); }
+
+  void TraceAfterDispatch(blink::Visitor*) const;
+
+ private:
+  Member<const CascadeLayer> layer_;
+  Member<const CSSValue> navigation_;
+};
+
+template <>
+struct DowncastTraits<StyleRuleViewTransition> {
+  static bool AllowFrom(const StyleRuleBase& rule) {
+    return rule.IsViewTransitionRule();
+  }
+};
+
+}  // namespace blink
+
+#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_RULE_VIEW_TRANSITION_H_
diff --git a/third_party/blink/renderer/core/css/style_rule_view_transitions.cc b/third_party/blink/renderer/core/css/style_rule_view_transitions.cc
deleted file mode 100644
index 3b6ad1b6..0000000
--- a/third_party/blink/renderer/core/css/style_rule_view_transitions.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/core/css/style_rule_view_transitions.h"
-
-#include "base/auto_reset.h"
-#include "base/memory/values_equivalent.h"
-#include "third_party/blink/renderer/core/css/cascade_layer.h"
-#include "third_party/blink/renderer/core/css/css_identifier_value.h"
-#include "third_party/blink/renderer/core/css/css_value_list.h"
-
-namespace blink {
-
-StyleRuleViewTransitions::StyleRuleViewTransitions(
-    CSSPropertyValueSet& properties)
-    : StyleRuleBase(kViewTransitions),
-      navigation_trigger_(
-          properties.GetPropertyCSSValue(CSSPropertyID::kNavigationTrigger)) {}
-
-StyleRuleViewTransitions::StyleRuleViewTransitions(
-    const StyleRuleViewTransitions&) = default;
-
-StyleRuleViewTransitions::~StyleRuleViewTransitions() = default;
-
-const CSSValue* StyleRuleViewTransitions::GetNavigationTrigger() const {
-  return navigation_trigger_.Get();
-}
-
-void StyleRuleViewTransitions::SetNavigationTrigger(const CSSValue* new_value) {
-  navigation_trigger_ = new_value;
-}
-
-void StyleRuleViewTransitions::TraceAfterDispatch(
-    blink::Visitor* visitor) const {
-  visitor->Trace(layer_);
-  visitor->Trace(navigation_trigger_);
-  StyleRuleBase::TraceAfterDispatch(visitor);
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/css/style_rule_view_transitions.h b/third_party/blink/renderer/core/css/style_rule_view_transitions.h
deleted file mode 100644
index 77f1dd22..0000000
--- a/third_party/blink/renderer/core/css/style_rule_view_transitions.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_RULE_VIEW_TRANSITIONS_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_RULE_VIEW_TRANSITIONS_H_
-
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/css/style_rule.h"
-
-namespace blink {
-
-class CORE_EXPORT StyleRuleViewTransitions : public StyleRuleBase {
- public:
-  explicit StyleRuleViewTransitions(CSSPropertyValueSet&);
-  StyleRuleViewTransitions(const StyleRuleViewTransitions&);
-  ~StyleRuleViewTransitions();
-
-  const CSSValue* GetNavigationTrigger() const;
-  void SetNavigationTrigger(const CSSValue* new_value);
-
-  StyleRuleViewTransitions* Copy() const {
-    return MakeGarbageCollected<StyleRuleViewTransitions>(*this);
-  }
-
-  void SetCascadeLayer(const CascadeLayer* layer) { layer_ = layer; }
-  const CascadeLayer* GetCascadeLayer() const { return layer_.Get(); }
-
-  void TraceAfterDispatch(blink::Visitor*) const;
-
- private:
-  Member<const CascadeLayer> layer_;
-  Member<const CSSValue> navigation_trigger_;
-};
-
-template <>
-struct DowncastTraits<StyleRuleViewTransitions> {
-  static bool AllowFrom(const StyleRuleBase& rule) {
-    return rule.IsViewTransitionsRule();
-  }
-};
-
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_STYLE_RULE_VIEW_TRANSITIONS_H_
diff --git a/third_party/blink/renderer/core/css/style_sheet_contents.cc b/third_party/blink/renderer/core/css/style_sheet_contents.cc
index 5c5d32e..4346f530 100644
--- a/third_party/blink/renderer/core/css/style_sheet_contents.cc
+++ b/third_party/blink/renderer/core/css/style_sheet_contents.cc
@@ -664,7 +664,7 @@
       case StyleRuleBase::kFontFeature:
       case StyleRuleBase::kPositionFallback:
       case StyleRuleBase::kTry:
-      case StyleRuleBase::kViewTransitions:
+      case StyleRuleBase::kViewTransition:
         break;
       case StyleRuleBase::kCounterStyle:
         if (To<StyleRuleCounterStyle>(rule)
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 71c8ebc..0d2ac4c 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -9030,6 +9030,12 @@
              mojom::blink::PreferredColorScheme::kDark;
 }
 
+const ui::ColorProvider* Document::GetColorProviderForPainting(
+    mojom::blink::ColorScheme color_scheme) const {
+  return GetPage()->GetColorProviderForPainting(
+      color_scheme, in_forced_colors_mode_);
+}
+
 void Document::CountUse(mojom::WebFeature feature) const {
   if (execution_context_)
     execution_context_->CountUse(feature);
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
index 79c27f4..4cb5a1b 100644
--- a/third_party/blink/renderer/core/dom/document.h
+++ b/third_party/blink/renderer/core/dom/document.h
@@ -124,6 +124,10 @@
 }  // namespace mojom
 }  // namespace network
 
+namespace ui {
+class ColorProvider;
+}  // namespace ui
+
 namespace blink {
 
 class AXContext;
@@ -1850,6 +1854,9 @@
   bool InForcedColorsMode() const;
   bool InDarkMode();
 
+  const ui::ColorProvider* GetColorProviderForPainting(
+      mojom::blink::ColorScheme color_scheme) const;
+
   // Capture the toggle event during parsing either by HTML parser or XML
   // parser.
   void SetToggleDuringParsing(bool toggle_during_parsing) {
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.cc b/third_party/blink/renderer/core/exported/web_settings_impl.cc
index b68ed9ed..d446ebf 100644
--- a/third_party/blink/renderer/core/exported/web_settings_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_settings_impl.cc
@@ -728,34 +728,28 @@
   settings_->SetLazyFrameLoadingDistanceThresholdPx4G(distance_px);
 }
 
-void WebSettingsImpl::SetLazyImageLoadingDistanceThresholdPxUnknown(
-    int distance_px) {
-  settings_->SetLazyImageLoadingDistanceThresholdPxUnknown(distance_px);
+void WebSettingsImpl::SetLazyLoadingImageMarginPxUnknown(int distance_px) {
+  settings_->SetLazyLoadingImageMarginPxUnknown(distance_px);
 }
 
-void WebSettingsImpl::SetLazyImageLoadingDistanceThresholdPxOffline(
-    int distance_px) {
-  settings_->SetLazyImageLoadingDistanceThresholdPxOffline(distance_px);
+void WebSettingsImpl::SetLazyLoadingImageMarginPxOffline(int distance_px) {
+  settings_->SetLazyLoadingImageMarginPxOffline(distance_px);
 }
 
-void WebSettingsImpl::SetLazyImageLoadingDistanceThresholdPxSlow2G(
-    int distance_px) {
-  settings_->SetLazyImageLoadingDistanceThresholdPxSlow2G(distance_px);
+void WebSettingsImpl::SetLazyLoadingImageMarginPxSlow2G(int distance_px) {
+  settings_->SetLazyLoadingImageMarginPxSlow2G(distance_px);
 }
 
-void WebSettingsImpl::SetLazyImageLoadingDistanceThresholdPx2G(
-    int distance_px) {
-  settings_->SetLazyImageLoadingDistanceThresholdPx2G(distance_px);
+void WebSettingsImpl::SetLazyLoadingImageMarginPx2G(int distance_px) {
+  settings_->SetLazyLoadingImageMarginPx2G(distance_px);
 }
 
-void WebSettingsImpl::SetLazyImageLoadingDistanceThresholdPx3G(
-    int distance_px) {
-  settings_->SetLazyImageLoadingDistanceThresholdPx3G(distance_px);
+void WebSettingsImpl::SetLazyLoadingImageMarginPx3G(int distance_px) {
+  settings_->SetLazyLoadingImageMarginPx3G(distance_px);
 }
 
-void WebSettingsImpl::SetLazyImageLoadingDistanceThresholdPx4G(
-    int distance_px) {
-  settings_->SetLazyImageLoadingDistanceThresholdPx4G(distance_px);
+void WebSettingsImpl::SetLazyLoadingImageMarginPx4G(int distance_px) {
+  settings_->SetLazyLoadingImageMarginPx4G(distance_px);
 }
 
 void WebSettingsImpl::SetForceDarkModeEnabled(bool enabled) {
diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.h b/third_party/blink/renderer/core/exported/web_settings_impl.h
index 0898729..1010561 100644
--- a/third_party/blink/renderer/core/exported/web_settings_impl.h
+++ b/third_party/blink/renderer/core/exported/web_settings_impl.h
@@ -212,12 +212,12 @@
   void SetLazyFrameLoadingDistanceThresholdPx2G(int) override;
   void SetLazyFrameLoadingDistanceThresholdPx3G(int) override;
   void SetLazyFrameLoadingDistanceThresholdPx4G(int) override;
-  void SetLazyImageLoadingDistanceThresholdPxUnknown(int) override;
-  void SetLazyImageLoadingDistanceThresholdPxOffline(int) override;
-  void SetLazyImageLoadingDistanceThresholdPxSlow2G(int) override;
-  void SetLazyImageLoadingDistanceThresholdPx2G(int) override;
-  void SetLazyImageLoadingDistanceThresholdPx3G(int) override;
-  void SetLazyImageLoadingDistanceThresholdPx4G(int) override;
+  void SetLazyLoadingImageMarginPxUnknown(int) override;
+  void SetLazyLoadingImageMarginPxOffline(int) override;
+  void SetLazyLoadingImageMarginPxSlow2G(int) override;
+  void SetLazyLoadingImageMarginPx2G(int) override;
+  void SetLazyLoadingImageMarginPx3G(int) override;
+  void SetLazyLoadingImageMarginPx4G(int) override;
 
   void SetForceDarkModeEnabled(bool) override;
   void SetPreferredColorScheme(mojom::blink::PreferredColorScheme) override;
diff --git a/third_party/blink/renderer/core/frame/frame_serializer.cc b/third_party/blink/renderer/core/frame/frame_serializer.cc
index 71e4542..526ddfed 100644
--- a/third_party/blink/renderer/core/frame/frame_serializer.cc
+++ b/third_party/blink/renderer/core/frame/frame_serializer.cc
@@ -471,7 +471,7 @@
     case CSSRule::kLayerStatementRule:
     case CSSRule::kPositionFallbackRule:
     case CSSRule::kTryRule:
-    case CSSRule::kViewTransitionsRule:
+    case CSSRule::kViewTransitionRule:
       break;
   }
 }
diff --git a/third_party/blink/renderer/core/frame/navigator_ua.cc b/third_party/blink/renderer/core/frame/navigator_ua.cc
index d77bc90..e93c0d7c 100644
--- a/third_party/blink/renderer/core/frame/navigator_ua.cc
+++ b/third_party/blink/renderer/core/frame/navigator_ua.cc
@@ -26,7 +26,13 @@
   ua_data->SetBitness(String::FromUTF8(metadata.bitness));
   ua_data->SetFullVersionList(metadata.brand_full_version_list);
   ua_data->SetWoW64(metadata.wow64);
-  ua_data->SetFormFactor(String::FromUTF8(metadata.form_factor));
+  Vector<String> form_factor;
+  form_factor.reserve(
+      base::checked_cast<wtf_size_t>(metadata.form_factor.size()));
+  for (auto& ff : metadata.form_factor) {
+    form_factor.push_back(String::FromUTF8(ff));
+  }
+  ua_data->SetFormFactor(std::move(form_factor));
 
   return ua_data;
 }
diff --git a/third_party/blink/renderer/core/frame/navigator_ua_data.cc b/third_party/blink/renderer/core/frame/navigator_ua_data.cc
index 0a8e6c4..c3b785db 100644
--- a/third_party/blink/renderer/core/frame/navigator_ua_data.cc
+++ b/third_party/blink/renderer/core/frame/navigator_ua_data.cc
@@ -28,18 +28,42 @@
 // getHighEntropyValues() call if the user is in the study.
 void MaybeRecordMetric(bool record_identifiability,
                        const String& hint,
-                       const String& value,
+                       const IdentifiableToken token,
                        ExecutionContext* execution_context) {
-  if (LIKELY(!record_identifiability))
+  if (LIKELY(!record_identifiability)) {
     return;
+  }
   auto identifiable_surface = IdentifiableSurface::FromTypeAndToken(
       IdentifiableSurface::Type::kNavigatorUAData_GetHighEntropyValues,
       IdentifiableToken(hint.Utf8()));
   IdentifiabilityMetricBuilder(execution_context->UkmSourceID())
-      .Add(identifiable_surface, IdentifiableToken(value.Utf8()))
+      .Add(identifiable_surface, token)
       .Record(execution_context->UkmRecorder());
 }
 
+void MaybeRecordMetric(bool record_identifiability,
+                       const String& hint,
+                       const String& value,
+                       ExecutionContext* execution_context) {
+  MaybeRecordMetric(record_identifiability, hint,
+                    IdentifiableToken(value.Utf8()), execution_context);
+}
+
+void MaybeRecordMetric(bool record_identifiability,
+                       const String& hint,
+                       const Vector<String>& strings,
+                       ExecutionContext* execution_context) {
+  if (LIKELY(!record_identifiability)) {
+    return;
+  }
+  IdentifiableTokenBuilder token_builder;
+  for (const auto& s : strings) {
+    token_builder.AddAtomic(s.Utf8());
+  }
+  MaybeRecordMetric(record_identifiability, hint, token_builder.GetToken(),
+                    execution_context);
+}
+
 }  // namespace
 
 NavigatorUAData::NavigatorUAData(ExecutionContext* context)
@@ -111,8 +135,8 @@
   is_wow64_ = wow64;
 }
 
-void NavigatorUAData::SetFormFactor(const String& form_factor) {
-  form_factor_ = form_factor;
+void NavigatorUAData::SetFormFactor(Vector<String> form_factor) {
+  form_factor_ = std::move(form_factor);
 }
 
 bool NavigatorUAData::mobile() const {
diff --git a/third_party/blink/renderer/core/frame/navigator_ua_data.h b/third_party/blink/renderer/core/frame/navigator_ua_data.h
index 71bdad5..10c6cb8 100644
--- a/third_party/blink/renderer/core/frame/navigator_ua_data.h
+++ b/third_party/blink/renderer/core/frame/navigator_ua_data.h
@@ -37,7 +37,7 @@
   void SetUAFullVersion(const String& uaFullVersion);
   void SetBitness(const String& bitness);
   void SetWoW64(bool wow64);
-  void SetFormFactor(const String& form_factor);
+  void SetFormFactor(Vector<String> form_factor);
 
   // IDL implementation
   const HeapVector<Member<NavigatorUABrandVersion>>& brands() const;
@@ -60,7 +60,7 @@
   String ua_full_version_;
   String bitness_;
   bool is_wow64_ = false;
-  String form_factor_;
+  Vector<String> form_factor_;
 
   void AddBrandVersion(const String& brand, const String& version);
   void AddBrandFullVersion(const String& brand, const String& version);
diff --git a/third_party/blink/renderer/core/frame/settings.json5 b/third_party/blink/renderer/core/frame/settings.json5
index eb6fa41..a383aca 100644
--- a/third_party/blink/renderer/core/frame/settings.json5
+++ b/third_party/blink/renderer/core/frame/settings.json5
@@ -977,35 +977,35 @@
     },
 
     //
-    // Lazy image loading distance-from-viewport thresholds for different effective connection types.
+    // Lazy loading image margins for different effective connection types.
     //
     {
-      name: "lazyImageLoadingDistanceThresholdPxUnknown",
+      name: "lazyLoadingImageMarginPxUnknown",
       initial: 3000,
       type: "int",
     },
     {
-      name: "lazyImageLoadingDistanceThresholdPxOffline",
+      name: "lazyLoadingImageMarginPxOffline",
       initial: 8000,
       type: "int",
     },
     {
-      name: "lazyImageLoadingDistanceThresholdPxSlow2G",
+      name: "lazyLoadingImageMarginPxSlow2G",
       initial: 8000,
       type: "int",
     },
     {
-      name: "lazyImageLoadingDistanceThresholdPx2G",
+      name: "lazyLoadingImageMarginPx2G",
       initial: 6000,
       type: "int",
     },
     {
-      name: "lazyImageLoadingDistanceThresholdPx3G",
+      name: "lazyLoadingImageMarginPx3G",
       initial: 2500,
       type: "int",
     },
     {
-      name: "lazyImageLoadingDistanceThresholdPx4G",
+      name: "lazyLoadingImageMarginPx4G",
       initial: 1250,
       type: "int",
     },
diff --git a/third_party/blink/renderer/core/frame/ua_data_values.idl b/third_party/blink/renderer/core/frame/ua_data_values.idl
index bbb6996..dbffccf 100644
--- a/third_party/blink/renderer/core/frame/ua_data_values.idl
+++ b/third_party/blink/renderer/core/frame/ua_data_values.idl
@@ -15,5 +15,5 @@
   DOMString bitness;
   sequence<NavigatorUABrandVersion> fullVersionList;
   boolean wow64;
-  DOMString formFactor;
+  sequence<DOMString> formFactor;
 };
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer.cc b/third_party/blink/renderer/core/html/lazy_load_image_observer.cc
index fc7b7a2..0922440 100644
--- a/third_party/blink/renderer/core/html/lazy_load_image_observer.cc
+++ b/third_party/blink/renderer/core/html/lazy_load_image_observer.cc
@@ -31,29 +31,6 @@
 
 namespace {
 
-int GetLazyImageLoadingViewportDistanceThresholdPx(const Document& document) {
-  const Settings* settings = document.GetSettings();
-  if (!settings)
-    return 0;
-
-  switch (GetNetworkStateNotifier().EffectiveType()) {
-    case WebEffectiveConnectionType::kTypeUnknown:
-      return settings->GetLazyImageLoadingDistanceThresholdPxUnknown();
-    case WebEffectiveConnectionType::kTypeOffline:
-      return settings->GetLazyImageLoadingDistanceThresholdPxOffline();
-    case WebEffectiveConnectionType::kTypeSlow2G:
-      return settings->GetLazyImageLoadingDistanceThresholdPxSlow2G();
-    case WebEffectiveConnectionType::kType2G:
-      return settings->GetLazyImageLoadingDistanceThresholdPx2G();
-    case WebEffectiveConnectionType::kType3G:
-      return settings->GetLazyImageLoadingDistanceThresholdPx3G();
-    case WebEffectiveConnectionType::kType4G:
-      return settings->GetLazyImageLoadingDistanceThresholdPx4G();
-  }
-  NOTREACHED();
-  return 0;
-}
-
 // Returns if the element or its ancestors are invisible, due to their style or
 // attribute or due to themselves not connected to the main document tree.
 bool IsElementInInvisibleSubTree(const Element& element) {
@@ -147,7 +124,7 @@
 }  // namespace
 
 LazyLoadImageObserver::LazyLoadImageObserver(const Document& root_document) {
-  use_viewport_distance_threshold_ =
+  use_margin_ =
       !RuntimeEnabledFeatures::DelayOutOfViewportLazyImagesEnabled() ||
       root_document.LoadEventFinished();
 }
@@ -330,11 +307,11 @@
   if (!RuntimeEnabledFeatures::DelayOutOfViewportLazyImagesEnabled()) {
     return;
   }
-  if (use_viewport_distance_threshold_) {
+  if (use_margin_) {
     return;
   }
 
-  use_viewport_distance_threshold_ = true;
+  use_margin_ = true;
 
   if (lazy_load_intersection_observer_) {
     // Intersection observer doesn't support dynamic margin changes so we just
@@ -345,15 +322,15 @@
 
 void LazyLoadImageObserver::CreateLazyLoadIntersectionObserver(
     Document* root_document) {
-  int viewport_threshold =
-      use_viewport_distance_threshold_
-          ? GetLazyImageLoadingViewportDistanceThresholdPx(*root_document)
-          : 0;
+  int margin = GetLazyLoadingImageMarginPx(*root_document);
   IntersectionObserver* new_observer = IntersectionObserver::Create(
-      {Length::Fixed(viewport_threshold)}, {std::numeric_limits<float>::min()},
-      root_document,
+      /* (root) margin */ {Length::Fixed(margin)},
+      /* thresholds */ {std::numeric_limits<float>::min()},
+      /* document */ root_document,
+      /* callback */
       WTF::BindRepeating(&LazyLoadImageObserver::LoadIfNearViewport,
                          WrapWeakPersistent(this)),
+      /* ukm_metric_id */
       LocalFrameUkmAggregator::kLazyLoadIntersectionObserver);
 
   if (lazy_load_intersection_observer_) {
@@ -372,4 +349,34 @@
   visitor->Trace(visibility_metrics_observer_);
 }
 
+int LazyLoadImageObserver::GetLazyLoadingImageMarginPx(
+    const Document& document) {
+  if (!use_margin_) {
+    return 0;
+  }
+
+  const Settings* settings = document.GetSettings();
+  if (!settings) {
+    return 0;
+  }
+
+  switch (GetNetworkStateNotifier().EffectiveType()) {
+    case WebEffectiveConnectionType::kTypeUnknown:
+      return settings->GetLazyLoadingImageMarginPxUnknown();
+    case WebEffectiveConnectionType::kTypeOffline:
+      return settings->GetLazyLoadingImageMarginPxOffline();
+    case WebEffectiveConnectionType::kTypeSlow2G:
+      return settings->GetLazyLoadingImageMarginPxSlow2G();
+    case WebEffectiveConnectionType::kType2G:
+      return settings->GetLazyLoadingImageMarginPx2G();
+    case WebEffectiveConnectionType::kType3G:
+      return settings->GetLazyLoadingImageMarginPx3G();
+    case WebEffectiveConnectionType::kType4G:
+      return settings->GetLazyLoadingImageMarginPx4G();
+    default:
+      NOTREACHED();
+      return 0;
+  }
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer.h b/third_party/blink/renderer/core/html/lazy_load_image_observer.h
index f6ad252..be8d8db 100644
--- a/third_party/blink/renderer/core/html/lazy_load_image_observer.h
+++ b/third_party/blink/renderer/core/html/lazy_load_image_observer.h
@@ -61,10 +61,12 @@
 
   void CreateLazyLoadIntersectionObserver(Document* root_document);
 
-  // True if `lazy_load_intersection_observer_` should use a non-zero threshold
-  // for the viewport. True by default and used by DelayOutOfViewportLazyImages
-  // to not use a threshold while loading.
-  bool use_viewport_distance_threshold_;
+  int GetLazyLoadingImageMarginPx(const Document& document);
+
+  // True if `lazy_load_intersection_observer_` should use a non-zero margin
+  // for it's intersection observer. True by default and used by
+  // DelayOutOfViewportLazyImages to not use a margin while loading.
+  bool use_margin_;
 
   // The intersection observer responsible for loading the image once it's near
   // the viewport.
diff --git a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
index 5fd6dfc..34e5d29 100644
--- a/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
+++ b/third_party/blink/renderer/core/html/lazy_load_image_observer_test.cc
@@ -178,19 +178,19 @@
     Settings& settings = WebView().GetPage()->GetSettings();
 
     // These should match the values that would be returned by
-    // GetLoadingDistanceThreshold().
-    settings.SetLazyImageLoadingDistanceThresholdPxUnknown(200);
-    settings.SetLazyImageLoadingDistanceThresholdPxOffline(300);
-    settings.SetLazyImageLoadingDistanceThresholdPxSlow2G(400);
-    settings.SetLazyImageLoadingDistanceThresholdPx2G(500);
-    settings.SetLazyImageLoadingDistanceThresholdPx3G(600);
-    settings.SetLazyImageLoadingDistanceThresholdPx4G(700);
+    // GetMargin().
+    settings.SetLazyLoadingImageMarginPxUnknown(200);
+    settings.SetLazyLoadingImageMarginPxOffline(300);
+    settings.SetLazyLoadingImageMarginPxSlow2G(400);
+    settings.SetLazyLoadingImageMarginPx2G(500);
+    settings.SetLazyLoadingImageMarginPx3G(600);
+    settings.SetLazyLoadingImageMarginPx4G(700);
   }
 
-  // When DelayOutOfViewportLazyImages is enabled, this returns the threshold
-  // that will be used after the document has finished loading, as a threshold
+  // When DelayOutOfViewportLazyImages is enabled, this returns the margin
+  // that will be used after the document has finished loading, as a margin
   // of zero is used during loading.
-  int GetLoadingDistanceThreshold() const {
+  int GetMargin() const {
     static constexpr int kDistanceThresholdByEffectiveConnectionType[] = {
         200, 300, 400, 500, 600, 700};
     return kDistanceThresholdByEffectiveConnectionType[static_cast<int>(
@@ -231,7 +231,7 @@
         <img src='https://example.com/unset.png'
              onload='console.log("unset onload");' />
         </body>)HTML",
-      kViewportHeight + GetLoadingDistanceThreshold() - 100));
+      kViewportHeight + GetMargin() - 100));
 
   css_resource.Complete("img { width: 50px; height: 50px; }");
   test::RunPendingTasks();
@@ -316,7 +316,7 @@
         <img src='https://example.com/unset.png'
              onload='console.log("unset onload");' />
         </body>)HTML",
-      kViewportHeight + GetLoadingDistanceThreshold() + 100));
+      kViewportHeight + GetMargin() + 100));
 
   css_resource.Complete("img { width: 50px; height: 50px; }");
   test::RunPendingTasks();
@@ -399,8 +399,7 @@
         gfx::Size(kViewportWidth, kViewportHeight));
 
     Settings& settings = WebView().GetPage()->GetSettings();
-    settings.SetLazyImageLoadingDistanceThresholdPx4G(
-        kLoadingDistanceThreshold);
+    settings.SetLazyLoadingImageMarginPx4G(kLoadingDistanceThreshold);
     settings.SetLazyFrameLoadingDistanceThresholdPx4G(
         kLoadingDistanceThreshold);
   }
@@ -1143,7 +1142,7 @@
         gfx::Size(kViewportWidth, kViewportHeight));
 
     Settings& settings = WebView().GetPage()->GetSettings();
-    settings.SetLazyImageLoadingDistanceThresholdPx4G(kDistanceThresholdPx);
+    settings.SetLazyLoadingImageMarginPx4G(kDistanceThresholdPx);
   }
 
  private:
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 9f63caa..063fb41 100644
--- a/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
@@ -871,7 +871,7 @@
       case StyleRule::kKeyframe:
       case StyleRule::kFontFeature:
       case StyleRule::kTry:
-      case StyleRule::kViewTransitions:
+      case StyleRule::kViewTransition:
         result->push_back(data);
         break;
       case StyleRule::kStyle:
@@ -953,7 +953,7 @@
       case CSSRule::kKeyframeRule:
       case CSSRule::kFontFeatureRule:
       case CSSRule::kTryRule:
-      case CSSRule::kViewTransitionsRule:
+      case CSSRule::kViewTransitionRule:
       case CSSRule::kFontPaletteValuesRule:
         result->push_back(rule);
         break;
diff --git a/third_party/blink/renderer/core/layout/grid/grid_data.h b/third_party/blink/renderer/core/layout/grid/grid_data.h
index ba174f1..831ad080 100644
--- a/third_party/blink/renderer/core/layout/grid/grid_data.h
+++ b/third_party/blink/renderer/core/layout/grid/grid_data.h
@@ -248,8 +248,9 @@
  public:
   GridLayoutSubtree() = default;
 
-  explicit GridLayoutSubtree(scoped_refptr<const GridLayoutTree>&& layout_tree)
-      : GridSubtree(std::move(layout_tree)) {}
+  explicit GridLayoutSubtree(scoped_refptr<const GridLayoutTree> layout_tree,
+                             wtf_size_t subtree_root = 0)
+      : GridSubtree(std::move(layout_tree), subtree_root) {}
 
   GridLayoutSubtree(const scoped_refptr<const GridLayoutTree>& layout_tree,
                     wtf_size_t parent_end_index,
diff --git a/third_party/blink/renderer/core/layout/grid/grid_layout_algorithm.cc b/third_party/blink/renderer/core/layout/grid/grid_layout_algorithm.cc
index f032ef0..5efae04 100644
--- a/third_party/blink/renderer/core/layout/grid/grid_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/grid/grid_layout_algorithm.cc
@@ -1503,7 +1503,7 @@
 }
 
 void GridLayoutAlgorithm::ComputeGridItemBaselines(
-    const GridLayoutSubtree& layout_subtree,
+    const scoped_refptr<const GridLayoutTree>& layout_tree,
     const GridSizingSubtree& sizing_subtree,
     GridTrackSizingDirection track_direction,
     SizingConstraint sizing_constraint) const {
@@ -1516,10 +1516,8 @@
   }
 
   const auto writing_mode = ConstraintSpace().GetWritingMode();
-
   track_collection.ResetBaselines();
 
-  auto next_subgrid_subtree = layout_subtree.FirstChild();
   for (auto& grid_item : sizing_data.grid_items) {
     if (!grid_item.IsBaselineSpecified(track_direction) ||
         !grid_item.IsConsideredForSizing(track_direction)) {
@@ -1528,9 +1526,8 @@
 
     GridLayoutSubtree subgrid_layout_subtree;
     if (grid_item.IsSubgrid()) {
-      DCHECK(next_subgrid_subtree);
-      subgrid_layout_subtree = next_subgrid_subtree;
-      next_subgrid_subtree = next_subgrid_subtree.NextSibling();
+      subgrid_layout_subtree = GridLayoutSubtree(
+          layout_tree, sizing_subtree.LookupSubgridIndex(grid_item));
     }
 
     const auto subgridded_item =
@@ -1701,6 +1698,10 @@
         track_collection.CacheInitializedSetsGeometry(
             start_border_scrollbar_padding);
       }
+
+      if (track_collection.HasBaselines()) {
+        track_collection.ResetBaselines();
+      }
     }
   };
 
@@ -1904,10 +1905,11 @@
     GridTrackSizingDirection track_direction,
     SizingConstraint sizing_constraint,
     bool* opt_needs_additional_pass) const {
-  ComputeBaselineAlignment(GridLayoutSubtree(sizing_tree.FinalizeTree()),
+  ComputeBaselineAlignment(sizing_tree.FinalizeTree(),
                            GridSizingSubtree(sizing_tree),
                            /* opt_subgrid_data */ kNoSubgriddedItemData,
                            track_direction, sizing_constraint);
+
   CompleteTrackSizingAlgorithm(GridSizingSubtree(sizing_tree),
                                /* opt_subgrid_data */ kNoSubgriddedItemData,
                                track_direction, sizing_constraint,
@@ -1915,7 +1917,7 @@
 }
 
 void GridLayoutAlgorithm::ComputeBaselineAlignment(
-    const GridLayoutSubtree& layout_subtree,
+    const scoped_refptr<const GridLayoutTree>& layout_tree,
     const GridSizingSubtree& sizing_subtree,
     const SubgriddedItemData& opt_subgrid_data,
     const absl::optional<GridTrackSizingDirection>& opt_track_direction,
@@ -1942,8 +1944,8 @@
                 opt_subgrid_data, track_direction));
           }
         } else {
-          ComputeGridItemBaselines(layout_subtree, sizing_subtree,
-                                   track_direction, sizing_constraint);
+          ComputeGridItemBaselines(layout_tree, sizing_subtree, track_direction,
+                                   sizing_constraint);
         }
       };
 
@@ -1954,28 +1956,24 @@
     ComputeOrRecreateBaselines(kForRows);
   }
 
-  auto next_layout_subtree = layout_subtree.FirstChild();
   ForEachSubgrid(sizing_subtree,
                  [&](const GridLayoutAlgorithm& subgrid_algorithm,
                      const GridSizingSubtree& subgrid_subtree,
                      const SubgriddedItemData& subgrid_data) {
-                   DCHECK(next_layout_subtree);
                    subgrid_algorithm.ComputeBaselineAlignment(
-                       next_layout_subtree, subgrid_subtree, subgrid_data,
+                       layout_tree, subgrid_subtree, subgrid_data,
                        RelativeDirectionFilterInSubgrid(opt_track_direction,
                                                         *subgrid_data),
                        sizing_constraint);
-                   next_layout_subtree = next_layout_subtree.NextSibling();
                  });
 }
 
 void GridLayoutAlgorithm::CompleteFinalBaselineAlignment(
     const GridSizingTree& sizing_tree) const {
-  ComputeBaselineAlignment(GridLayoutSubtree(sizing_tree.FinalizeTree()),
-                           GridSizingSubtree(sizing_tree),
-                           /* opt_subgrid_data */ kNoSubgriddedItemData,
-                           /* opt_track_direction */ absl::nullopt,
-                           SizingConstraint::kLayout);
+  ComputeBaselineAlignment(
+      sizing_tree.FinalizeTree(), GridSizingSubtree(sizing_tree),
+      /* opt_subgrid_data */ kNoSubgriddedItemData,
+      /* opt_track_direction */ absl::nullopt, SizingConstraint::kLayout);
 }
 
 template <typename CallbackFunc>
diff --git a/third_party/blink/renderer/core/layout/grid/grid_layout_algorithm.h b/third_party/blink/renderer/core/layout/grid/grid_layout_algorithm.h
index 63a73930..b7d15c5b 100644
--- a/third_party/blink/renderer/core/layout/grid/grid_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/grid/grid_layout_algorithm.h
@@ -105,11 +105,12 @@
       GridTrackSizingDirection track_direction) const;
 
   // Determines the major/minor alignment baselines for each row/column based on
-  // each item in |grid_items|, and stores the results in |track_collection|.
-  void ComputeGridItemBaselines(const GridLayoutSubtree& layout_subtree,
-                                const GridSizingSubtree& sizing_subtree,
-                                GridTrackSizingDirection track_direction,
-                                SizingConstraint sizing_constraint) const;
+  // each item in `grid_items`, and stores the results in `track_collection`.
+  void ComputeGridItemBaselines(
+      const scoped_refptr<const GridLayoutTree>& layout_tree,
+      const GridSizingSubtree& sizing_subtree,
+      GridTrackSizingDirection track_direction,
+      SizingConstraint sizing_constraint) const;
 
   std::unique_ptr<GridLayoutTrackCollection> CreateSubgridTrackCollection(
       const SubgriddedItemData& subgrid_data,
@@ -153,11 +154,11 @@
 
   // Performs the final baseline alignment pass of a grid sizing subtree.
   void ComputeBaselineAlignment(
-      const GridLayoutSubtree& layout_subtree,
+      const scoped_refptr<const GridLayoutTree>& layout_tree,
       const GridSizingSubtree& sizing_subtree,
       const SubgriddedItemData& opt_subgrid_data,
       const absl::optional<GridTrackSizingDirection>& opt_track_direction,
-      SizingConstraint) const;
+      SizingConstraint sizing_constraint) const;
 
   // Helper that calls the method above for the entire grid sizing tree.
   void CompleteFinalBaselineAlignment(const GridSizingTree& sizing_tree) const;
diff --git a/third_party/blink/renderer/core/layout/grid/grid_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/grid/grid_layout_algorithm_test.cc
index 5652c97..9ee8b6b2 100644
--- a/third_party/blink/renderer/core/layout/grid/grid_layout_algorithm_test.cc
+++ b/third_party/blink/renderer/core/layout/grid/grid_layout_algorithm_test.cc
@@ -27,11 +27,8 @@
 
 }  // namespace
 
-class GridLayoutAlgorithmTest : public NGBaseLayoutAlgorithmTest,
-                                private ScopedLayoutNGSubgridForTest {
+class GridLayoutAlgorithmTest : public NGBaseLayoutAlgorithmTest {
  protected:
-  GridLayoutAlgorithmTest() : ScopedLayoutNGSubgridForTest(true) {}
-
   void SetUp() override { NGBaseLayoutAlgorithmTest::SetUp(); }
 
   void BuildGridItemsAndTrackCollections(GridLayoutAlgorithm& algorithm) {
diff --git a/third_party/blink/renderer/core/layout/grid/grid_named_line_collection.cc b/third_party/blink/renderer/core/layout/grid/grid_named_line_collection.cc
index ae5bf98..c24650f 100644
--- a/third_party/blink/renderer/core/layout/grid/grid_named_line_collection.cc
+++ b/third_party/blink/renderer/core/layout/grid/grid_named_line_collection.cc
@@ -28,9 +28,7 @@
   // Line names from the container style are valid when the grid axis type is a
   // standalone grid or the axis is a subgrid and the parent is a grid. See:
   // https://www.w3.org/TR/css-grid-2/#subgrid-listing
-  bool are_named_lines_valid = true;
-  if (RuntimeEnabledFeatures::LayoutNGSubgridEnabled())
-    are_named_lines_valid = is_subgridded_to_parent || is_standalone_grid_;
+  bool are_named_lines_valid = is_subgridded_to_parent || is_standalone_grid_;
 
   const NamedGridLinesMap& auto_repeat_grid_line_names =
       computed_grid_track_list.auto_repeat_named_grid_lines;
diff --git a/third_party/blink/renderer/core/layout/grid/grid_sizing_tree.h b/third_party/blink/renderer/core/layout/grid/grid_sizing_tree.h
index dc6a82e..7b76cbb 100644
--- a/third_party/blink/renderer/core/layout/grid/grid_sizing_tree.h
+++ b/third_party/blink/renderer/core/layout/grid/grid_sizing_tree.h
@@ -177,6 +177,12 @@
     return grid_tree_->LookupSubgriddedItemData(grid_item);
   }
 
+  wtf_size_t LookupSubgridIndex(const GridItemData& subgrid_data) const {
+    DCHECK(grid_tree_);
+    DCHECK(subgrid_data.IsSubgrid());
+    return grid_tree_->LookupSubgridIndex(subgrid_data);
+  }
+
   GridSizingSubtree SubgridSizingSubtree(
       const GridItemData& subgrid_data) const {
     DCHECK(grid_tree_);
diff --git a/third_party/blink/renderer/core/layout/grid/grid_subtree.h b/third_party/blink/renderer/core/layout/grid/grid_subtree.h
index 1411e46..b4c844b 100644
--- a/third_party/blink/renderer/core/layout/grid/grid_subtree.h
+++ b/third_party/blink/renderer/core/layout/grid/grid_subtree.h
@@ -60,9 +60,8 @@
  protected:
   GridSubtree() = default;
 
-  explicit GridSubtree(GridTreePtr grid_tree, wtf_size_t subtree_root = 0)
+  explicit GridSubtree(GridTreePtr grid_tree, wtf_size_t subtree_root)
       : grid_tree_(std::move(grid_tree)), subtree_root_(subtree_root) {
-    DCHECK(grid_tree_);
     parent_end_index_ = NextSiblingIndex();
   }
 
@@ -88,7 +87,11 @@
 
  private:
   wtf_size_t NextSiblingIndex() const {
-    return subtree_root_ + grid_tree_->SubtreeSize(subtree_root_);
+    DCHECK(grid_tree_);
+    const wtf_size_t subtree_size = grid_tree_->SubtreeSize(subtree_root_);
+
+    DCHECK_GT(subtree_size, 0u);
+    return subtree_root_ + subtree_size;
   }
 
   // Index of the next sibling of this subtree's parent; used to avoid iterating
diff --git a/third_party/blink/renderer/core/loader/base_fetch_context.cc b/third_party/blink/renderer/core/loader/base_fetch_context.cc
index 91e547c..758d94a 100644
--- a/third_party/blink/renderer/core/loader/base_fetch_context.cc
+++ b/third_party/blink/renderer/core/loader/base_fetch_context.cc
@@ -389,7 +389,7 @@
             network::mojom::blink::WebClientHintsType::kUAFormFactor,
             hints_preferences)) {
       SetHttpHeader(WebClientHintsType::kUAFormFactor,
-                    SerializeStringHeader(ua->form_factor), request);
+                    AtomicString(ua->SerializeFormFactor().c_str()), request);
     }
   }
 
diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
index 6f0e331..19b0139f 100644
--- a/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
+++ b/third_party/blink/renderer/core/loader/frame_fetch_context_test.cc
@@ -955,7 +955,7 @@
                  false, "");
     ExpectHeader("https://www.example.com/1.gif", "Sec-CH-UA-Model", false, "");
     ExpectHeader("https://www.example.com/1.gif", "Sec-CH-UA-Form-Factor", true,
-                 EmptyString());
+                 "");
 
     ExpectHeader("http://www.example.com/1.gif", "Sec-CH-UA-Arch", false, "");
     ExpectHeader("http://www.example.com/1.gif", "Sec-CH-UA-Platform-Version",
@@ -1118,7 +1118,7 @@
   ExpectHeader("https://www.example.com/1.gif", "Sec-CH-UA-Model", true,
                EmptyString());
   ExpectHeader("https://www.example.com/1.gif", "Sec-CH-UA-Form-Factor", true,
-               EmptyString());
+               "");
   ExpectHeader("https://www.example.com/1.gif", "Sec-CH-Prefers-Color-Scheme",
                true, "light");
   ExpectHeader("https://www.example.com/1.gif", "Sec-CH-Prefers-Reduced-Motion",
diff --git a/third_party/blink/renderer/core/page/page.cc b/third_party/blink/renderer/core/page/page.cc
index c059ec6..17d6e71 100644
--- a/third_party/blink/renderer/core/page/page.cc
+++ b/third_party/blink/renderer/core/page/page.cc
@@ -481,6 +481,18 @@
           color_provider_colors.forced_colors_map));
 }
 
+const ui::ColorProvider* Page::GetColorProviderForPainting(
+    mojom::blink::ColorScheme color_scheme,
+    bool in_forced_colors) const {
+  if (in_forced_colors) {
+    return forced_colors_color_provider_.get();
+  }
+
+  return color_scheme == mojom::blink::ColorScheme::kDark
+             ? dark_color_provider_.get()
+             : light_color_provider_.get();
+}
+
 void Page::InitialStyleChanged() {
   for (Frame* frame = MainFrame(); frame;
        frame = frame->Tree().TraverseNext()) {
diff --git a/third_party/blink/renderer/core/page/page.h b/third_party/blink/renderer/core/page/page.h
index cdd87b4..78bd30f 100644
--- a/third_party/blink/renderer/core/page/page.h
+++ b/third_party/blink/renderer/core/page/page.h
@@ -36,6 +36,7 @@
 #include "third_party/blink/public/common/page/browsing_context_group_info.h"
 #include "third_party/blink/public/mojom/devtools/inspector_issue.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/fenced_frame/fenced_frame.mojom-blink.h"
+#include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/frame/text_autosizer_page_info.mojom-blink.h"
 #include "third_party/blink/public/mojom/page/page.mojom-blink.h"
 #include "third_party/blink/public/mojom/page/page_visibility_state.mojom-blink.h"
@@ -163,6 +164,9 @@
 
   void UpdateColorProviders(
       const ColorProviderColorMaps& color_provider_colors);
+  const ui::ColorProvider* GetColorProviderForPainting(
+      mojom::blink::ColorScheme color_scheme,
+      bool in_forced_colors) const;
 
   void InitialStyleChanged();
   void UpdateAcceleratedCompositingSettings();
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
index 4356aa6..2340ed3 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -1251,24 +1251,44 @@
 
 mojom::blink::ColorScheme PaintLayerScrollableArea::UsedColorSchemeScrollbars()
     const {
-  if (RuntimeEnabledFeatures::UsedColorSchemeRootScrollbarsEnabled() &&
-      GetLayoutBox()->IsGlobalRootScroller() &&
-      !GetPageScrollbarTheme().UsesOverlayScrollbars()) {
-    const Document& document = GetLayoutBox()->GetDocument();
-    if (document.documentElement() &&
-        document.documentElement()->GetComputedStyle() &&
-        document.documentElement()->GetComputedStyle()->ColorScheme().empty() &&
-        document.GetStyleEngine().GetPageColorSchemes() ==
-            static_cast<ColorSchemeFlags>(ColorSchemeFlag::kNormal) &&
-        document.GetPreferredColorScheme() ==
-            mojom::blink::PreferredColorScheme::kDark) {
-      return mojom::blink::ColorScheme::kDark;
-    }
+  if (IsGlobalRootNonOverlayScroller() &&
+      GetLayoutBox()->StyleRef().ColorSchemeFlagsIsNormal() &&
+      GetLayoutBox()->GetDocument().GetPreferredColorScheme() ==
+          mojom::blink::PreferredColorScheme::kDark) {
+    return mojom::blink::ColorScheme::kDark;
   }
 
   return GetLayoutBox()->StyleRef().UsedColorScheme();
 }
 
+bool PaintLayerScrollableArea::UsedColorSchemeScrollbarsChanged(
+    const ComputedStyle* old_style) const {
+  if (!old_style) {
+    return false;
+  }
+
+  if (old_style->UsedColorScheme() !=
+      GetLayoutBox()->StyleRef().UsedColorScheme()) {
+    return true;
+  }
+
+  // Root scrollbars will be invalidated on preferred color scheme change
+  // so here we only check for the changes in color scheme flags.
+  if (IsGlobalRootNonOverlayScroller() &&
+      old_style->ColorSchemeFlagsIsNormal() !=
+          GetLayoutBox()->StyleRef().ColorSchemeFlagsIsNormal()) {
+    return true;
+  }
+
+  return false;
+}
+
+bool PaintLayerScrollableArea::IsGlobalRootNonOverlayScroller() const {
+  return RuntimeEnabledFeatures::UsedColorSchemeRootScrollbarsEnabled() &&
+         GetLayoutBox()->IsGlobalRootScroller() &&
+         !GetPageScrollbarTheme().UsesOverlayScrollbars();
+}
+
 bool PaintLayerScrollableArea::HasHorizontalOverflow() const {
   // TODO(szager): Make the algorithm for adding/subtracting overflow:auto
   // scrollbars memoryless (crbug.com/625300).  This client_width hack will
@@ -1335,8 +1355,7 @@
 
   UpdateScrollCornerStyle();
 
-  if (!old_style ||
-      old_style->UsedColorScheme() != UsedColorSchemeScrollbars() ||
+  if (!old_style || UsedColorSchemeScrollbarsChanged(old_style) ||
       old_style->ScrollbarThumbColorResolved() !=
           GetLayoutBox()->StyleRef().ScrollbarThumbColorResolved() ||
       old_style->ScrollbarTrackColorResolved() !=
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
index 82287df..eb17eca 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -682,6 +682,9 @@
 
   void SetShouldCheckForPaintInvalidation();
 
+  bool UsedColorSchemeScrollbarsChanged(const ComputedStyle* old_style) const;
+  bool IsGlobalRootNonOverlayScroller() const;
+
   // PaintLayer is destructed before PaintLayerScrollable area, during this
   // time before PaintLayerScrollableArea has been collected layer_ will
   // be set to nullptr by the Dispose method.
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
index 43c35c5..15bd01a 100644
--- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
+++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
@@ -82,6 +82,14 @@
     return false;
   }
 
+  void ExpectEqAllScrollControlsNeedPaintInvalidation(
+      const PaintLayerScrollableArea* area,
+      bool expectation) const {
+    EXPECT_EQ(area->VerticalScrollbarNeedsPaintInvalidation(), expectation);
+    EXPECT_EQ(area->HorizontalScrollbarNeedsPaintInvalidation(), expectation);
+    EXPECT_EQ(area->ScrollCornerNeedsPaintInvalidation(), expectation);
+  }
+
  private:
   void SetUp() override {
     EnableCompositing();
@@ -1720,6 +1728,155 @@
             mojom::blink::ColorScheme::kDark);
 }
 
+TEST_P(MAYBE_PaintLayerScrollableAreaTest,
+       UsedColorSchemeRootScrollbarsInvalidateOnPreferredColorSchemeChange) {
+  USE_NON_OVERLAY_SCROLLBARS();
+
+  SetHtmlInnerHTML(R"HTML(
+    <style>
+      html { height: 1000px; width: 1000px; }
+      .container { overflow: scroll; width: 100px; height: 100px; }
+      .scrollable { height: 400px; width: 400px; }
+    </style>
+    <div id="normal" class="container">
+      <div class="scrollable"></div>
+    </div>
+  )HTML");
+
+  ASSERT_EQ(GetDocument().GetPreferredColorScheme(),
+            mojom::blink::PreferredColorScheme::kLight);
+
+  const auto* non_root_scroller = GetLayoutBoxByElementId("normal");
+  ASSERT_TRUE(non_root_scroller);
+
+  // Change preferred color scheme to dark.
+  ColorSchemeHelper color_scheme_helper(GetDocument());
+  color_scheme_helper.SetPreferredColorScheme(
+      mojom::blink::PreferredColorScheme::kDark);
+
+  // Root scrollbars should be set for invalidation after the preferred color
+  // scheme change.
+  EXPECT_TRUE(GetLayoutView().ShouldDoFullPaintInvalidation());
+
+  // Non root scrollbars should not change.
+  EXPECT_FALSE(non_root_scroller->ShouldDoFullPaintInvalidation());
+}
+
+TEST_P(MAYBE_PaintLayerScrollableAreaTest,
+       UsedColorSchemeRootScrollbarsInvalidateOnNormalToLightChange) {
+  USE_NON_OVERLAY_SCROLLBARS();
+
+  SetHtmlInnerHTML(R"HTML(
+    <style>
+      html { height: 1000px; width: 1000px; }
+      .container { overflow: scroll; width: 100px; height: 100px; }
+      .scrollable { height: 400px; width: 400px; }
+    </style>
+    <div id="normal" class="container">
+      <div class="scrollable"></div>
+    </div>
+  )HTML");
+
+  ASSERT_EQ(GetDocument().GetPreferredColorScheme(),
+            mojom::blink::PreferredColorScheme::kLight);
+
+  const auto* root_scrollable_area = GetLayoutView().GetScrollableArea();
+  ASSERT_TRUE(root_scrollable_area);
+  const auto* non_root_scrollable_area =
+      GetPaintLayerByElementId("normal")->GetScrollableArea();
+  ASSERT_TRUE(non_root_scrollable_area);
+
+  // Change preferred color scheme to dark.
+  ColorSchemeHelper color_scheme_helper(GetDocument());
+  color_scheme_helper.SetPreferredColorScheme(
+      mojom::blink::PreferredColorScheme::kDark);
+  UpdateAllLifecyclePhasesForTest();
+
+  // Set root element's color scheme to light.
+  GetDocument().documentElement()->SetInlineStyleProperty(
+      CSSPropertyID::kColorScheme, AtomicString("light"));
+
+  // Update lifecycle up until the pre-paint before the scrollbars paint is
+  // invalidated.
+  GetDocument().View()->UpdateLifecycleToCompositingInputsClean(
+      DocumentUpdateReason::kTest);
+
+  // Root scrollbars should be set for invalidation after the color scheme
+  // change.
+  if (RuntimeEnabledFeatures::UsedColorSchemeRootScrollbarsEnabled()) {
+    ExpectEqAllScrollControlsNeedPaintInvalidation(root_scrollable_area, true);
+  } else {
+    ExpectEqAllScrollControlsNeedPaintInvalidation(root_scrollable_area, false);
+  }
+
+  // Non root scrollbars should not change.
+  ExpectEqAllScrollControlsNeedPaintInvalidation(non_root_scrollable_area,
+                                                 false);
+
+  EXPECT_EQ(root_scrollable_area->UsedColorSchemeScrollbars(),
+            mojom::blink::ColorScheme::kLight);
+}
+
+TEST_P(MAYBE_PaintLayerScrollableAreaTest,
+       UsedColorSchemeRootScrollbarsInvalidateOnLightToNormalChange) {
+  USE_NON_OVERLAY_SCROLLBARS();
+
+  SetHtmlInnerHTML(R"HTML(
+    <style>
+      html { height: 1000px; width: 1000px; color-scheme: light; }
+      .container { overflow: scroll; width: 100px; height: 100px; }
+      .scrollable { height: 400px; width: 400px; }
+    </style>
+    <div id="normal" class="container">
+      <div class="scrollable"></div>
+    </div>
+  )HTML");
+
+  ASSERT_EQ(GetDocument().GetPreferredColorScheme(),
+            mojom::blink::PreferredColorScheme::kLight);
+
+  const auto* root_scrollable_area = GetLayoutView().GetScrollableArea();
+  ASSERT_TRUE(root_scrollable_area);
+  const auto* non_root_scrollable_area =
+      GetPaintLayerByElementId("normal")->GetScrollableArea();
+  ASSERT_TRUE(non_root_scrollable_area);
+
+  // Change preferred color scheme to dark.
+  ColorSchemeHelper color_scheme_helper(GetDocument());
+  color_scheme_helper.SetPreferredColorScheme(
+      mojom::blink::PreferredColorScheme::kDark);
+  UpdateAllLifecyclePhasesForTest();
+
+  // Set root element's color scheme to normal.
+  GetDocument().documentElement()->SetInlineStyleProperty(
+      CSSPropertyID::kColorScheme, AtomicString("normal"));
+
+  // Update lifecycle up until the pre-paint before the scrollbars paint is
+  // invalidated.
+  GetDocument().View()->UpdateLifecycleToCompositingInputsClean(
+      DocumentUpdateReason::kTest);
+
+  // Root scrollbars should be set for invalidation after the color scheme
+  // change.
+  if (RuntimeEnabledFeatures::UsedColorSchemeRootScrollbarsEnabled()) {
+    ExpectEqAllScrollControlsNeedPaintInvalidation(root_scrollable_area, true);
+  } else {
+    ExpectEqAllScrollControlsNeedPaintInvalidation(root_scrollable_area, false);
+  }
+
+  // Non root scrollbars should not change.
+  ExpectEqAllScrollControlsNeedPaintInvalidation(non_root_scrollable_area,
+                                                 false);
+
+  if (RuntimeEnabledFeatures::UsedColorSchemeRootScrollbarsEnabled()) {
+    EXPECT_EQ(root_scrollable_area->UsedColorSchemeScrollbars(),
+              mojom::blink::ColorScheme::kDark);
+  } else {
+    EXPECT_EQ(root_scrollable_area->UsedColorSchemeScrollbars(),
+              mojom::blink::ColorScheme::kLight);
+  }
+}
+
 // TODO(crbug.com/1020913): Actually this tests a situation that should not
 // exist but it does exist due to different or incorrect rounding methods for
 // scroll geometries. This test can be converted to test the correct behavior
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc
index 29934494..d1434c6 100644
--- a/third_party/blink/renderer/core/style/computed_style.cc
+++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -2840,6 +2840,12 @@
       (force_dark && !prefers_dark);
 
   SetColorSchemeForced(forced_scheme);
+
+  if (RuntimeEnabledFeatures::UsedColorSchemeRootScrollbarsEnabled()) {
+    const bool is_normal =
+        flags == static_cast<ColorSchemeFlags>(ColorSchemeFlag::kNormal);
+    SetColorSchemeFlagsIsNormal(is_normal);
+  }
 }
 
 CSSVariableData* ComputedStyleBuilder::GetVariableData(
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 59ea7d6..854c98a 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
@@ -892,6 +892,14 @@
       inherited: true,
     },
     {
+      name: "ColorSchemeFlagsIsNormal",
+      field_template: "primitive",
+      type_name: "bool",
+      default_value: "false",
+      custom_compare: true,
+      inherited: true,
+    },
+    {
       name: "ColorSchemeForced",
       field_template: "primitive",
       type_name: "bool",
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc b/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc
index 01ff04e..f4b1d99 100644
--- a/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc
+++ b/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc
@@ -327,12 +327,12 @@
   auto* document = GetSupplementable();
   CHECK(document);
 
-  // Update active styles will compute the @view-transitions
-  // navigation-trigger opt in.
+  // Update active styles will compute the @view-transition
+  // navigation opt in.
   // TODO(https://crbug.com/1463966): This is probably a bit of a heavy hammer.
   // In the long term, we probably don't want to make this decision at
   // WillInsertBody or, if we do, we could look specifically for
-  // @view-transitions rather than all rules.
+  // @view-transition rather than all rules.
   document->GetStyleEngine().UpdateActiveStyle();
 
   // If the opt-in is enabled, then there's nothing to do in this function.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index 43b83fc..2f8f1054 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -3238,7 +3238,7 @@
     // less than stops in the slider, otherwise, move by 5%.
     float max = step_range.Maximum().ToString().ToFloat();
     float min = step_range.Minimum().ToString().ToFloat();
-    int num_stops = (max - min) / step;
+    int num_stops = base::saturated_cast<int>((max - min) / step);
     constexpr int kNumStopsForFivePercentRule = 40;
     if (num_stops >= kNumStopsForFivePercentRule) {
       // No explicit step, and the step is very small -- don't expose a step
diff --git a/third_party/blink/renderer/modules/scheduler/script_wrappable_task_state.cc b/third_party/blink/renderer/modules/scheduler/script_wrappable_task_state.cc
index ef83b1c..4dabfbe 100644
--- a/third_party/blink/renderer/modules/scheduler/script_wrappable_task_state.cc
+++ b/third_party/blink/renderer/modules/scheduler/script_wrappable_task_state.cc
@@ -11,9 +11,22 @@
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
 #include "third_party/blink/renderer/platform/bindings/script_state.h"
+#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
 
 namespace blink {
 
+namespace {
+
+void ClearContinuationPreservedEmbedderData(v8::Isolate* isolate) {
+  v8::HandleScope handle_scope(isolate);
+  v8::Local<v8::Context> context =
+      V8PerIsolateData::From(isolate)->EnsureScriptRegexpContext();
+  v8::Context::Scope context_scope(context);
+  context->SetContinuationPreservedEmbedderData(v8::Local<v8::Value>());
+}
+
+}  // namespace
+
 ScriptWrappableTaskState::ScriptWrappableTaskState(
     scheduler::TaskAttributionInfo* task,
     AbortSignal* abort_source,
@@ -64,19 +77,31 @@
     ScriptState* script_state,
     ScriptWrappableTaskState* task_state) {
   DCHECK(script_state);
-  if (!script_state->ContextIsValid()) {
-    return;
-  }
-  CHECK(!ScriptForbiddenScope::IsScriptForbidden());
-  ScriptState::Scope scope(script_state);
   v8::Isolate* isolate = script_state->GetIsolate();
   DCHECK(isolate);
   if (isolate->IsExecutionTerminating()) {
     return;
   }
+  CHECK(!ScriptForbiddenScope::IsScriptForbidden());
+  if (!script_state->ContextIsValid()) {
+    // TODO(crbug.com/1351643): This is a temporary workaround for detached
+    // contexts while transitioning to per-isolate CPED. When v8 switches to
+    // per-isolate CPED, we won't restore the previous value if the context is
+    // detached, which can result in propagating the wrong value or leaking the
+    // context.
+    //
+    // The following prevents this by clearing the CPED on an arbitrary context
+    // associated with the isolate. Before the v8 API changes, this is a no-op
+    // (aside from potentially creating the context). After it changes, this
+    // will clear the per-isolate CPED since
+    // Context::SetContinuationPreservedEmbedderData() will delegate to
+    // Isolate::SetContinuationPreservedEmbedderData().
+    ClearContinuationPreservedEmbedderData(isolate);
+    return;
+  }
+  ScriptState::Scope scope(script_state);
   v8::Local<v8::Context> context = script_state->GetContext();
   DCHECK(!context.IsEmpty());
-
   if (task_state) {
     context->SetContinuationPreservedEmbedderData(
         ToV8Traits<ScriptWrappableTaskState>::ToV8(script_state, task_state)
diff --git a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
index f88fa23..87c1fc5 100644
--- a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator.cc
@@ -50,6 +50,9 @@
     if (new_chunk.Matches(GetOldChunk(i)))
       return i;
   }
+  if (RuntimeEnabledFeatures::OnePassRasterInvalidationEnabled()) {
+    return kNotFound;
+  }
   for (wtf_size_t i = 0; i < old_index; i++) {
     if (new_chunk.Matches(GetOldChunk(i)))
       return i;
@@ -216,7 +219,8 @@
         ClipByLayerBounds(old_chunk_info.bounds_in_layer);
 
     auto reason = PaintInvalidationReason::kNone;
-    if (matched_old_index < max_matched_old_index) {
+    if (!RuntimeEnabledFeatures::OnePassRasterInvalidationEnabled() &&
+        matched_old_index < max_matched_old_index) {
       reason = PaintInvalidationReason::kChunkReordered;
     } else if (ScrollbarNeedsUpdateDisplay(it)) {
       reason = PaintInvalidationReason::kScrollControl;
@@ -285,9 +289,13 @@
     }
 
     old_index = matched_old_index + 1;
-    if (old_index == old_paint_chunks_info_.size())
-      old_index = 0;
-    max_matched_old_index = std::max(max_matched_old_index, matched_old_index);
+    if (!RuntimeEnabledFeatures::OnePassRasterInvalidationEnabled()) {
+      if (old_index == old_paint_chunks_info_.size()) {
+        old_index = 0;
+      }
+      max_matched_old_index =
+          std::max(max_matched_old_index, matched_old_index);
+    }
   }
 
   // Invalidate remaining unmatched (disappeared or uncacheable) old chunks.
diff --git a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
index 2b6a1f05..1ce6343 100644
--- a/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
+++ b/third_party/blink/renderer/platform/graphics/paint/raster_invalidator_test.cc
@@ -19,13 +19,18 @@
 
 namespace blink {
 
+enum { kOnePassRasterInvalidation = 1 << 20 };
+
 static constexpr gfx::Vector2dF kDefaultLayerOffset(-9999, -7777);
 static constexpr gfx::Size kDefaultLayerBounds(18888, 16666);
 
 class RasterInvalidatorTest : public testing::Test,
-                              public PaintTestConfigurations {
+                              public PaintTestConfigurations,
+                              private ScopedOnePassRasterInvalidationForTest {
  public:
-  RasterInvalidatorTest() = default;
+  RasterInvalidatorTest()
+      : ScopedOnePassRasterInvalidationForTest(GetParam() &
+                                               kOnePassRasterInvalidation) {}
 
   static PropertyTreeState DefaultPropertyTreeState() {
     return PropertyTreeState::Root();
@@ -57,7 +62,10 @@
   int sequence_number_ = 1;
 };
 
-INSTANTIATE_PAINT_TEST_SUITE_P(RasterInvalidatorTest);
+INSTANTIATE_TEST_SUITE_P(All,
+                         RasterInvalidatorTest,
+                         ::testing::Values(PAINT_TEST_SUITE_P_VALUES,
+                                           kOnePassRasterInvalidation));
 
 using MapFunction = base::RepeatingCallback<void(gfx::Rect&)>;
 static gfx::Rect ChunkRectToLayer(
@@ -220,14 +228,25 @@
                                   .Build());
   invalidator_.Generate(base::DoNothing(), new_chunks, kDefaultLayerOffset,
                         kDefaultLayerBounds, DefaultPropertyTreeState());
-  // Invalidated new chunk 2's old (as chunks[{0, 1]) and new
-  // (as new_chunks[{0, 2]) bounds.
-  EXPECT_THAT(
-      TrackedRasterInvalidations(),
-      ElementsAre(ChunkInvalidation(chunks, 1,
-                                    PaintInvalidationReason::kChunkReordered),
-                  ChunkInvalidation(new_chunks, 2,
-                                    PaintInvalidationReason::kChunkReordered)));
+  if (RuntimeEnabledFeatures::OnePassRasterInvalidationEnabled()) {
+    EXPECT_THAT(
+        TrackedRasterInvalidations(),
+        ElementsAre(
+            ChunkInvalidation(new_chunks, 2,
+                              PaintInvalidationReason::kChunkAppeared),
+            ChunkInvalidation(chunks, 1,
+                              PaintInvalidationReason::kChunkDisappeared)));
+  } else {
+    // Invalidated new chunk 2's old (as chunks[{0, 1]) and new
+    // (as new_chunks[{0, 2]) bounds.
+    EXPECT_THAT(
+        TrackedRasterInvalidations(),
+        ElementsAre(
+            ChunkInvalidation(chunks, 1,
+                              PaintInvalidationReason::kChunkReordered),
+            ChunkInvalidation(new_chunks, 2,
+                              PaintInvalidationReason::kChunkReordered)));
+  }
   FinishCycle(new_chunks);
 }
 
@@ -253,18 +272,33 @@
                                   .Build());
   invalidator_.Generate(base::DoNothing(), new_chunks, kDefaultLayerOffset,
                         kDefaultLayerBounds, DefaultPropertyTreeState());
-  // Invalidated new chunk 3's old (as chunks[{0, 1] and new
-  // (as new_chunks[{0, 3]) bounds.
-  // Invalidated new chunk 4's new bounds. Didn't invalidate old bounds because
-  // it's the same as the new bounds.
-  EXPECT_THAT(
-      TrackedRasterInvalidations(),
-      ElementsAre(ChunkInvalidation(chunks, 1,
-                                    PaintInvalidationReason::kChunkReordered),
-                  ChunkInvalidation(new_chunks, 3,
-                                    PaintInvalidationReason::kChunkReordered),
-                  ChunkInvalidation(new_chunks, 4,
-                                    PaintInvalidationReason::kChunkReordered)));
+  if (RuntimeEnabledFeatures::OnePassRasterInvalidationEnabled()) {
+    EXPECT_THAT(
+        TrackedRasterInvalidations(),
+        ElementsAre(
+            ChunkInvalidation(new_chunks, 3,
+                              PaintInvalidationReason::kChunkAppeared),
+            ChunkInvalidation(new_chunks, 4,
+                              PaintInvalidationReason::kChunkAppeared),
+            ChunkInvalidation(chunks, 1,
+                              PaintInvalidationReason::kChunkDisappeared),
+            ChunkInvalidation(chunks, 2,
+                              PaintInvalidationReason::kChunkDisappeared)));
+  } else {
+    // Invalidated new chunk 3's old (as chunks[{0, 1] and new
+    // (as new_chunks[{0, 3]) bounds.
+    // Invalidated new chunk 4's new bounds. Didn't invalidate old bounds
+    // because it's the same as the new bounds.
+    EXPECT_THAT(
+        TrackedRasterInvalidations(),
+        ElementsAre(
+            ChunkInvalidation(chunks, 1,
+                              PaintInvalidationReason::kChunkReordered),
+            ChunkInvalidation(new_chunks, 3,
+                              PaintInvalidationReason::kChunkReordered),
+            ChunkInvalidation(new_chunks, 4,
+                              PaintInvalidationReason::kChunkReordered)));
+  }
   FinishCycle(new_chunks);
 }
 
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 2bf59860..02062fea 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -245,6 +245,11 @@
       base_feature: "none",
     },
     {
+      name: "AccessibilityOSLevelBoldText",
+      status: "experimental",
+      public: true,
+    },
+    {
       name: "AccessibilityPageZoom",
       base_feature: "none",
       public: true,
@@ -2151,11 +2156,6 @@
       base_feature: "LayoutNGShapeCache",
     },
     {
-      name: "LayoutNGSubgrid",
-      status: "stable",
-      base_feature: "none",
-    },
-    {
       name: "LazyInitializeMediaControls",
       base_feature: "none",
       public: true,
@@ -2530,6 +2530,10 @@
       status: {"Android": "", "default": "stable"},
       base_feature: "none",
     },
+    {
+      name: "OnePassRasterInvalidation",
+      status: "experimental",
+    },
     // This flag is a killswitch. It was only exists as a way for us to turn
     // the feature off in the emergency that it breaks websites.
     // TODO(http://crbug.com/1473340): Delete internal web_tests which are
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
index d824c20e..879a411 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h
@@ -5,10 +5,9 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_TASK_QUEUE_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_TASK_QUEUE_H_
 
-#include <limits>
+#include <bit>
 #include <memory>
 
-#include "base/bits.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
@@ -176,24 +175,25 @@
       kRenderBlocking = 13,
       kLow = 14,
 
-      kCount = 15
+      kMaxValue = kLow
     };
 
-    // kPrioritisationTypeWidthBits is the number of bits required
-    // for PrioritisationType::kCount - 1, which is the number of bits needed
-    // to represent |prioritisation_type| in QueueTraitKeyType.
-    // We need to update it whenever there is a change in
-    // PrioritisationType::kCount.
-    static constexpr unsigned PrioritisationTypeCount =
-        static_cast<unsigned>(QueueTraits::PrioritisationType::kCount);
-
+    // Bit width required for the PrioritisationType enumeration
     static constexpr unsigned kPrioritisationTypeWidthBits =
-        std::numeric_limits<unsigned>::digits -
-        base::bits::CountTrailingZeroBits(PrioritisationTypeCount - 1);
+        std::bit_width(static_cast<unsigned>(PrioritisationType::kMaxValue));
 
-    static_assert(PrioritisationTypeCount <=
+    // Ensure that the count of the enumeration does not exceed the
+    // representable range
+    static_assert(static_cast<unsigned>(PrioritisationType::kMaxValue) <
                       (1u << kPrioritisationTypeWidthBits),
-                  "Wrong instantiation for kPrioritisationTypeWidthBits");
+                  "PrioritisationType count exceeds the bit width range");
+
+    // Ensure that the count of the enumeration is not less than half the
+    // representable range
+    static_assert(
+        static_cast<unsigned>(PrioritisationType::kMaxValue) >=
+            (1u << (kPrioritisationTypeWidthBits - 1)),
+        "PrioritisationType count is less than half the bit width range");
 
     QueueTraits(const QueueTraits&) = default;
     QueueTraits& operator=(const QueueTraits&) = default;
diff --git a/third_party/blink/renderer/platform/wtf/vector.h b/third_party/blink/renderer/platform/wtf/vector.h
index a566d3a..7a49249 100644
--- a/third_party/blink/renderer/platform/wtf/vector.h
+++ b/third_party/blink/renderer/platform/wtf/vector.h
@@ -24,6 +24,7 @@
 #include <string.h>
 
 #include <algorithm>
+#include <concepts>
 #include <functional>
 #include <initializer_list>
 #include <iterator>
@@ -1082,6 +1083,20 @@
   static constexpr bool value = true;
 };
 
+namespace internal {
+
+template <typename Collection>
+concept VectorCanConstructFromCollection = requires(Collection c) {
+  // TODO(crbug.com/1502036): In theory we should be able to require that these
+  // conform to std::input_iterator, but HashTableConstIteratorAdapter actually
+  // doesn't.
+  c.begin();
+  c.end();
+  { c.size() } -> std::unsigned_integral;
+};
+
+}  // namespace internal
+
 template <typename T, wtf_size_t inlineCapacity, typename Allocator>
 class Vector
     : private VectorBuffer<T, INLINE_CAPACITY, Allocator>,
@@ -1148,22 +1163,14 @@
 
   // Creates a vector with items copied from a collection. |Collection| must
   // have size(), begin() and end() methods.
-  template <typename Collection,
-            // This prevents this constructor from being chosen for e.g.
-            // Vector(3).
-            typename = std::enable_if_t<std::disjunction_v<
-                std::is_same<value_type, typename Collection::value_type>,
-                std::is_constructible<value_type,
-                                      typename Collection::const_reference>>>>
+  template <typename Collection>
+    requires internal::VectorCanConstructFromCollection<Collection>
   explicit Vector(const Collection& collection) : Vector() {
     assign(collection);
   }
   // Replaces the vector with items copied from a collection.
-  template <typename Collection,
-            typename = std::enable_if_t<std::disjunction_v<
-                std::is_same<value_type, typename Collection::value_type>,
-                std::is_constructible<value_type,
-                                      typename Collection::const_reference>>>>
+  template <typename Collection>
+    requires internal::VectorCanConstructFromCollection<Collection>
   void assign(const Collection&);
 
   // Moving.
@@ -1657,7 +1664,8 @@
 }
 
 template <typename T, wtf_size_t inlineCapacity, typename Allocator>
-template <typename Collection, typename SFINAE>
+template <typename Collection>
+  requires internal::VectorCanConstructFromCollection<Collection>
 void Vector<T, inlineCapacity, Allocator>::assign(const Collection& other) {
   static_assert(
       !std::is_same_v<Vector<T, inlineCapacity, Allocator>, Collection>,
diff --git a/third_party/blink/tools/blinkpy/web_tests/flake_suppressor/web_tests_queries.py b/third_party/blink/tools/blinkpy/web_tests/flake_suppressor/web_tests_queries.py
index 3999a509..ef3b8a92 100644
--- a/third_party/blink/tools/blinkpy/web_tests/flake_suppressor/web_tests_queries.py
+++ b/third_party/blink/tools/blinkpy/web_tests/flake_suppressor/web_tests_queries.py
@@ -165,8 +165,8 @@
   (ARRAY_TO_STRING(ft.typ_expectations, '') = "Pass" OR
    ARRAY_TO_STRING(ft.typ_expectations, '') = "PassSlow") AND
   pt.name IS NULL AND
-  (STARTS_WITH(step_name, 'blink_wpt_tests') OR
-   STARTS_WITH(step_name, 'blink_web_tests'))
+  (STARTS_WITH(ft.step_name, 'blink_wpt_tests') OR
+   STARTS_WITH(ft.step_name, 'blink_web_tests'))
 """.format(
     sheriff_rotations_ci_builds_subquery=SHERIFF_ROTATIONS_CI_BUILDS_SUBQUERY)
 
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index b643a87..bc004e0 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -2064,6 +2064,11 @@
 # can be problematic on debug builds.
 crbug.com/1197087 [ Debug ] external/wpt/web-animations/interfaces/Animation/finished.html [ Skip ]
 
+# Chrome only runs nonvirtual WPT tests at the moment.
+[ Chrome ] * [ Skip ]
+[ Chrome ] external/wpt/* [ Pass ]
+[ Chrome ] wpt_internal/* [ Pass ]
+
 # At the moment, no plans to run wdspec tests for anything other than Chrome on
 # Linux due to resource constraints.
 [ Mac ] external/wpt/webdriver/tests/* [ Skip ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 210b4dd..33fcf25 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -336944,10 +336944,6 @@
        []
       ]
      },
-     "sin-cos-tan-serialize-expected.txt": [
-      "692b9cb129cbe083f11e82d8eae198be7f0418de",
-      []
-     ],
      "support": {
       "1x1-green.png": [
        "b98ca0ba0a03c580ac339e4a3653539cfa8edc71",
@@ -385873,7 +385869,7 @@
       []
      ],
      "storage-access-beyond-cookies-iframe-iframe.html": [
-      "b33d3b0ddc551cc839129b931748e0649fbb89c4",
+      "993d87d0d3a346aa410d662bdfd43379185a2a46",
       []
      ],
      "storage-access-beyond-cookies-iframe.sub.html": [
@@ -464647,7 +464643,7 @@
       ]
      ],
      "sin-cos-tan-computed.html": [
-      "bad6017520944a7726b2962a9f859f97626d0db4",
+      "6cf4f1968472de0348e8e9d770e03a34ca24c075",
       [
        null,
        {}
@@ -622991,7 +622987,7 @@
      ]
     ],
     "storage-access-beyond-cookies.localStorage.tentative.sub.https.window.js": [
-     "108e778766db5d89fb442ceb4d6ab37cf50aee38",
+     "6243cb1fa8c5c25e15747dfc22de3f3c108eea98",
      [
       "storage-access-api/storage-access-beyond-cookies.localStorage.tentative.sub.https.window.html",
       {
@@ -623027,7 +623023,7 @@
      ]
     ],
     "storage-access-beyond-cookies.sessionStorage.tentative.sub.https.window.js": [
-     "2e504851c22b58c60e79829f7bd9921424a877df",
+     "1b12f133b2c36ea2ed8eaa3cfd86b8d268dbff9c",
      [
       "storage-access-api/storage-access-beyond-cookies.sessionStorage.tentative.sub.https.window.html",
       {
@@ -656032,6 +656028,15 @@
       {}
      ]
     ],
+    "RTCConfiguration-validation.html": [
+     "851ed8d81b188468c053996275e534c307c6864d",
+     [
+      null,
+      {
+       "timeout": "long"
+      }
+     ]
+    ],
     "RTCDTMFSender-insertDTMF.https.html": [
      "71cfe70171f7ff4aeddd01483fce6edbf29e59b9",
      [
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-revoke.https.html b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-revoke.https.html
deleted file mode 100644
index fb63197..0000000
--- a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-revoke.https.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE html>
-<title>Federated Credential Management API revoke() tests.</title>
-<link rel="help" href="https://fedidcg.github.io/FedCM">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-
-<body>
-
-<script type="module">
-import {fedcm_test,
-        revoke_options,
-        fedcm_get_and_select_first_account,
-        request_options_with_mediation_required} from './support/fedcm-helper.sub.js';
-
-fedcm_test(async t => {
-  const revoke = IdentityCredential.revoke(revoke_options("nonExistent"));
-  return promise_rejects_dom(t, 'NetworkError', revoke);
-}, 'Test that revoke fails when there is no account to revoke');
-
-fedcm_test(async t => {
-  const cred = await fedcm_get_and_select_first_account(t, request_options_with_mediation_required());
-
-  return IdentityCredential.revoke(revoke_options("1234"));
-}, 'Test that revoke succeeds when there is an account to revoke');
-
-fedcm_test(async t => {
-  const cred = await fedcm_get_and_select_first_account(t, request_options_with_mediation_required());
-
-  await IdentityCredential.revoke(revoke_options("1234"));
-
-  const revoke = IdentityCredential.revoke(revoke_options("1234"));
-  return promise_rejects_dom(t, 'NetworkError', revoke);
-}, 'Test that revoking the same account twice results in failure.');
-
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/fedcm-revoke.sub.https.html b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-revoke.sub.https.html
new file mode 100644
index 0000000..b16c0162
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/credential-management/fedcm-revoke.sub.https.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<title>Federated Credential Management API revoke() tests.</title>
+<link rel="help" href="https://fedidcg.github.io/FedCM">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<body>
+
+<script type="module">
+import {fedcm_test,
+        mark_signed_in,
+        set_fedcm_cookie,
+        revoke_options,
+        fedcm_get_and_select_first_account,
+        request_options_with_mediation_required,
+        alt_manifest_origin,
+        alt_request_options_with_mediation_required,
+        alt_revoke_options,
+        set_alt_fedcm_cookie} from './support/fedcm-helper.sub.js';
+
+fedcm_test(async t => {
+  await mark_signed_in();
+  await set_fedcm_cookie();
+  // Get at least one connected account that can be revoked.
+  const cred = await fedcm_get_and_select_first_account(t, request_options_with_mediation_required());
+  // The IDP implementation will accept any account hint, so this is really testing that the user
+  // agent eventually stops sending the requests to the IDP.
+  // This test clears the connection just created above, but it also clears any previously existing
+  // connected accounts, which helps the logic of the other tests.
+  return new Promise(async resolve => {
+    while (true) {
+      try {
+        await IdentityCredential.revoke(revoke_options("1234"));
+      } catch(e) {
+        resolve();
+        break;
+      }
+    }
+  });
+}, "Repeatedly calling revoke should eventually fail");
+
+fedcm_test(async t => {
+  const revoke = IdentityCredential.revoke(revoke_options("nonExistent"));
+  return promise_rejects_dom(t, 'NetworkError', revoke);
+}, 'Test that revoke fails when there is no account to revoke');
+
+fedcm_test(async t => {
+  const cred = await fedcm_get_and_select_first_account(t, request_options_with_mediation_required());
+
+  return IdentityCredential.revoke(revoke_options("1234"));
+}, 'Test that revoke succeeds when there is an account to revoke');
+
+fedcm_test(async t => {
+  const cred = await fedcm_get_and_select_first_account(t, request_options_with_mediation_required());
+
+  await IdentityCredential.revoke(revoke_options("1234"));
+
+  const revoke = IdentityCredential.revoke(revoke_options("1234"));
+  return promise_rejects_dom(t, 'NetworkError', revoke);
+}, 'Test that revoking the same account twice results in failure.');
+
+fedcm_test(async t => {
+  const cred = await fedcm_get_and_select_first_account(t, request_options_with_mediation_required());
+  // A connected account is guaranteed by the above, and IDP accepts any account hint, so this tests
+  // that the user agent allows the request to go through to the IDP.
+  return IdentityCredential.revoke(revoke_options("noMatch"));
+}, 'Revoke passing an incorrect ID can still succeed');
+
+fedcm_test(async t => {
+  await set_alt_fedcm_cookie();
+  await mark_signed_in(alt_manifest_origin);
+  await fedcm_get_and_select_first_account(t, alt_request_options_with_mediation_required());
+  await fedcm_get_and_select_first_account(t, request_options_with_mediation_required());
+
+  // Await the first revocation since they cannot happen in parallel. Both should succeed.
+  await IdentityCredential.revoke(revoke_options("1"));
+  return IdentityCredential.revoke(alt_revoke_options("2"));
+}, 'Revocation is bound to each IDP');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm-helper.sub.js b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm-helper.sub.js
index 319dc08..8c3a52c5 100644
--- a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm-helper.sub.js
+++ b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm-helper.sub.js
@@ -225,3 +225,16 @@
       accountHint: accountHint
       };
 }
+
+export function alt_revoke_options(accountHint, manifest_filename) {
+  if (manifest_filename === undefined) {
+    manifest_filename = "manifest.py";
+  }
+  const manifest_path = `${alt_manifest_origin}/\
+credential-management/support/fedcm/${manifest_filename}`;
+  return {
+      configURL: manifest_path,
+      clientId: '1',
+      accountHint: accountHint
+  };
+}
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/revoke.py b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/revoke.py
index 3b06526..cf62ced 100644
--- a/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/revoke.py
+++ b/third_party/blink/web_tests/external/wpt/credential-management/support/fedcm/revoke.py
@@ -2,12 +2,13 @@
 error_checker = importlib.import_module("credential-management.support.fedcm.request-params-check")
 
 def main(request, response):
+  response.headers.set(b"Content-Type", b"application/json")
+  response.headers.set(b"Access-Control-Allow-Origin", request.headers.get(b"origin"))
+  response.headers.set(b"Access-Control-Allow-Credentials", b"true")
   request_error = error_checker.revokeCheck(request)
-  if (request_error):
+  if request_error:
     return request_error
 
-  response.headers.set(b"Content-Type", b"application/json")
-
   # Pass the account_hint as the accountId.
-  account_hint = request.POST.get(b"account_hint");
+  account_hint = request.POST.get(b"account_hint")
   return f"{{\"account_id\": \"{account_hint}\"}}"
diff --git a/third_party/blink/web_tests/external/wpt/credential-management/support/set_cookie.headers b/third_party/blink/web_tests/external/wpt/credential-management/support/set_cookie.headers
index cf5ea7fff..b19ff933 100644
--- a/third_party/blink/web_tests/external/wpt/credential-management/support/set_cookie.headers
+++ b/third_party/blink/web_tests/external/wpt/credential-management/support/set_cookie.headers
@@ -1,2 +1,2 @@
 Content-Type: text/html
-Set-Cookie: cookie=1; SameSite=Strict; Secure
+Set-Cookie: cookie=1; SameSite=None; Secure
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-baseline-010.html b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-baseline-010.html
new file mode 100644
index 0000000..74b9382
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/subgrid-baseline-010.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Test: Baseline-aligned items within subgrid</title>
+<link rel="author" title="Ethan Jimenez" href="mailto:ethavar@microsoft.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-2/#subgrid-grid-alignment">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<style>
+html, body {
+  margin: 0;
+  padding: 0;
+  font: 15px/1 Ahem;
+}
+main {
+  display: grid;
+  align-items: baseline;
+  grid-template: 50px / repeat(2, 30px);
+}
+main > div {
+  display: grid;
+  grid-column: 1 / -1;
+  align-items: baseline;
+  grid-template: 50px / subgrid;
+}
+.item:nth-child(2) { font-size: 30px }
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.item')">
+<main>
+  <div>
+    <div class="item" data-offset-y="12" data-expected-height="15">X</div>
+    <div class="item" data-offset-y="0" data-expected-height="30">X</div>
+  </div>
+</main>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/system-state-and-capabilities/the-navigator-object/navigator_user_agent.https.html b/third_party/blink/web_tests/external/wpt/html/webappapis/system-state-and-capabilities/the-navigator-object/navigator_user_agent.https.html
index 32c0cb1..10b3dd2 100644
--- a/third_party/blink/web_tests/external/wpt/html/webappapis/system-state-and-capabilities/the-navigator-object/navigator_user_agent.https.html
+++ b/third_party/blink/web_tests/external/wpt/html/webappapis/system-state-and-capabilities/the-navigator-object/navigator_user_agent.https.html
@@ -26,7 +26,9 @@
     assert_equals(typeof highEntropyData["architecture"], "string", "Architecture should be a string");
     assert_equals(typeof highEntropyData["model"], "string", "Model should be a string");
     assert_equals(typeof highEntropyData["uaFullVersion"], "string", "UAFullVersion should be a string");
-    assert_equals(typeof highEntropyData["formFactor"], "string", "FormFactor should be a string");
+    for (formFactor of highEntropyData['formFactor']) {
+      assert_equals(typeof formFactor, "string", "Each FormFactor should be a string");
+    }
     for (brandVersionPair of highEntropyData['fullVersionList']) {
       assert_equals(typeof brandVersionPair.brand, "string", "brand should be a string");
       assert_regexp_match(brandVersionPair.brand, brandRegex, "brand should not contain unexpected characters");
@@ -39,7 +41,7 @@
     assert_false("model" in highEntropyData2, "Model should be an empty string");
     assert_false("uaFullVersion" in highEntropyData2, "UAFullVersion should be an empty string");
     assert_false("formFactor" in highEntropyData2, "FormFactor should be an empty string");
-    assert_false("fullVersionList" in highEntropyData2, "fullVersionList should be an empty string");
+    assert_false("fullVersionList" in highEntropyData2, "fullVersionList should not be present");
     let finalPromise = uaData.getHighEntropyValues([]).then(() => {
       assert_true(didMicrotaskRun, "getHighEntropyValues queued on a task");
     });
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCConfiguration-validation.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCConfiguration-validation.html
new file mode 100644
index 0000000..851ed8d8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCConfiguration-validation.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<meta name="timeout" content="long">
+<title>RTCConfiguration validation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="RTCConfiguration-helper.js"></script>
+<script src="RTCPeerConnection-helper.js"></script>
+<script>
+  test(() => {
+    // Check that a configuration change gets applied only if it's entirely valid
+    // see https://github.com/w3c/webrtc-pc/issues/2688
+    // and https://github.com/w3c/webrtc-pc/pull/2689
+    const pc = new RTCPeerConnection();
+    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
+    assert_throws_dom('SyntaxError', () =>
+      pc.setConfiguration({iceTransportPolicy: 'relay', iceServers: [{urls: ""}]})
+    );
+    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
+  }, `setConfiguration only applies if the entire configuration is valid`);
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/workers/WorkerNavigator_userAgentData.https.html b/third_party/blink/web_tests/external/wpt/workers/WorkerNavigator_userAgentData.https.html
index 0a0d4ca..8c22d8f8 100644
--- a/third_party/blink/web_tests/external/wpt/workers/WorkerNavigator_userAgentData.https.html
+++ b/third_party/blink/web_tests/external/wpt/workers/WorkerNavigator_userAgentData.https.html
@@ -39,7 +39,7 @@
     assert_equals(e.data.platformVersion, highEntropyValues.platformVersion);
     assert_equals(e.data.uaFullVersion, highEntropyValues.uaFullVersion);
     assert_equals(e.data.wow64, highEntropyValues.wow64);
-    assert_equals(e.data.formFactor, highEntropyValues.formFactor);
+    assert_equals(e.data.formFactor.join(','), highEntropyValues.formFactor.join(','));
     assert_equals(e.data.NavigatorUADataExposed, true);
 
     // Architecture should be one of two permitted values.
diff --git a/third_party/blink/web_tests/platform/linux-chrome/virtual/longtask-from-loaf/external/wpt/longtask-timing/idlharness.window-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/virtual/longtask-from-loaf/external/wpt/longtask-timing/idlharness.window-expected.txt
deleted file mode 100644
index 5b37deb..0000000
--- a/third_party/blink/web_tests/platform/linux-chrome/virtual/longtask-from-loaf/external/wpt/longtask-timing/idlharness.window-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-All subtests passed and are omitted for brevity.
-See https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/writing_web_tests.md#Text-Test-Baselines for details.
-Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/linux-chrome/virtual/plz-dedicated-worker-disabled/external/wpt/resource-timing/idlharness.any-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/virtual/plz-dedicated-worker-disabled/external/wpt/resource-timing/idlharness.any-expected.txt
deleted file mode 100644
index 5b37deb..0000000
--- a/third_party/blink/web_tests/platform/linux-chrome/virtual/plz-dedicated-worker-disabled/external/wpt/resource-timing/idlharness.any-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-All subtests passed and are omitted for brevity.
-See https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/writing_web_tests.md#Text-Test-Baselines for details.
-Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/linux-chrome/virtual/plz-dedicated-worker-disabled/external/wpt/resource-timing/idlharness.any.worker-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/virtual/plz-dedicated-worker-disabled/external/wpt/resource-timing/idlharness.any.worker-expected.txt
deleted file mode 100644
index 5b37deb..0000000
--- a/third_party/blink/web_tests/platform/linux-chrome/virtual/plz-dedicated-worker-disabled/external/wpt/resource-timing/idlharness.any.worker-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-All subtests passed and are omitted for brevity.
-See https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/writing_web_tests.md#Text-Test-Baselines for details.
-Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/platform/linux-chrome/virtual/portals/external/wpt/portals/idlharness.window-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/virtual/portals/external/wpt/portals/idlharness.window-expected.txt
deleted file mode 100644
index caecc7c..0000000
--- a/third_party/blink/web_tests/platform/linux-chrome/virtual/portals/external/wpt/portals/idlharness.window-expected.txt
+++ /dev/null
@@ -1,84 +0,0 @@
-This is a testharness.js-based test.
-Found 75 tests; 70 PASS, 5 FAIL, 0 TIMEOUT, 0 NOTRUN.
-[PASS] idl_test setup
-[PASS] idl_test validation
-[PASS] Partial interface Window: original interface defined
-[PASS] Partial interface Window: member names are unique
-[PASS] Partial interface mixin WindowEventHandlers: original interface mixin defined
-[PASS] Partial interface mixin WindowEventHandlers: member names are unique
-[PASS] Partial interface HTMLBodyElement: member names are unique
-[PASS] Partial interface Window[2]: member names are unique
-[PASS] HTMLElement includes GlobalEventHandlers: member names are unique
-[PASS] HTMLElement includes ElementContentEditable: member names are unique
-[PASS] HTMLElement includes HTMLOrSVGElement: member names are unique
-[PASS] HTMLBodyElement includes WindowEventHandlers: member names are unique
-[PASS] Window includes GlobalEventHandlers: member names are unique
-[PASS] Window includes WindowEventHandlers: member names are unique
-[PASS] Window includes WindowOrWorkerGlobalScope: member names are unique
-[PASS] Window includes AnimationFrameProvider: member names are unique
-[PASS] Window includes WindowSessionStorage: member names are unique
-[PASS] Window includes WindowLocalStorage: member names are unique
-[PASS] HTMLFrameSetElement includes WindowEventHandlers: member names are unique
-[PASS] Element includes ParentNode: member names are unique
-[PASS] Element includes NonDocumentTypeChildNode: member names are unique
-[PASS] Element includes ChildNode: member names are unique
-[PASS] Element includes Slottable: member names are unique
-[PASS] HTMLPortalElement interface: existence and properties of interface object
-[PASS] HTMLPortalElement interface object length
-[PASS] HTMLPortalElement interface object name
-[PASS] HTMLPortalElement interface: existence and properties of interface prototype object
-[PASS] HTMLPortalElement interface: existence and properties of interface prototype object's "constructor" property
-[PASS] HTMLPortalElement interface: existence and properties of interface prototype object's @@unscopables property
-[PASS] HTMLPortalElement interface: attribute src
-[PASS] HTMLPortalElement interface: attribute referrerPolicy
-[PASS] HTMLPortalElement interface: operation activate(optional PortalActivateOptions)
-[PASS] HTMLPortalElement interface: operation postMessage(any, optional StructuredSerializeOptions)
-[PASS] HTMLPortalElement interface: attribute onmessage
-[PASS] HTMLPortalElement interface: attribute onmessageerror
-[PASS] HTMLPortalElement must be primary interface of document.createElement("portal")
-[PASS] Stringification of document.createElement("portal")
-[PASS] HTMLPortalElement interface: document.createElement("portal") must inherit property "src" with the proper type
-[PASS] HTMLPortalElement interface: document.createElement("portal") must inherit property "referrerPolicy" with the proper type
-[PASS] HTMLPortalElement interface: document.createElement("portal") must inherit property "activate(optional PortalActivateOptions)" with the proper type
-[PASS] HTMLPortalElement interface: calling activate(optional PortalActivateOptions) on document.createElement("portal") with too few arguments must throw TypeError
-[PASS] HTMLPortalElement interface: document.createElement("portal") must inherit property "postMessage(any, optional StructuredSerializeOptions)" with the proper type
-[PASS] HTMLPortalElement interface: calling postMessage(any, optional StructuredSerializeOptions) on document.createElement("portal") with too few arguments must throw TypeError
-[PASS] HTMLPortalElement interface: document.createElement("portal") must inherit property "onmessage" with the proper type
-[PASS] HTMLPortalElement interface: document.createElement("portal") must inherit property "onmessageerror" with the proper type
-[PASS] PortalHost interface: existence and properties of interface object
-[PASS] PortalHost interface object length
-[PASS] PortalHost interface object name
-[PASS] PortalHost interface: existence and properties of interface prototype object
-[PASS] PortalHost interface: existence and properties of interface prototype object's "constructor" property
-[PASS] PortalHost interface: existence and properties of interface prototype object's @@unscopables property
-[PASS] PortalHost interface: operation postMessage(any, optional StructuredSerializeOptions)
-[PASS] PortalHost interface: attribute onmessage
-[PASS] PortalHost interface: attribute onmessageerror
-[FAIL] Stringification of window.portalHost
-  assert_class_string: class string of window.portalHost expected "[object PortalHost]" but got "[object Null]"
-[FAIL] PortalHost interface: window.portalHost must inherit property "postMessage(any, optional StructuredSerializeOptions)" with the proper type
-  assert_inherits: provided value is not an object
-[FAIL] PortalHost interface: calling postMessage(any, optional StructuredSerializeOptions) on window.portalHost with too few arguments must throw TypeError
-  assert_inherits: provided value is not an object
-[FAIL] PortalHost interface: window.portalHost must inherit property "onmessage" with the proper type
-  assert_inherits: provided value is not an object
-[FAIL] PortalHost interface: window.portalHost must inherit property "onmessageerror" with the proper type
-  assert_inherits: provided value is not an object
-[PASS] PortalActivateEvent interface: existence and properties of interface object
-[PASS] PortalActivateEvent interface object length
-[PASS] PortalActivateEvent interface object name
-[PASS] PortalActivateEvent interface: existence and properties of interface prototype object
-[PASS] PortalActivateEvent interface: existence and properties of interface prototype object's "constructor" property
-[PASS] PortalActivateEvent interface: existence and properties of interface prototype object's @@unscopables property
-[PASS] PortalActivateEvent interface: attribute data
-[PASS] PortalActivateEvent interface: operation adoptPredecessor()
-[PASS] PortalActivateEvent must be primary interface of new PortalActivateEvent("portalactivate")
-[PASS] Stringification of new PortalActivateEvent("portalactivate")
-[PASS] PortalActivateEvent interface: new PortalActivateEvent("portalactivate") must inherit property "data" with the proper type
-[PASS] PortalActivateEvent interface: new PortalActivateEvent("portalactivate") must inherit property "adoptPredecessor()" with the proper type
-[PASS] HTMLBodyElement interface: attribute onportalactivate
-[PASS] Window interface: attribute portalHost
-[PASS] Window interface: attribute onportalactivate
-[PASS] HTMLFrameSetElement interface: attribute onportalactivate
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/linux-chrome/virtual/scalefactor200/external/wpt/largest-contentful-paint/idlharness-expected.txt b/third_party/blink/web_tests/platform/linux-chrome/virtual/scalefactor200/external/wpt/largest-contentful-paint/idlharness-expected.txt
deleted file mode 100644
index 5b37deb..0000000
--- a/third_party/blink/web_tests/platform/linux-chrome/virtual/scalefactor200/external/wpt/largest-contentful-paint/idlharness-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-All subtests passed and are omitted for brevity.
-See https://chromium.googlesource.com/chromium/src/+/HEAD/docs/testing/writing_web_tests.md#Text-Test-Baselines for details.
-Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-cssom.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-cssom.html
index 5b1617e..8a29c11 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-cssom.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-cssom.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
-<title>View transitions: CSSOM for @view-transitions rule</title>
+<title>View transitions: CSSOM for @view-transition rule</title>
 <link rel="help" href="https://github.com/WICG/view-transitions">
 <link rel="author" href="mailto:bokan@chromium.org">
 <script src="/resources/testharness.js"></script>
@@ -16,104 +16,104 @@
 test(function () {
   resetStateAndTest(() => {
     document.styleSheets[0].insertRule(`
-      @view-transitions {
+      @view-transition {
       }
     `);
     let rule = document.styleSheets[0].cssRules[0];
-    assert_true(rule instanceof CSSViewTransitionsRule);
+    assert_true(rule instanceof CSSViewTransitionRule);
     assert_equals(rule.type, 0);
-    assert_equals(rule.cssText, "@view-transitions { }");
-    assert_equals(rule.navigationTrigger, '');
+    assert_equals(rule.cssText, "@view-transition { }");
+    assert_equals(rule.navigation, '');
 
   });
-}, "CSSViewTransitionsRule is correctly parsed and accessible via CSSOM.");
+}, "CSSViewTransitionRule is correctly parsed and accessible via CSSOM.");
 
 test(function () {
   resetStateAndTest(() => {
     document.styleSheets[0].insertRule(`
-      @view-transitions {
-        navigation-trigger: cross-document-same-origin;
+      @view-transition {
+        navigation: auto;
       }
     `);
     let rule = document.styleSheets[0].cssRules[0];
     assert_equals(rule.cssText,
-        "@view-transitions { navigation-trigger: cross-document-same-origin; }");
-    assert_equals(rule.navigationTrigger, 'cross-document-same-origin');
+        "@view-transition { navigation: auto; }");
+    assert_equals(rule.navigation, 'auto');
 
   });
-}, "`navigation-trigger: cross-document-same-origin` is correctly parsed.");
+}, "`navigation: auto` is correctly parsed.");
 
 test(function () {
   resetStateAndTest(() => {
     document.styleSheets[0].insertRule(`
-      @view-transitions {
-        navigation-trigger: none;
+      @view-transition {
+        navigation: none;
       }
     `);
     let rule = document.styleSheets[0].cssRules[0];
-    assert_equals(rule.cssText, "@view-transitions { navigation-trigger: none; }");
-    assert_equals(rule.navigationTrigger, 'none');
+    assert_equals(rule.cssText, "@view-transition { navigation: none; }");
+    assert_equals(rule.navigation, 'none');
   });
-}, "`navigation-trigger: none` is correctly parsed.");
+}, "`navigation: none` is correctly parsed.");
 
 test(function () {
   resetStateAndTest(() => {
     assert_throws_dom('SyntaxError', () => {
-      document.styleSheets[0].insertRule('@view-transitions foo {}');
+      document.styleSheets[0].insertRule('@view-transition foo {}');
     }, "Failed to execute 'insertRule' on 'CSSStyleSheet': " +
-        "Failed to parse the rule '@view-transitions foo {}'");
+        "Failed to parse the rule '@view-transition foo {}'");
     assert_equals(document.styleSheets[0].cssRules.length, 0);
   });
-}, "@view-transitions fails parsing with a preamble");
+}, "@view-transition fails parsing with a preamble");
 
 test(function () {
   resetStateAndTest(() => {
     document.styleSheets[0].insertRule(`
-      @view-transitions {
-        navigation-trigger: foo;
+      @view-transition {
+        navigation: foo;
       }
     `);
     let rule = document.styleSheets[0].cssRules[0];
-    assert_equals(rule.cssText, "@view-transitions { }");
+    assert_equals(rule.cssText, "@view-transition { }");
   });
-}, "Invalid navigation-trigger fails to parse.");
+}, "Invalid `navigation` value fails to parse.");
 
 test(function () {
   resetStateAndTest(() => {
     document.styleSheets[0].insertRule(`
-      @view-transitions {
-        navigation-trigger: none !important;
+      @view-transition {
+        navigation: none !important;
       }
     `);
     let rule = document.styleSheets[0].cssRules[0];
-    assert_equals(rule.cssText, "@view-transitions { }");
+    assert_equals(rule.cssText, "@view-transition { }");
   });
-}, "navigation-trigger with !important flag should fail to parse.");
+}, "`navigation` with !important flag should fail to parse.");
 
 test(function () {
   resetStateAndTest(() => {
     document.styleSheets[0].insertRule(`
-      @view-transitions {
-        navigation-trigger: none;
+      @view-transition {
+        navigation: none;
       }
     `);
     let rule = document.styleSheets[0].cssRules[0];
-    rule.navigationTrigger = "cross-document-same-origin";
-    assert_equals(rule.navigationTrigger, "cross-document-same-origin");
+    rule.navigation = "auto";
+    assert_equals(rule.navigation, "auto");
   });
-}, "navigation-trigger attribute can be set.");
+}, "`navigation` descriptor can be set.");
 
 test(function () {
   resetStateAndTest(() => {
     document.styleSheets[0].insertRule(`
-      @view-transitions {
-        navigation-trigger: none;
+      @view-transition {
+        navigation: none;
       }
     `);
     let rule = document.styleSheets[0].cssRules[0];
-    rule.navigationTrigger = "foo";
-    assert_equals(rule.navigationTrigger, "none");
+    rule.navigation = "foo";
+    assert_equals(rule.navigation, "none");
   });
-}, "navigation-trigger doesn't set invalid token.");
+}, "Cannot set invalid value to `navigation` descriptor");
 
 </script>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-layer-cascade-external-stylesheet.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-layer-cascade-external-stylesheet.html
index b27e96eb..53c6135a 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-layer-cascade-external-stylesheet.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-layer-cascade-external-stylesheet.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<title>View Transitions: @view-transitions cascaldes correclty with layers in separate external stylesheets.</title>
+<title>View Transitions: @view-transition cascaldes correclty with layers in separate external stylesheets.</title>
 <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
 <link rel="author" href="mailto:bokan@chromium.org">
 <script src="/resources/testharness.js"></script>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-layer-cascade.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-layer-cascade.html
index 25c13b46..a38ca48e 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-layer-cascade.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-layer-cascade.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<title>View Transitions: @view-transitions cascaldes correclty with layers.</title>
+<title>View Transitions: @view-transition cascaldes correclty with layers.</title>
 <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
 <link rel="author" href="mailto:bokan@chromium.org">
 <script src="/resources/testharness.js"></script>
@@ -8,18 +8,18 @@
 @layer inertA, inertB, active;
 
 @layer inertA {
-  @view-transitions {
-    navigation-trigger: none;
+  @view-transition {
+    navigation: none;
   }
 }
 @layer active {
-  @view-transitions {
-    navigation-trigger: cross-document-same-origin;
+  @view-transition {
+    navigation: auto;
   }
 }
 @layer inertB {
-  @view-transitions {
-    navigation-trigger: none;
+  @view-transition {
+    navigation: none;
   }
 }
 </style>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-layer.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-layer.html
index 5923471..63ec4c3 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-layer.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-layer.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
-<title>View Transitions: @view-transitions nested in a @layer rule.</title>
+<title>View Transitions: @view-transition nested in a @layer rule.</title>
 <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
 <link rel="author" href="mailto:bokan@chromium.org">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <style>
 @layer transition {
-  @view-transitions {
-    navigation-trigger: cross-document-same-origin;
+  @view-transition {
+    navigation: auto;
   }
 }
 </style>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-matching-media.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-matching-media.html
index b45eca30..77f2e05c 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-matching-media.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-matching-media.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
-<title>View Transitions: @view-transitions nested in a matching @media rule.</title>
+<title>View Transitions: @view-transition nested in a matching @media rule.</title>
 <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
 <link rel="author" href="mailto:bokan@chromium.org">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <style>
 @media screen {
-  @view-transitions {
-    navigation-trigger: cross-document-same-origin;
+  @view-transition {
+    navigation: auto;
   }
 }
 </style>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-non-matching-media.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-non-matching-media.html
index e750d834..ac9dbde3 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-non-matching-media.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-non-matching-media.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
-<title>View Transitions: @view-transitions nested in a non-matching @media rule.</title>
+<title>View Transitions: @view-transition nested in a non-matching @media rule.</title>
 <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
 <link rel="author" href="mailto:bokan@chromium.org">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <style>
 @media print {
-  @view-transitions {
-    navigation-trigger: cross-document-same-origin;
+  @view-transition {
+    navigation: auto;
   }
 }
 </style>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-shadow-dom.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-shadow-dom.html
index 7b35ede..7edd8e0 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-shadow-dom.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-in-shadow-dom.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<title>View Transitions: @view-transitions not applied from shadow tree.</title>
+<title>View Transitions: @view-transition not applied from shadow tree.</title>
 <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
 <link rel="author" href="mailto:bokan@chromium.org">
 <script src="/resources/testharness.js"></script>
@@ -13,8 +13,8 @@
     const host = document.querySelector("#host");
     const shadow = host.attachShadow({ mode: "open" });
     const style = document.createElement("style");
-    style.textContent = `@view-transitions {
-      navigation-trigger: cross-document-same-origin;
+    style.textContent = `@view-transition {
+      navigation: auto;
     }`;
     shadow.appendChild(style);
     requestAnimationFrame(() => requestAnimationFrame(() => {
@@ -26,8 +26,8 @@
   // be effective by the time the <body> element is parsed and only elements in
   // <body> can be a shadow root.
   const style = document.createElement("style");
-  style.textContent = `@view-transitions {
-    navigation-trigger: cross-document-same-origin;
+  style.textContent = `@view-transition {
+    navigation: auto;
   }`;
   document.head.appendChild(style);
   promise_test(() => {
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-multiple-rules.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-multiple-rules.html
index e1a17f7..5a84d46 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-multiple-rules.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-multiple-rules.html
@@ -1,15 +1,15 @@
 <!DOCTYPE html>
-<title>View Transitions: Multiple @view-transitions, last one wins.</title>
+<title>View Transitions: Multiple @view-transition, last one wins.</title>
 <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
 <link rel="author" href="mailto:bokan@chromium.org">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <style>
-@view-transitions {
-  navigation-trigger: cross-document-same-origin;
+@view-transition {
+  navigation: auto;
 }
-@view-transitions {
-  navigation-trigger: none;
+@view-transition {
+  navigation: none;
 }
 </style>
 <script>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-cross-document-same-origin-ref.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-auto-ref.html
similarity index 82%
rename from third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-cross-document-same-origin-ref.html
rename to third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-auto-ref.html
index ef002a4..9d091fb 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-cross-document-same-origin-ref.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-auto-ref.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<title>View Transitions: @view-transitions opt in for cross-document (ref)</title>
+<title>View Transitions: @view-transition opt in for cross-document (ref)</title>
 <link rel="help" href="https://github.com/WICG/view-transitions">
 <link rel="author" href="mailto:bokan@chromium.org">
 <style>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-auto.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-auto.html
new file mode 100644
index 0000000..2a8e1aa
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-auto.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<title>View Transitions: @view-transition opt in for auto</title>
+<link rel="help" href="https://github.com/WICG/view-transitions">
+<link rel="author" href="mailto:bokan@chromium.org">
+<link rel="match" href="at-rule-opt-in-auto-ref.html">
+<script src="/common/reftest-wait.js"></script>
+<style>
+@view-transition {
+  navigation: auto;
+}
+
+html {
+  background: blue;
+}
+</style>
+<script>
+function runTest() {
+  const url = "resources/at-rule-opt-in-auto.html";
+  window.location.replace(new URL(url, window.location));
+}
+onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
+</script>
+</html>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-cross-document-same-origin.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-cross-document-same-origin.html
deleted file mode 100644
index b8dfd9af..0000000
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-cross-document-same-origin.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<html class="reftest-wait">
-<title>View Transitions: @view-transitions opt in for cross-document-same-origin</title>
-<link rel="help" href="https://github.com/WICG/view-transitions">
-<link rel="author" href="mailto:bokan@chromium.org">
-<link rel="match" href="at-rule-opt-in-cross-document-same-origin-ref.html">
-<script src="/common/reftest-wait.js"></script>
-<style>
-@view-transitions {
-  navigation-trigger: cross-document-same-origin;
-}
-
-html {
-  background: blue;
-}
-</style>
-<script>
-function runTest() {
-  const url = "resources/at-rule-opt-in-cross-document-same-origin.html";
-  window.location.replace(new URL(url, window.location));
-}
-onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
-</script>
-</html>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-none-in-new.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-none-in-new.html
index 4f5c470..a40bb2b 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-none-in-new.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-none-in-new.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
 <html class="reftest-wait">
-<title>View Transitions: @view-transitions opt out in new document.</title>
+<title>View Transitions: @view-transition opt out in new document.</title>
 <link rel="help" href="https://github.com/WICG/view-transitions">
 <link rel="author" href="mailto:bokan@chromium.org">
 <link rel="match" href="at-rule-opt-in-none-ref.html">
 <script src="/common/reftest-wait.js"></script>
 <style>
-@view-transitions {
-  navigation-trigger: cross-document-same-origin;
+@view-transition {
+  navigation: auto;
 }
 html {
   background: blue;
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-none-in-old.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-none-in-old.html
index f645b6a..40c8b89a 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-none-in-old.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-none-in-old.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
 <html class="reftest-wait">
-<title>View Transitions: @view-transitions opt out in new document.</title>
+<title>View Transitions: @view-transition opt out in new document.</title>
 <link rel="help" href="https://github.com/WICG/view-transitions">
 <link rel="author" href="mailto:bokan@chromium.org">
 <link rel="match" href="at-rule-opt-in-none-ref.html">
 <script src="/common/reftest-wait.js"></script>
 <style>
-@view-transitions {
-  navigation-trigger: none;
+@view-transition {
+  navigation: none;
 }
 html {
   background: blue;
@@ -15,7 +15,7 @@
 </style>
 <script>
 function runTest() {
-  const url = "resources/at-rule-opt-in-cross-document-same-origin.html";
+  const url = "resources/at-rule-opt-in-auto.html";
   window.location.replace(new URL(url, window.location));
 }
 onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-none-ref.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-none-ref.html
index 4c8c92d..f484aab9 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-none-ref.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-none-ref.html
@@ -1,11 +1,11 @@
 <!DOCTYPE html>
-<title>View Transitions: @view-transitions opt out in new ocument (ref)</title>
+<title>View Transitions: @view-transition opt out in new ocument (ref)</title>
 <link rel="help" href="https://github.com/WICG/view-transitions">
 <link rel="author" href="mailto:bokan@chromium.org">
 <style>
 :root {
   /*
-   * There should be no transition due to  `navigation-trigger: none` in the
+   * There should be no transition due to  `navigation: none` in the
    * new or old page.
    */
   background: grey;
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-via-cssom.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-via-cssom.html
index 86faf4cb..c2aa006 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-via-cssom.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-in-via-cssom.html
@@ -1,17 +1,17 @@
 <!DOCTYPE html>
-<title>View Transitions: @view-transitions opt-in programmatically.</title>
+<title>View Transitions: @view-transition opt-in programmatically.</title>
 <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
 <link rel="author" href="mailto:bokan@chromium.org">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <style>
-@view-transitions {
-    navigation-trigger: none;
+@view-transition {
+    navigation: none;
 }
 </style>
 <script>
 function optIn() {
-    document.styleSheets[0].cssRules[0].navigationTrigger = 'cross-document-same-origin';
+    document.styleSheets[0].cssRules[0].navigation = 'auto';
 }
 const params = new URLSearchParams(location.search);
 const is_new_page = params.has('new');
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-out-via-cssom.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-out-via-cssom.html
index 9d3e384..f1f5a7b 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-out-via-cssom.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/at-rule-opt-out-via-cssom.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
-<title>View Transitions: @view-transitions opt-out programmatically.</title>
+<title>View Transitions: @view-transition opt-out programmatically.</title>
 <link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
 <link rel="author" href="mailto:bokan@chromium.org">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <style>
-@view-transitions {
-    navigation-trigger: cross-document-same-origin;
+@view-transition {
+    navigation: auto;
 }
 </style>
 <script>
@@ -15,7 +15,7 @@
 
 if (!is_new_page) {
   onload = () => requestAnimationFrame(() => requestAnimationFrame(() => {
-      document.styleSheets[0].rules[0].navigationTrigger = 'none';
+      document.styleSheets[0].rules[0].navigation = 'none';
       location.replace(location.href + '?new');
   }));
 } else {
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-finished-promise.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-finished-promise.html
index c730be7..baac948b 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-finished-promise.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-finished-promise.html
@@ -30,8 +30,8 @@
 }
 </script>
 <style>
-@view-transitions {
-  navigation-trigger: cross-document-same-origin;
+@view-transition {
+  navigation: auto;
 }
 #target {
   width: 100px;
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-ready-promise.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-ready-promise.html
index 2f972bd4..65b370c9 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-ready-promise.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-ready-promise.html
@@ -26,8 +26,8 @@
 }
 </script>
 <style>
-@view-transitions {
-  navigation-trigger: cross-document-same-origin;
+@view-transition {
+  navigation: auto;
 }
 #target {
   width: 100px;
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-setup-transition.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-setup-transition.html
index 8d42f0c..7407824 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-setup-transition.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-setup-transition.html
@@ -27,8 +27,8 @@
 }
 </script>
 <style>
-@view-transitions {
-  navigation-trigger: cross-document-same-origin;
+@view-transition {
+  navigation: auto;
 }
 #target {
   width: 100px;
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-updatecallbackdone-promise.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-updatecallbackdone-promise.html
index d1dab4b..3d259e6 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-updatecallbackdone-promise.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-updatecallbackdone-promise.html
@@ -7,8 +7,8 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <style>
-@view-transitions {
-  navigation-trigger: cross-document-same-origin;
+@view-transition {
+  navigation: auto;
 }
 </style>
 <script>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-with-view-transition.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-with-view-transition.html
index 20b9638..3f21d56 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-with-view-transition.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/pagereveal-with-view-transition.html
@@ -5,8 +5,8 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <style>
-@view-transitions {
-  navigation-trigger: cross-document-same-origin;
+@view-transition {
+  navigation: auto;
 }
 </style>
 <script>
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/at-rule-opt-in-cross-document-same-origin.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/at-rule-opt-in-auto.html
similarity index 82%
rename from third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/at-rule-opt-in-cross-document-same-origin.html
rename to third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/at-rule-opt-in-auto.html
index 8fca8d83..c86ac3f 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/at-rule-opt-in-cross-document-same-origin.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/at-rule-opt-in-auto.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html class="reftest-wait">
-<title>View Transitions: @view-transitions opt in for cross-document-same-origin (new page)</title>
+<title>View Transitions: @view-transition opt in for auto (new page)</title>
 <link rel="help" href="https://github.com/WICG/view-transitions">
 <link rel="author" href="mailto:bokan@chromium.org">
 <script src="/common/reftest-wait.js"></script>
@@ -8,8 +8,8 @@
 onload = takeScreenshot;
 </script>
 <style>
-@view-transitions {
-  navigation-trigger: cross-document-same-origin;
+@view-transition {
+  navigation: auto;
 }
 html {
   background: grey;
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/at-rule-opt-in-none.html b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/at-rule-opt-in-none.html
index 51d8bdddb..ade6d503 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/at-rule-opt-in-none.html
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/at-rule-opt-in-none.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html class="reftest-wait">
-<title>View Transitions: @view-transitions opt out in new document (new page)</title>
+<title>View Transitions: @view-transition opt out in new document (new page)</title>
 <link rel="help" href="https://github.com/WICG/view-transitions">
 <link rel="author" href="mailto:bokan@chromium.org">
 <script src="/common/reftest-wait.js"></script>
@@ -8,8 +8,8 @@
 onload = takeScreenshot;
 </script>
 <style>
-@view-transitions {
-  navigation-trigger: none;
+@view-transition {
+  navigation: none;
 }
 html {
   background: grey;
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/opt-in-style.css b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/opt-in-style.css
index 9d6806e9..9aac2b4 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/opt-in-style.css
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/opt-in-style.css
@@ -1,3 +1,3 @@
-@view-transitions {
-  navigation-trigger: cross-document-same-origin;
+@view-transition {
+  navigation: auto;
 }
diff --git a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/opt-out-style.css b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/opt-out-style.css
index df40819a..f01d587 100644
--- a/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/opt-out-style.css
+++ b/third_party/blink/web_tests/wpt_internal/view-transition-on-navigation/resources/opt-out-style.css
@@ -1,3 +1,3 @@
-@view-transitions {
-  navigation-trigger: none;
+@view-transition {
+  navigation: none;
 }
diff --git a/third_party/catapult b/third_party/catapult
index 23e70e6..e1208d0 160000
--- a/third_party/catapult
+++ b/third_party/catapult
@@ -1 +1 @@
-Subproject commit 23e70e69e5584cd120a57befe5896df916e91dcc
+Subproject commit e1208d01fe87e354960b5f91128aacd65d11f041
diff --git a/third_party/chromite b/third_party/chromite
index 74e55f6..5976e0d 160000
--- a/third_party/chromite
+++ b/third_party/chromite
@@ -1 +1 @@
-Subproject commit 74e55f68b5d4e5e0e958a02b306cc062caf1c7ca
+Subproject commit 5976e0d356895032a85474c875ed9960ba146a98
diff --git a/third_party/chromium-variations b/third_party/chromium-variations
index 0a32d1c..cc3abd9 160000
--- a/third_party/chromium-variations
+++ b/third_party/chromium-variations
@@ -1 +1 @@
-Subproject commit 0a32d1cfed9c8329fbc36c7ed4c264a2b3bdd860
+Subproject commit cc3abd9b31c38f36ad77f404adf37837e33c4c3a
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index 935f0b4..8edc90a 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-13-2-72-gb0265ccd3
-Revision: b0265ccd336cafce6865f6f260e9b61d69459b7e
+Version: VER-2-13-2-73-gc580926f3
+Revision: c580926f354108c1e693364dbe9e64af2d11038a
 CPEPrefix: cpe:/a:freetype:freetype:2.13.2
 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
          JPEG Group) licenses"
diff --git a/third_party/freetype/src b/third_party/freetype/src
index b0265cc..c580926 160000
--- a/third_party/freetype/src
+++ b/third_party/freetype/src
@@ -1 +1 @@
-Subproject commit b0265ccd336cafce6865f6f260e9b61d69459b7e
+Subproject commit c580926f354108c1e693364dbe9e64af2d11038a
diff --git a/third_party/openscreen/src b/third_party/openscreen/src
index 96daa68..4701cb1 160000
--- a/third_party/openscreen/src
+++ b/third_party/openscreen/src
@@ -1 +1 @@
-Subproject commit 96daa682c82a8e7cce45da9cbc49bc4b0ec504bb
+Subproject commit 4701cb1e1777f08c3a40c4f6085f91a294cefc71
diff --git a/third_party/r8/README.chromium b/third_party/r8/README.chromium
index 7b58660..9978743 100644
--- a/third_party/r8/README.chromium
+++ b/third_party/r8/README.chromium
@@ -80,6 +80,7 @@
 
 How to file bugs against R8:
 * Copy & paste the failing ninja command (starts with proguard.py), and add --dump-inputs.
+  * On siso you may need to find it at the beginning of `out/<Directory>/siso_output`.
   * This also works for dex.py, it produces d8inputs.zip
   * As a shortcut: third_party/r8/dump_inputs.py out/Release/apks/ChromePublic.apk.mapping
 * File bug at go/r8bug
diff --git a/third_party/skia b/third_party/skia
index 3b7a62e..55b8b5b 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit 3b7a62e2ac3f4c4dcb00e122f7728865cb125c87
+Subproject commit 55b8b5b71355ab383a379652577109feea758a85
diff --git a/third_party/webgpu-cts/src b/third_party/webgpu-cts/src
index d3e4c53..e14e419 160000
--- a/third_party/webgpu-cts/src
+++ b/third_party/webgpu-cts/src
@@ -1 +1 @@
-Subproject commit d3e4c5300efaec139cc5728c3455508386fe4db2
+Subproject commit e14e419cf67727abe03646e35b7460f96b9d5051
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 985484ef..80f193d 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -184,32 +184,6 @@
       'win-rel-cft': 'release_bot_minimal_symbols_chrome_for_testing_reclient',
     },
 
-    'chromium.chromiumos': {
-      'chromeos-amd64-generic-asan-rel': 'chromeos_amd64-generic_asan_reclient',
-      'chromeos-amd64-generic-cfi-thin-lto-rel': 'chromeos_amd64-generic_cfi_thin_lto_reclient',
-      'chromeos-amd64-generic-dbg': 'chromeos_amd64-generic_dbg_reclient',
-      'chromeos-amd64-generic-lacros-dbg': 'chromeos_amd64-generic_lacros_dbg_reclient',
-      'chromeos-amd64-generic-rel': 'chromeos_amd64-generic-vm_use_fake_dbus_clients_reclient',
-      'chromeos-amd64-generic-rel-renamed': 'chromeos_amd64-generic-vm_use_fake_dbus_clients_reclient',
-      'chromeos-arm-generic-dbg': 'chromeos_arm-generic_dbg_reclient',
-      'chromeos-arm-generic-rel': 'chromeos_arm-generic_reclient',
-      'chromeos-arm64-generic-rel': 'chromeos_arm64-generic_dchecks_reclient',
-      'chromeos-jacuzzi-rel': 'chromeos_jacuzzi_dchecks_reclient',
-      'chromeos-octopus-rel': 'chromeos_octopus_dchecks_reclient',
-      'lacros-amd64-generic-rel': 'chromeos_amd64-generic_lacros_rel_skylab_reclient',
-      'lacros-amd64-generic-rel-non-skylab': 'chromeos_amd64-generic_lacros_rel_reclient',
-      'lacros-arm-generic-rel': 'chromeos_arm-generic_lacros_rel_reclient',
-      'lacros-arm-generic-rel-skylab': 'chromeos_arm-generic_lacros_rel_skylab_reclient',
-      'lacros-arm64-generic-rel': 'chromeos_arm64-generic_lacros_rel_reclient',
-      'lacros-arm64-generic-rel-skylab': 'chromeos_arm64-generic_lacros_rel_skylab_reclient',
-      'linux-ash-chromium-generator-rel': 'chromeos_with_codecs_release_bot_reclient',
-      'linux-cfm-rel': 'linux_cfm_release_bot_reclient',
-      'linux-chromeos-dbg': 'chromeos_with_codecs_debug_bot_reclient',
-      'linux-chromeos-rel': 'chromeos_with_codecs_with_lacros_release_bot_reclient',
-      'linux-lacros-builder-rel': 'lacros_on_linux_release_bot_reclient_with_cups',
-      'linux-lacros-dbg': 'lacros_on_linux_debug_bot_reclient_with_cups',
-    },
-
     'chromium.clang': {
       'ToTLinuxOfficial': 'clang_tot_official',
       'ToTMacOfficial': 'mac_clang_tot_official',
@@ -880,41 +854,12 @@
     },
 
     'tryserver.chromium.chromiumos': {
-      'chromeos-amd64-generic-asan-rel': 'chromeos_amd64-generic_asan_reclient',
-      # TODO(crbug.com/913750): Enable DCHECKS on the two amd64-generic bots
-      # when the PFQ has it enabled.
-      'chromeos-amd64-generic-cfi-thin-lto-rel': 'chromeos_amd64-generic_cfi_thin_lto_reclient',
-      'chromeos-amd64-generic-dbg': 'chromeos_amd64-generic_dbg_reclient_use_dummy_lastchange',
-      'chromeos-amd64-generic-lacros-dbg': 'chromeos_amd64-generic_lacros_dbg_reclient',
-      'chromeos-amd64-generic-rel': 'chromeos_amd64-generic_use_fake_dbus_clients_vm_optimized_dchecks_reclient',
-      'chromeos-amd64-generic-rel-gtest': 'chromeos_amd64-generic_use_fake_dbus_clients_vm_optimized_dchecks_reclient',
-      'chromeos-amd64-generic-rel-gtest-and-tast': 'chromeos_amd64-generic_use_fake_dbus_clients_vm_optimized_dchecks_reclient',
-      'chromeos-amd64-generic-rel-renamed': 'chromeos_amd64-generic_use_fake_dbus_clients_vm_optimized_dchecks_reclient',
       'chromeos-amd64-generic-siso-rel': 'chromeos_amd64-generic_use_fake_dbus_clients_vm_optimized_dchecks_reclient',
-      'chromeos-arm-generic-dbg': 'chromeos_arm-generic_dbg_reclient',
-      'chromeos-arm-generic-rel': 'chromeos_arm-generic_dcheck_always_on_reclient',
-      'chromeos-arm64-generic-rel': 'chromeos_arm64-generic_dchecks_reclient',
-      'chromeos-jacuzzi-rel': 'chromeos_jacuzzi_dchecks_reclient',
-      'chromeos-jacuzzi-rel-skylab': 'chromeos_jacuzzi_rel_skylab_reclient',
-      'chromeos-octopus-rel': 'chromeos_octopus_dchecks_reclient',
       'gpu-fyi-try-chromeos-amd64-generic': 'gpu_tests_chromeos_amd64_release_trybot_dcheck_off_no_symbols_reclient',
       'lacros-amd64-generic-rel': 'chromeos_amd64-generic_lacros_rel_dchecks_skylab_reclient_use_dummy_lastchange',
-      'lacros-amd64-generic-rel-non-skylab': 'chromeos_amd64-generic_lacros_rel_dchecks_reclient',
-      # TODO (crbug.com/1287228): Remove when orchestrator is verified
-      'lacros-amd64-generic-rel-orchestrator': 'chromeos_amd64-generic_lacros_rel_dchecks_skylab_reclient_use_dummy_lastchange',
-      'lacros-arm-generic-rel': 'chromeos_arm-generic_lacros_rel_dchecks_reclient',
-      'lacros-arm-generic-rel-skylab': 'chromeos_arm-generic_lacros_rel_skylab_reclient',
-      'lacros-arm64-generic-rel': 'chromeos_arm64-generic_lacros_rel_dchecks_reclient',
-      'lacros-arm64-generic-rel-skylab': 'chromeos_arm64-generic_lacros_rel_skylab_reclient',
       'lacros-arm64-generic-rel-skylab-fyi': 'chromeos_arm64-generic_lacros_rel_skylab_reclient',
-      'linux-cfm-rel': 'linux_cfm_release_trybot_reclient',
       'linux-chromeos-annotator-rel': 'chromeos_with_codecs_release_trybot_code_coverage_reclient',
-      'linux-chromeos-compile-dbg': 'chromeos_with_codecs_debug_trybot_reclient_no_symbols',
       'linux-chromeos-compile-siso-dbg': 'chromeos_with_codecs_debug_trybot_reclient_no_symbols',
-      'linux-chromeos-dbg': 'chromeos_with_codecs_debug_trybot_reclient',
-      'linux-chromeos-rel': 'chromeos_with_codecs_release_trybot_code_coverage_reclient',
-      'linux-lacros-dbg': 'lacros_on_linux_debug_bot_reclient_with_cups',
-      'linux-lacros-rel': 'lacros_on_linux_release_trybot_reclient_code_coverage_with_cups',
     },
 
     'tryserver.chromium.codesearch': {
@@ -1578,27 +1523,6 @@
       'also_build_lacros_chrome_for_architecture_amd64',
     ],
 
-    'chromeos_amd64-generic_asan_reclient': [
-      'chromeos_amd64-generic_reclient', 'asan',
-    ],
-
-    'chromeos_amd64-generic_cfi_thin_lto_reclient': [
-      'chromeos_amd64-generic_reclient', 'cfi_full', 'thin_lto',
-      'also_build_lacros_chrome_for_architecture_amd64',
-    ],
-
-    'chromeos_amd64-generic_dbg_reclient': [
-      'chromeos_amd64-generic_reclient', 'debug',
-    ],
-
-    'chromeos_amd64-generic_dbg_reclient_use_dummy_lastchange': [
-      'chromeos_amd64-generic_reclient', 'debug', 'use_dummy_lastchange',
-    ],
-
-    'chromeos_amd64-generic_lacros_dbg_reclient': [
-      'chromeos_amd64-generic-crostoolchain_reclient', 'lacros', 'debug', 'static',
-    ],
-
     'chromeos_amd64-generic_lacros_official': [
       'chromeos_amd64-generic-crostoolchain', 'lacros', 'official', 'minimal_symbols', 'cfi', 'thin_lto', 'no_reclient', 'goma',
     ],
@@ -1625,10 +1549,6 @@
       'chromeos_amd64-generic-crostoolchain_reclient', 'lacros', 'official', 'minimal_symbols', 'cfi', 'thin_lto', 'is_skylab',
     ],
 
-    'chromeos_amd64-generic_lacros_rel_dchecks_reclient': [
-      'chromeos_amd64-generic-crostoolchain_reclient', 'lacros', 'release', 'dcheck_always_on', 'use_dummy_lastchange',
-    ],
-
     'chromeos_amd64-generic_lacros_rel_dchecks_skylab_reclient_use_dummy_lastchange': [
       'chromeos_amd64-generic-crostoolchain_reclient', 'lacros', 'release', 'dcheck_always_on', 'is_skylab', 'use_dummy_lastchange',
     ],
@@ -1658,14 +1578,6 @@
       'chromeos_device_reclient', 'arm-generic', 'cfi_full', 'thin_lto', 'official', 'full_symbols', 'ozone_headless'
     ],
 
-    'chromeos_arm-generic_dbg_reclient': [
-      'chromeos_device_reclient', 'arm-generic', 'debug', 'ozone_headless'
-    ],
-
-    'chromeos_arm-generic_dcheck_always_on_reclient': [
-      'chromeos_device_reclient', 'arm-generic', 'dcheck_always_on', 'ozone_headless', 'use_dummy_lastchange',
-    ],
-
     'chromeos_arm-generic_lacros_official_reclient': [
       'chromeos_arm-generic-crostoolchain_reclient', 'lacros', 'official', 'minimal_symbols', 'cfi', 'thin_lto',
     ],
@@ -1677,10 +1589,6 @@
       'chromeos_arm-generic-crostoolchain_reclient', 'lacros', 'official', 'minimal_symbols', 'cfi', 'thin_lto', 'is_skylab',
     ],
 
-    'chromeos_arm-generic_lacros_rel_dchecks_reclient': [
-      'chromeos_arm-generic-crostoolchain_reclient', 'lacros', 'release', 'dcheck_always_on', 'use_dummy_lastchange',
-    ],
-
     'chromeos_arm-generic_lacros_rel_reclient': [
       'chromeos_arm-generic-crostoolchain_reclient', 'lacros', 'release',
     ],
@@ -1689,10 +1597,6 @@
       'chromeos_arm-generic-crostoolchain_reclient', 'lacros', 'release','is_skylab',
     ],
 
-    'chromeos_arm-generic_reclient': [
-      'chromeos_device_reclient', 'arm-generic', 'ozone_headless'
-    ],
-
     'chromeos_arm64-generic_cfi_thin_lto_official': [
       'chromeos_device', 'arm64-generic', 'cfi_full', 'thin_lto', 'official', 'full_symbols',
     ],
@@ -1700,10 +1604,6 @@
       'chromeos_device_reclient', 'arm64-generic', 'cfi_full', 'thin_lto', 'official', 'full_symbols', 'ozone_headless'
     ],
 
-    'chromeos_arm64-generic_dchecks_reclient': [
-      'chromeos_device_reclient', 'arm64-generic', 'dcheck_always_on', 'ozone_headless'
-    ],
-
     'chromeos_arm64-generic_lacros_official_reclient': [
       'chromeos_arm64-generic-crostoolchain_reclient', 'lacros', 'official', 'minimal_symbols', 'cfi', 'thin_lto',
     ],
@@ -1715,10 +1615,6 @@
       'chromeos_arm64-generic-crostoolchain_reclient', 'lacros', 'official', 'minimal_symbols', 'cfi', 'thin_lto', 'is_skylab',
     ],
 
-    'chromeos_arm64-generic_lacros_rel_dchecks_reclient': [
-      'chromeos_arm64-generic-crostoolchain_reclient', 'lacros', 'release', 'dcheck_always_on',
-    ],
-
     'chromeos_arm64-generic_lacros_rel_reclient': [
       'chromeos_arm64-generic-crostoolchain_reclient', 'lacros', 'release',
     ],
@@ -1789,9 +1685,6 @@
       'also_build_lacros_chrome_for_architecture_amd64', 'ozone_headless'
     ],
 
-    'chromeos_jacuzzi_dchecks_reclient': [
-      'chromeos_jacuzzi_reclient', 'dcheck_always_on',
-    ],
     'chromeos_jacuzzi_include_unwind_tables_official': [
       'chromeos_device', 'jacuzzi', 'include_unwind_tables', 'official',
       # TODO(crbug.com/1275785): Enable DCHECKs on jacuzzi bots when the
@@ -1835,10 +1728,6 @@
       'chromeos', 'msan', 'release_bot_reclient',
     ],
 
-    'chromeos_octopus_dchecks_reclient': [
-      'chromeos_octopus_reclient', 'dcheck_always_on',
-    ],
-
     'chromeos_octopus_include_unwind_tables_official_dchecks': [
       'chromeos_device', 'octopus', 'include_unwind_tables', 'official', 'dcheck_always_on',
       'also_build_lacros_chrome_for_architecture_amd64',
@@ -1884,14 +1773,6 @@
       'also_build_lacros_chrome_for_architecture_amd64',
     ],
 
-    'chromeos_with_codecs_debug_bot_reclient': [
-      'chromeos_with_codecs', 'debug_bot_reclient', 'use_cups',
-    ],
-
-    'chromeos_with_codecs_debug_trybot_reclient': [
-      'chromeos_with_codecs', 'debug_bot_reclient', 'use_cups', 'use_dummy_lastchange',
-    ],
-
     'chromeos_with_codecs_debug_trybot_reclient_no_symbols': [
       'chromeos_with_codecs', 'debug_bot_reclient', 'no_symbols', 'use_cups', 'use_dummy_lastchange',
     ],
@@ -1922,10 +1803,6 @@
       'chromeos_with_codecs', 'release_trybot_reclient', 'no_symbols',
     ],
 
-    'chromeos_with_codecs_with_lacros_release_bot_reclient': [
-      'chromeos_with_codecs', 'release_bot_reclient', 'use_cups', 'also_build_lacros_chrome'
-    ],
-
     'clang_code_coverage_ios_xctest_reclient': [
       'use_clang_coverage', 'debug_static_bot_reclient', 'x64', 'ios', 'xctest',
     ],
@@ -2380,18 +2257,10 @@
       'lacros_on_linux', 'debug_bot_reclient', 'also_build_ash_chrome',
     ],
 
-    'lacros_on_linux_debug_bot_reclient_with_cups': [
-      'lacros_on_linux', 'debug_bot_reclient', 'also_build_ash_chrome', 'use_cups',
-    ],
-
     'lacros_on_linux_release_bot_reclient': [
       'lacros_on_linux', 'release_bot_reclient', 'also_build_ash_chrome',
     ],
 
-    'lacros_on_linux_release_bot_reclient_with_cups': [
-      'lacros_on_linux', 'release_bot_reclient', 'also_build_ash_chrome', 'use_cups',
-    ],
-
     'lacros_on_linux_release_not_build_ash_bot_reclient': [
       'lacros_on_linux', 'release_bot_reclient',
     ],
@@ -2400,10 +2269,6 @@
       'lacros_on_linux_release_trybot_reclient',
     ],
 
-    'lacros_on_linux_release_trybot_reclient_code_coverage_with_cups': [
-      'lacros_on_linux_release_trybot_reclient', 'clang', 'use_clang_coverage', 'use_cups', 'partial_code_coverage_instrumentation', 'use_dummy_lastchange',
-    ],
-
     'libfuzzer_asan_debug_bot_reclient': [
       'libfuzzer', 'asan', 'debug_bot_reclient', 'shared', 'chromeos_codecs', 'pdf_xfa', 'disable_nacl', 'optimize_for_fuzzing', 'disable_seed_corpus',
     ],
@@ -2487,14 +2352,6 @@
       'release_bot_reclient', 'updater',
     ],
 
-    'linux_cfm_release_bot_reclient': [
-      'cfm', 'release_bot_reclient', 'chromeos',
-    ],
-
-    'linux_cfm_release_trybot_reclient': [
-      'cfm', 'release_trybot_reclient', 'chromeos',
-    ],
-
     'linux_fuzz_coverage':[
       'use_clang_coverage', 'static', 'mojo_fuzzer', 'libfuzzer', 'dcheck_off', 'disable_nacl',
       'reclient', 'chromeos_codecs', 'pdf_xfa'
@@ -3116,10 +2973,6 @@
       'gn_args': 'also_build_lacros_chrome_for_architecture="arm64"',
     },
 
-    'amd64-generic': {
-      'args_file': '//build/args/chromeos/amd64-generic.gni',
-    },
-
     'amd64-generic-crostoolchain': {
       'args_file': '//build/args/chromeos/amd64-generic-crostoolchain.gni',
     },
@@ -3269,10 +3122,6 @@
       'gn_args': 'use_cfi_icall=true',
     },
 
-    'cfm': {
-      'gn_args': 'is_cfm=true',
-    },
-
     'chrome_branded': {
       'gn_args': 'is_chrome_branded=true'
     },
@@ -3309,10 +3158,6 @@
       'mixins': ['chromeos_device_reclient', 'amd64-generic-vm', 'ozone_headless']
     },
 
-    'chromeos_amd64-generic_reclient': {
-      'mixins': ['chromeos_device_reclient', 'amd64-generic', 'ozone_headless']
-    },
-
     'chromeos_arm-generic-crostoolchain': {
       'mixins': ['chromeos_device', 'arm-generic-crostoolchain',]
     },
@@ -3351,10 +3196,6 @@
       'mixins': ['chromeos_device_reclient', 'kevin', 'ozone_headless']
     },
 
-    'chromeos_octopus_reclient': {
-      'mixins': ['chromeos_device_reclient', 'octopus', 'ozone_headless']
-    },
-
     'chromeos_with_codecs': {
       'mixins': ['chromeos', 'chromeos_codecs'],
     },
diff --git a/tools/mb/mb_config_expectations/chromium.chromiumos.json b/tools/mb/mb_config_expectations/chromium.chromiumos.json
deleted file mode 100644
index 488415f..0000000
--- a/tools/mb/mb_config_expectations/chromium.chromiumos.json
+++ /dev/null
@@ -1,262 +0,0 @@
-{
-  "chromeos-amd64-generic-asan-rel": {
-    "args_file": "//build/args/chromeos/amd64-generic.gni",
-    "gn_args": {
-      "dcheck_always_on": false,
-      "is_asan": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-amd64-generic-cfi-thin-lto-rel": {
-    "args_file": "//build/args/chromeos/amd64-generic.gni",
-    "gn_args": {
-      "also_build_lacros_chrome_for_architecture": "amd64",
-      "dcheck_always_on": false,
-      "is_cfi": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_cfi_cast": true,
-      "use_remoteexec": true,
-      "use_thin_lto": true
-    }
-  },
-  "chromeos-amd64-generic-dbg": {
-    "args_file": "//build/args/chromeos/amd64-generic.gni",
-    "gn_args": {
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_debug": true,
-      "ozone_platform_headless": true,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-amd64-generic-lacros-dbg": {
-    "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_component_build": false,
-      "is_debug": true,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-amd64-generic-rel": {
-    "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
-    "gn_args": {
-      "also_build_lacros_chrome_for_architecture": "amd64",
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_real_dbus_clients": false,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-amd64-generic-rel-renamed": {
-    "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
-    "gn_args": {
-      "also_build_lacros_chrome_for_architecture": "amd64",
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_real_dbus_clients": false,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-arm-generic-dbg": {
-    "args_file": "//build/args/chromeos/arm-generic.gni",
-    "gn_args": {
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_debug": true,
-      "ozone_platform_headless": true,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-arm-generic-rel": {
-    "args_file": "//build/args/chromeos/arm-generic.gni",
-    "gn_args": {
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-arm64-generic-rel": {
-    "args_file": "//build/args/chromeos/arm64-generic.gni",
-    "gn_args": {
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-jacuzzi-rel": {
-    "args_file": "//build/args/chromeos/jacuzzi.gni",
-    "gn_args": {
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-octopus-rel": {
-    "args_file": "//build/args/chromeos/octopus.gni",
-    "gn_args": {
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_remoteexec": true
-    }
-  },
-  "lacros-amd64-generic-rel": {
-    "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_debug": false,
-      "is_skylab": true,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_remoteexec": true
-    }
-  },
-  "lacros-amd64-generic-rel-non-skylab": {
-    "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_debug": false,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_remoteexec": true
-    }
-  },
-  "lacros-arm-generic-rel": {
-    "args_file": "//build/args/chromeos/arm-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_debug": false,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_remoteexec": true
-    }
-  },
-  "lacros-arm-generic-rel-skylab": {
-    "args_file": "//build/args/chromeos/arm-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_debug": false,
-      "is_skylab": true,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_remoteexec": true
-    }
-  },
-  "lacros-arm64-generic-rel": {
-    "args_file": "//build/args/chromeos/arm64-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_debug": false,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_remoteexec": true
-    }
-  },
-  "lacros-arm64-generic-rel-skylab": {
-    "args_file": "//build/args/chromeos/arm64-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_debug": false,
-      "is_skylab": true,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_remoteexec": true
-    }
-  },
-  "linux-ash-chromium-generator-rel": {
-    "gn_args": {
-      "dcheck_always_on": false,
-      "ffmpeg_branding": "ChromeOS",
-      "is_component_build": false,
-      "is_debug": false,
-      "proprietary_codecs": true,
-      "target_os": "chromeos",
-      "use_cups": true,
-      "use_remoteexec": true
-    }
-  },
-  "linux-cfm-rel": {
-    "gn_args": {
-      "dcheck_always_on": false,
-      "is_cfm": true,
-      "is_component_build": false,
-      "is_debug": false,
-      "target_os": "chromeos",
-      "use_remoteexec": true
-    }
-  },
-  "linux-chromeos-dbg": {
-    "gn_args": {
-      "ffmpeg_branding": "ChromeOS",
-      "is_component_build": true,
-      "is_debug": true,
-      "proprietary_codecs": true,
-      "symbol_level": 1,
-      "target_os": "chromeos",
-      "use_cups": true,
-      "use_remoteexec": true
-    }
-  },
-  "linux-chromeos-rel": {
-    "gn_args": {
-      "also_build_lacros_chrome": true,
-      "dcheck_always_on": false,
-      "ffmpeg_branding": "ChromeOS",
-      "is_component_build": false,
-      "is_debug": false,
-      "proprietary_codecs": true,
-      "target_os": "chromeos",
-      "use_cups": true,
-      "use_remoteexec": true
-    }
-  },
-  "linux-lacros-builder-rel": {
-    "gn_args": {
-      "also_build_ash_chrome": true,
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": false,
-      "is_component_build": false,
-      "is_debug": false,
-      "target_os": "chromeos",
-      "use_cups": true,
-      "use_remoteexec": true
-    }
-  },
-  "linux-lacros-dbg": {
-    "gn_args": {
-      "also_build_ash_chrome": true,
-      "chromeos_is_browser_only": true,
-      "is_component_build": true,
-      "is_debug": true,
-      "symbol_level": 1,
-      "target_os": "chromeos",
-      "use_cups": true,
-      "use_remoteexec": true
-    }
-  }
-}
\ No newline at end of file
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json b/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
index 58fd47ba..82a1a781 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.chromiumos.json
@@ -1,99 +1,4 @@
 {
-  "chromeos-amd64-generic-asan-rel": {
-    "args_file": "//build/args/chromeos/amd64-generic.gni",
-    "gn_args": {
-      "dcheck_always_on": false,
-      "is_asan": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-amd64-generic-cfi-thin-lto-rel": {
-    "args_file": "//build/args/chromeos/amd64-generic.gni",
-    "gn_args": {
-      "also_build_lacros_chrome_for_architecture": "amd64",
-      "dcheck_always_on": false,
-      "is_cfi": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_cfi_cast": true,
-      "use_remoteexec": true,
-      "use_thin_lto": true
-    }
-  },
-  "chromeos-amd64-generic-dbg": {
-    "args_file": "//build/args/chromeos/amd64-generic.gni",
-    "gn_args": {
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_debug": true,
-      "ozone_platform_headless": true,
-      "use_dummy_lastchange": true,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-amd64-generic-lacros-dbg": {
-    "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_component_build": false,
-      "is_debug": true,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-amd64-generic-rel": {
-    "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
-    "gn_args": {
-      "also_build_lacros_chrome_for_architecture": "amd64",
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_dummy_lastchange": true,
-      "use_real_dbus_clients": false,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-amd64-generic-rel-gtest": {
-    "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
-    "gn_args": {
-      "also_build_lacros_chrome_for_architecture": "amd64",
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_dummy_lastchange": true,
-      "use_real_dbus_clients": false,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-amd64-generic-rel-gtest-and-tast": {
-    "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
-    "gn_args": {
-      "also_build_lacros_chrome_for_architecture": "amd64",
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_dummy_lastchange": true,
-      "use_real_dbus_clients": false,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-amd64-generic-rel-renamed": {
-    "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
-    "gn_args": {
-      "also_build_lacros_chrome_for_architecture": "amd64",
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_dummy_lastchange": true,
-      "use_real_dbus_clients": false,
-      "use_remoteexec": true
-    }
-  },
   "chromeos-amd64-generic-siso-rel": {
     "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
     "gn_args": {
@@ -106,65 +11,6 @@
       "use_remoteexec": true
     }
   },
-  "chromeos-arm-generic-dbg": {
-    "args_file": "//build/args/chromeos/arm-generic.gni",
-    "gn_args": {
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_debug": true,
-      "ozone_platform_headless": true,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-arm-generic-rel": {
-    "args_file": "//build/args/chromeos/arm-generic.gni",
-    "gn_args": {
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_dummy_lastchange": true,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-arm64-generic-rel": {
-    "args_file": "//build/args/chromeos/arm64-generic.gni",
-    "gn_args": {
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-jacuzzi-rel": {
-    "args_file": "//build/args/chromeos/jacuzzi.gni",
-    "gn_args": {
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-jacuzzi-rel-skylab": {
-    "args_file": "//build/args/chromeos/jacuzzi.gni",
-    "gn_args": {
-      "also_build_lacros_chrome_for_architecture": "arm",
-      "dcheck_always_on": false,
-      "exclude_unwind_tables": false,
-      "is_chromeos_device": true,
-      "is_skylab": true,
-      "ozone_platform_headless": true,
-      "use_remoteexec": true
-    }
-  },
-  "chromeos-octopus-rel": {
-    "args_file": "//build/args/chromeos/octopus.gni",
-    "gn_args": {
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "ozone_platform_headless": true,
-      "use_remoteexec": true
-    }
-  },
   "gpu-fyi-try-chromeos-amd64-generic": {
     "args_file": "//build/args/chromeos/amd64-generic-vm.gni",
     "gn_args": {
@@ -194,84 +40,6 @@
       "use_remoteexec": true
     }
   },
-  "lacros-amd64-generic-rel-non-skylab": {
-    "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "is_debug": false,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_dummy_lastchange": true,
-      "use_remoteexec": true
-    }
-  },
-  "lacros-amd64-generic-rel-orchestrator": {
-    "args_file": "//build/args/chromeos/amd64-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "is_debug": false,
-      "is_skylab": true,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_dummy_lastchange": true,
-      "use_remoteexec": true
-    }
-  },
-  "lacros-arm-generic-rel": {
-    "args_file": "//build/args/chromeos/arm-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "is_debug": false,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_dummy_lastchange": true,
-      "use_remoteexec": true
-    }
-  },
-  "lacros-arm-generic-rel-skylab": {
-    "args_file": "//build/args/chromeos/arm-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_debug": false,
-      "is_skylab": true,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_remoteexec": true
-    }
-  },
-  "lacros-arm64-generic-rel": {
-    "args_file": "//build/args/chromeos/arm64-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": true,
-      "is_chromeos_device": true,
-      "is_debug": false,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_remoteexec": true
-    }
-  },
-  "lacros-arm64-generic-rel-skylab": {
-    "args_file": "//build/args/chromeos/arm64-generic-crostoolchain.gni",
-    "gn_args": {
-      "chromeos_is_browser_only": true,
-      "dcheck_always_on": false,
-      "is_chromeos_device": true,
-      "is_debug": false,
-      "is_skylab": true,
-      "ozone_platform_headless": true,
-      "target_os": "chromeos",
-      "use_remoteexec": true
-    }
-  },
   "lacros-arm64-generic-rel-skylab-fyi": {
     "args_file": "//build/args/chromeos/arm64-generic-crostoolchain.gni",
     "gn_args": {
@@ -285,18 +53,6 @@
       "use_remoteexec": true
     }
   },
-  "linux-cfm-rel": {
-    "gn_args": {
-      "dcheck_always_on": true,
-      "is_cfm": true,
-      "is_component_build": false,
-      "is_debug": false,
-      "symbol_level": 0,
-      "target_os": "chromeos",
-      "use_dummy_lastchange": true,
-      "use_remoteexec": true
-    }
-  },
   "linux-chromeos-annotator-rel": {
     "gn_args": {
       "also_build_lacros_chrome": true,
@@ -317,19 +73,6 @@
       "use_remoteexec": true
     }
   },
-  "linux-chromeos-compile-dbg": {
-    "gn_args": {
-      "ffmpeg_branding": "ChromeOS",
-      "is_component_build": true,
-      "is_debug": true,
-      "proprietary_codecs": true,
-      "symbol_level": 0,
-      "target_os": "chromeos",
-      "use_cups": true,
-      "use_dummy_lastchange": true,
-      "use_remoteexec": true
-    }
-  },
   "linux-chromeos-compile-siso-dbg": {
     "gn_args": {
       "ffmpeg_branding": "ChromeOS",
@@ -342,67 +85,5 @@
       "use_dummy_lastchange": true,
       "use_remoteexec": true
     }
-  },
-  "linux-chromeos-dbg": {
-    "gn_args": {
-      "ffmpeg_branding": "ChromeOS",
-      "is_component_build": true,
-      "is_debug": true,
-      "proprietary_codecs": true,
-      "symbol_level": 1,
-      "target_os": "chromeos",
-      "use_cups": true,
-      "use_dummy_lastchange": true,
-      "use_remoteexec": true
-    }
-  },
-  "linux-chromeos-rel": {
-    "gn_args": {
-      "also_build_lacros_chrome": true,
-      "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
-      "dcheck_always_on": true,
-      "enable_backup_ref_ptr_feature_flag": true,
-      "enable_dangling_raw_ptr_checks": true,
-      "enable_dangling_raw_ptr_feature_flag": true,
-      "ffmpeg_branding": "ChromeOS",
-      "is_component_build": false,
-      "is_debug": false,
-      "proprietary_codecs": true,
-      "symbol_level": 0,
-      "target_os": "chromeos",
-      "use_clang_coverage": true,
-      "use_cups": true,
-      "use_dummy_lastchange": true,
-      "use_remoteexec": true
-    }
-  },
-  "linux-lacros-dbg": {
-    "gn_args": {
-      "also_build_ash_chrome": true,
-      "chromeos_is_browser_only": true,
-      "is_component_build": true,
-      "is_debug": true,
-      "symbol_level": 1,
-      "target_os": "chromeos",
-      "use_cups": true,
-      "use_remoteexec": true
-    }
-  },
-  "linux-lacros-rel": {
-    "gn_args": {
-      "also_build_ash_chrome": true,
-      "chromeos_is_browser_only": true,
-      "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
-      "dcheck_always_on": true,
-      "is_clang": true,
-      "is_component_build": false,
-      "is_debug": false,
-      "symbol_level": 0,
-      "target_os": "chromeos",
-      "use_clang_coverage": true,
-      "use_cups": true,
-      "use_dummy_lastchange": true,
-      "use_remoteexec": true
-    }
   }
 }
\ No newline at end of file
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 43a94cc..4a64efc3 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -17052,6 +17052,24 @@
   <int value="3" label="Keyboard"/>
 </enum>
 
+<enum name="DocsOfflineEnableStatus">
+  <int value="0" label="Unknown"/>
+  <int value="1" label="Success"/>
+  <int value="2" label="Already enabled"/>
+  <int value="3" label="Unknown error"/>
+  <int value="4" label="Disable unsupported"/>
+  <int value="5" label="Offline eligible"/>
+  <int value="6" label="Offline ineligible - Unknown"/>
+  <int value="7" label="Offline ineligible - Other user already enabled"/>
+  <int value="8" label="Offline ineligible - DD in invalid state"/>
+  <int value="9" label="Offline ineligible - Policy disallow"/>
+  <int value="10" label="Offline ineligible - No extension"/>
+  <int value="11" label="Offline ineligible - Insufficient disk space"/>
+  <int value="12" label="Native message host error"/>
+  <int value="13" label="Native message client error"/>
+  <int value="14" label="System error"/>
+</enum>
+
 <enum name="DocumentPolicyFeature">
 <!-- Generated from third_party/blink/public/mojom/permissions_policy/document_policy_feature.mojom.
 Called by update_document_policy_enum.py.-->
@@ -27594,7 +27612,7 @@
   <int value="4623" label="V8RTCEncodedVideoFrame_SetMetadata_Method"/>
   <int value="4624" label="V8RTCEncodedVideoFrame_SetTimestamp_Method"/>
   <int value="4625" label="V8RTCEncodedAudioFrame_SetTimestamp_Method"/>
-  <int value="4626" label="CSSAtRuleViewTransitions"/>
+  <int value="4626" label="CSSAtRuleViewTransition"/>
   <int value="4627" label="SharedDictionaryUsedWithSharedBrotli"/>
   <int value="4628" label="SharedDictionaryUsedWithSharedZstd"/>
   <int value="4629" label="ZstdContentEncoding"/>
@@ -34563,6 +34581,7 @@
   <int value="35"
       label="Profile menu of installable chrome://password-manager WebUI)"/>
   <int value="36" label="Launch from system tray Calendar"/>
+  <int value="37" label="Installer"/>
 </enum>
 
 <enum name="LaunchWebAuthFlowResult">
@@ -37040,6 +37059,7 @@
   <int value="-1541187160" label="UsernameFirstFlow:disabled"/>
   <int value="-1540007054" label="ArcHostVpn:disabled"/>
   <int value="-1539513973" label="ContentSettingsRedesign:disabled"/>
+  <int value="-1538921509" label="AutofillEnableCardBenefits:disabled"/>
   <int value="-1538752676" label="IncognitoBrandConsistencyForAndroid:enabled"/>
   <int value="-1538734579"
       label="AutofillEnableSendingBcnInGetUploadDetails:disabled"/>
@@ -37678,6 +37698,7 @@
   <int value="-1251359563" label="SharingRenameDevices:disabled"/>
   <int value="-1250965985" label="MediaFeeds:enabled"/>
   <int value="-1250611337" label="ChromeVoxArcSupport:disabled"/>
+  <int value="-1250299966" label="SuspiciousSiteDetectionRTLookups:enabled"/>
   <int value="-1250240035" label="NearbySharingOnePageOnboarding:enabled"/>
   <int value="-1250222445" label="WebMidi:enabled"/>
   <int value="-1249349654" label="UseAndroidStagingSmds:disabled"/>
@@ -38031,6 +38052,7 @@
   <int value="-1078093206" label="ash-debug-shortcuts"/>
   <int value="-1077752943" label="enable-password-generation"/>
   <int value="-1077534880" label="OmniboxDynamicMaxAutocomplete:enabled"/>
+  <int value="-1077006912" label="ReadAnythingOmniboxIcon:disabled"/>
   <int value="-1075156797" label="enable-brotli"/>
   <int value="-1075089382" label="enable-physical-web"/>
   <int value="-1074257709" label="ScalableAppList:enabled"/>
@@ -39854,6 +39876,7 @@
   <int value="-195029497" label="MediaRemoting:disabled"/>
   <int value="-192962976" label="CCTResizableAlwaysShowNavBarButtons:enabled"/>
   <int value="-192919826" label="ViewsSimplifiedFullscreenUI:enabled"/>
+  <int value="-192433738" label="AutofillEnableCardBenefits:enabled"/>
   <int value="-192389983" label="NoStatePrefetch:enabled"/>
   <int value="-190723154" label="AppLaunchAutomation:enabled"/>
   <int value="-190449995" label="CommerceLocalPDPDetection:enabled"/>
@@ -41747,6 +41770,7 @@
   <int value="715957869" label="SendTabToSelfSigninPromo:disabled"/>
   <int value="716073306" label="AssistantVoiceMatch:disabled"/>
   <int value="716080990" label="restrict-iframe-permissions"/>
+  <int value="716592729" label="SuspiciousSiteDetectionRTLookups:disabled"/>
   <int value="717020975" label="ForceOffTextAutosizing:disabled"/>
   <int value="717591093" label="UrlLoaderSyncClient:disabled"/>
   <int value="717827121" label="ChromeSharingHub:disabled"/>
@@ -42951,6 +42975,7 @@
   <int value="1292091029" label="OmniboxOneClickUnelide:disabled"/>
   <int value="1292482533" label="EnableTabMuting:disabled"/>
   <int value="1292763218" label="SystemTrayUnified:disabled"/>
+  <int value="1293292046" label="ReadAnythingOmniboxIcon:enabled"/>
   <int value="1293473298" label="PageInfoAboutThisSiteNewIcon:disabled"/>
   <int value="1293697921" label="RequestDesktopSiteExceptions:enabled"/>
   <int value="1294131571" label="disable-winrt-midi-api"/>
@@ -45916,7 +45941,7 @@
   <int value="765" label="position-fallback-bounds"/>
   <int value="766" label="transition-behavior"/>
   <int value="767" label="text-autospace"/>
-  <int value="768" label="navigation-trigger"/>
+  <int value="768" label="navigation"/>
   <int value="769" label="dynamic-range-limit"/>
   <int value="770" label="field-sizing"/>
   <int value="771" label="text-spacing-trim"/>
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml
index 2361a6d..c1c8026 100644
--- a/tools/metrics/histograms/metadata/apps/histograms.xml
+++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -2052,6 +2052,7 @@
     <variant name=".FromFullRestore" summary="From full restore."/>
     <variant name=".FromInstalledNotification"
         summary="From installed notification."/>
+    <variant name=".FromInstaller" summary="From Intallation UI."/>
     <variant name=".FromIntentUrl" summary="From Intent Url."/>
     <variant name=".FromKeyboard" summary="From keyboard shortcut."/>
     <variant name=".FromKiosk" summary="From Kiosk."/>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml
index 04aac2d..22ede01c 100644
--- a/tools/metrics/histograms/metadata/ash/histograms.xml
+++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -5706,11 +5706,7 @@
     The number of feature pods (e.g. WiFi, Bluetooth, IME, Accessibility, etc.)
     in the system tray quick settings when it is opened, including pods that
     overflow to other pages. This metric is logged by 2 different types of
-    {DeviceMode}: &quot;Clamshell&quot; and &quot;Tablet&quot;. This metric gets
-    recorded for both the new quick settings view and the old unified system
-    view, see
-    &quot;Ash.UnifiedSystemView.{DeviceMode}.FeaturePodCountOnOpen&quot; which
-    is the metric for the old view.
+    {DeviceMode}: &quot;Clamshell&quot; and &quot;Tablet&quot;.
   </summary>
   <token key="DeviceMode">
     <variant name="Clamshell" summary="Regular mode"/>
@@ -6729,69 +6725,6 @@
   </summary>
 </histogram>
 
-<histogram name="Ash.UnifiedSystemView.Button.Activated"
-    enum="QsButtonCatalogName" expires_after="2024-07-30">
-  <owner>jiamingc@google.com</owner>
-  <owner>cros-status-area-eng@google.com</owner>
-  <summary>
-    Recorded when any button in the old quick settings view is activated.
-  </summary>
-</histogram>
-
-<histogram name="Ash.UnifiedSystemView.FeaturePod.{FeaturePodBehavior}"
-    enum="QsFeatureCatalogName" expires_after="2024-07-30">
-  <owner>jiamingc@google.com</owner>
-  <owner>cros-status-area-eng@google.com</owner>
-  <summary>
-    Recorded when an action is done on any FeaturePod in the old quick settings
-    view. {FeaturePodBehavior} can be a toggle to enable the feature, toggle to
-    disable this feature, going to the feature's detailed page, or making the
-    button visible.
-  </summary>
-  <token key="FeaturePodBehavior">
-    <variant name="DiveIn" summary="Go to the feature's detailed page"/>
-    <variant name="ToggledOff" summary="Toggle to disable the feature"/>
-    <variant name="ToggledOn" summary="Toggle to enable the feature"/>
-    <variant name="Visible" summary="The feature pod is shown"/>
-  </token>
-</histogram>
-
-<histogram name="Ash.UnifiedSystemView.Slider.{SliderBehavior}"
-    enum="QsSliderCatalogName" expires_after="2024-07-30">
-  <owner>jiamingc@google.com</owner>
-  <owner>cros-status-area-eng@google.com</owner>
-  <summary>
-    Recorded when an action is done on any slider in the old quick settings view
-    or in the slider bubble. {SliderBehavior} can be changing the value or
-    toggling to enable the feature.
-  </summary>
-  <token key="SliderBehavior">
-    <variant name="DisableFeature" summary="Toggle to disable the feature"/>
-    <variant name="Down" summary="Turn the slider value down"/>
-    <variant name="EnableFeature" summary="Toggle to enable the feature"/>
-    <variant name="Up" summary="Turn the slider value up"/>
-  </token>
-</histogram>
-
-<histogram name="Ash.UnifiedSystemView.{DeviceMode}.FeaturePodCountOnOpen"
-    units="count" expires_after="2024-07-30">
-  <owner>jiamingc@google.com</owner>
-  <owner>cros-status-area-eng@google.com</owner>
-  <summary>
-    The number of feature pods (e.g. WiFi, Bluetooth, IME, Accessibility, etc.)
-    in the old system tray quick settings when it is opened, including pods that
-    overflow to other pages. This metric is logged by 2 different types of
-    {DeviceMode}: &quot;Clamshell&quot; and &quot;Tablet&quot;. This metric gets
-    recorded for both the new quick settings view and the old unified system
-    view, see &quot;Ash.QuickSettings.{DeviceMode}.FeaturePodCountOnOpen&quot;
-    which is the metric for the new quick settings view.
-  </summary>
-  <token key="DeviceMode">
-    <variant name="Clamshell" summary="Regular mode"/>
-    <variant name="Tablet" summary="Tablet mode"/>
-  </token>
-</histogram>
-
 <histogram base="true" name="Ash.UnlockAnimation.Smoothness" units="%"
     expires_after="2024-07-12">
   <owner>oshima@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/cookie/histograms.xml b/tools/metrics/histograms/metadata/cookie/histograms.xml
index 939e2696..5d25b105 100644
--- a/tools/metrics/histograms/metadata/cookie/histograms.xml
+++ b/tools/metrics/histograms/metadata/cookie/histograms.xml
@@ -239,7 +239,7 @@
 </histogram>
 
 <histogram name="Cookie.CrossSiteRedirectDowngradeChangesInclusionHttpMethod"
-    enum="HttpMethods" expires_after="2023-11-15">
+    enum="HttpMethods" expires_after="2024-05-15">
   <owner>bingler@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
@@ -810,7 +810,7 @@
 </histogram>
 
 <histogram name="Cookie.Port.OmniboxURLNavigation.Localhost"
-    enum="InterestingCookiePorts" expires_after="2023-11-18">
+    enum="InterestingCookiePorts" expires_after="2024-05-18">
   <owner>bingler@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
@@ -831,7 +831,7 @@
 </histogram>
 
 <histogram name="Cookie.Port.OmniboxURLNavigation.RemoteHost"
-    enum="InterestingCookiePorts" expires_after="2023-11-18">
+    enum="InterestingCookiePorts" expires_after="2024-05-18">
   <owner>bingler@chromium.org</owner>
   <owner>miketaylr@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/file/histograms.xml b/tools/metrics/histograms/metadata/file/histograms.xml
index e0d3735..94f54016 100644
--- a/tools/metrics/histograms/metadata/file/histograms.xml
+++ b/tools/metrics/histograms/metadata/file/histograms.xml
@@ -534,13 +534,13 @@
   </summary>
 </histogram>
 
-<histogram name="FileBrowser.GoogleDrive.BulkPinning.EnableDocsOfflineResult"
-    enum="DriveFileError" expires_after="2024-06-01">
+<histogram name="FileBrowser.GoogleDrive.BulkPinning.EnableDocsOffline"
+    enum="DocsOfflineEnableStatus" expires_after="2024-06-01">
   <owner>simmonsjosh@google.com</owner>
   <owner>src/ui/file_manager/OWNERS</owner>
   <summary>
-    Result returned when trying to enable the Docs offline functionality when
-    pinning items.
+    Result returned when trying to enable Docs offline functionality as part of
+    enabling the File sync feature.
   </summary>
 </histogram>
 
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml
index 6bb8fb41..4a78143 100644
--- a/tools/metrics/histograms/metadata/net/histograms.xml
+++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -5259,17 +5259,6 @@
   </summary>
 </histogram>
 
-<histogram name="Net.SSLCertVerificationTime" units="ms" expires_after="M89">
-  <owner>rsleevi@chromium.org</owner>
-  <summary>Time to complete a certificate verification (success case).</summary>
-</histogram>
-
-<histogram name="Net.SSLCertVerificationTimeError" units="ms"
-    expires_after="M89">
-  <owner>rsleevi@chromium.org</owner>
-  <summary>Time to complete a certificate verification (error case).</summary>
-</histogram>
-
 <histogram name="Net.SSLClientCertSignatureAlgorithm"
     enum="SSLSignatureAlgorithm" expires_after="2024-03-17">
   <owner>davidben@chromium.org</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 47d19a3d..7d8c2ad6 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -1,24 +1,24 @@
 {
     "trace_processor_shell": {
         "linux_arm64": {
-            "hash": "648fd2d97f101c933bc660fdf97d505c113a02c4",
-            "full_remote_path": "perfetto-luci-artifacts/3ddcaa5468c5999805a2a01d439013437cdc54c3/linux-arm64/trace_processor_shell"
+            "hash": "72a0be4a863ca12f46c82a56a39244da2258601f",
+            "full_remote_path": "perfetto-luci-artifacts/v39.0/linux-arm64/trace_processor_shell"
         },
         "win": {
             "hash": "83e3c874c7a0105c8e31fb5522af917abfd081bb",
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/3167ef8f02a3756c5abb75b041ba33c902bfe1d1/trace_processor_shell.exe"
         },
         "linux_arm": {
-            "hash": "31c9eaa742510719c8b7dab703db0122d79c7cf2",
-            "full_remote_path": "perfetto-luci-artifacts/3ddcaa5468c5999805a2a01d439013437cdc54c3/linux-arm/trace_processor_shell"
+            "hash": "a1d9784ec695f726793b073ed723ac2367caecbb",
+            "full_remote_path": "perfetto-luci-artifacts/v39.0/linux-arm/trace_processor_shell"
         },
         "mac": {
             "hash": "d2f9b340d27e126852b82843c7bc2974ce2ddfcf",
             "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/3167ef8f02a3756c5abb75b041ba33c902bfe1d1/trace_processor_shell"
         },
         "mac_arm64": {
-            "hash": "2f180e7a08b419df1a8e86537bd7ea2d944d4cd6",
-            "full_remote_path": "perfetto-luci-artifacts/3ddcaa5468c5999805a2a01d439013437cdc54c3/mac-arm64/trace_processor_shell"
+            "hash": "b43a1b06ca7c181a829fff15796962108806cb1d",
+            "full_remote_path": "perfetto-luci-artifacts/v39.0/mac-arm64/trace_processor_shell"
         },
         "linux": {
             "hash": "db5cd5de0ce5c2520486fd62e5debb4c627bd67c",
diff --git a/ui/accessibility/extensions/color_contrast_companion/highcontrast.js b/ui/accessibility/extensions/color_contrast_companion/highcontrast.js
index b18e831..a1abad2 100644
--- a/ui/accessibility/extensions/color_contrast_companion/highcontrast.js
+++ b/ui/accessibility/extensions/color_contrast_companion/highcontrast.js
@@ -20,7 +20,7 @@
     '<svg xmlns="http://www.w3.org/2000/svg" version="1.1"><defs><filter x="0" y="0" width="99999" height="99999" id="hc_extension_off"><feComponentTransfer><feFuncR type="table" tableValues="0 1"/><feFuncG type="table" tableValues="0 1"/><feFuncB type="table" tableValues="0 1"/></feComponentTransfer></filter><filter x="0" y="0" width="99999" height="99999" id="hc_extension_highcontrast"><feComponentTransfer><feFuncR type="gamma" exponent="3.0"/><feFuncG type="gamma" exponent="3.0"/><feFuncB type="gamma" exponent="3.0"/></feComponentTransfer></filter><filter x="0" y="0" width="99999" height="99999" id="hc_extension_highcontrast_back"><feComponentTransfer><feFuncR type="gamma" exponent="0.33"/><feFuncG type="gamma" exponent="0.33"/><feFuncB type="gamma" exponent="0.33"/></feComponentTransfer></filter><filter x="0" y="0" width="99999" height="99999" id="hc_extension_grayscale"><feColorMatrix type="matrix" values="0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0"/><feComponentTransfer><feFuncR type="gamma" exponent="3"/><feFuncG type="gamma" exponent="3"/><feFuncB type="gamma" exponent="3"/></feComponentTransfer></filter><filter x="0" y="0" width="99999" height="99999" id="hc_extension_grayscale_back"><feComponentTransfer><feFuncR type="gamma" exponent="0.33"/><feFuncG type="gamma" exponent="0.33"/><feFuncB type="gamma" exponent="0.33"/></feComponentTransfer></filter><filter x="0" y="0" width="99999" height="99999" id="hc_extension_invert"><feComponentTransfer><feFuncR type="gamma" amplitude="-1" exponent="3" offset="1"/><feFuncG type="gamma" amplitude="-1" exponent="3" offset="1"/><feFuncB type="gamma" amplitude="-1" exponent="3" offset="1"/></feComponentTransfer></filter><filter x="0" y="0" width="99999" height="99999" id="hc_extension_invert_back"><feComponentTransfer><feFuncR type="table" tableValues="1 0"/><feFuncG type="table" tableValues="1 0"/><feFuncB type="table" tableValues="1 0"/></feComponentTransfer><feComponentTransfer><feFuncR type="gamma" exponent="1.7"/><feFuncG type="gamma" exponent="1.7"/><feFuncB type="gamma" exponent="1.7"/></feComponentTransfer></filter><filter x="0" y="0" width="99999" height="99999" id="hc_extension_invert_grayscale"><feColorMatrix type="matrix" values="0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0.2126 0.7152 0.0722 0 0 0 0 0 1 0"/><feComponentTransfer><feFuncR type="gamma" amplitude="-1" exponent="3" offset="1"/><feFuncG type="gamma" amplitude="-1" exponent="3" offset="1"/><feFuncB type="gamma" amplitude="-1" exponent="3" offset="1"/></feComponentTransfer></filter><filter x="0" y="0" width="99999" height="99999" id="hc_extension_yellow_on_black"><feComponentTransfer><feFuncR type="gamma" amplitude="-1" exponent="3" offset="1"/><feFuncG type="gamma" amplitude="-1" exponent="3" offset="1"/><feFuncB type="gamma" amplitude="-1" exponent="3" offset="1"/></feComponentTransfer><feColorMatrix type="matrix" values="0.3 0.5 0.2 0 0 0.3 0.5 0.2 0 0 0 0 0 0 0 0 0 0 1 0"/></filter><filter x="0" y="0" width="99999" height="99999" id="hc_extension_yellow_on_black_back"><feComponentTransfer><feFuncR type="table" tableValues="1 0"/><feFuncG type="table" tableValues="1 0"/><feFuncB type="table" tableValues="1 0"/></feComponentTransfer><feComponentTransfer><feFuncR type="gamma" exponent="0.33"/><feFuncG type="gamma" exponent="0.33"/><feFuncB type="gamma" exponent="0.33"/></feComponentTransfer></filter></defs></svg>';
 
 var cssTemplate =
-    'html[hc="a0"] {   -webkit-filter: url("#hc_extension_off"); } html[hcx="0"] img[src*="jpg"], html[hcx="0"] img[src*="jpeg"], html[hcx="0"] svg image, html[hcx="0"] img.rg_i, html[hcx="0"] embed, html[hcx="0"] object, html[hcx="0"] video {   -webkit-filter: url("#hc_extension_off"); }  html[hc="a1"] {   -webkit-filter: url("#hc_extension_highcontrast"); } html[hcx="1"] img[src*="jpg"], html[hcx="1"] img[src*="jpeg"], html[hcx="1"] img.rg_i, html[hcx="1"] svg image, html[hcx="1"] embed, html[hcx="1"] object, html[hcx="1"] video {   -webkit-filter: url("#hc_extension_highcontrast_back"); }  html[hc="a2"] {   -webkit-filter: url("#hc_extension_grayscale"); } html[hcx="2"] img[src*="jpg"], html[hcx="2"] img[src*="jpeg"], html[hcx="2"] img.rg_i, html[hcx="2"] svg image, html[hcx="2"] embed, html[hcx="2"] object, html[hcx="2"] video {   -webkit-filter: url("#hc_extension_grayscale_back"); }  html[hc="a3"] {   -webkit-filter: url("#hc_extension_invert"); } html[hcx="3"] img[src*="jpg"], html[hcx="3"] img[src*="jpeg"], html[hcx="3"] img.rg_i, html[hcx="3"] svg image, html[hcx="3"] embed, html[hcx="3"] object, html[hcx="3"] video {   -webkit-filter: url("#hc_extension_invert_back"); }  html[hc="a4"] {   -webkit-filter: url("#hc_extension_invert_grayscale"); } html[hcx="4"] img[src*="jpg"], html[hcx="4"] img[src*="jpeg"], html[hcx="4"] img.rg_i, html[hcx="4"] svg image, html[hcx="4"] embed, html[hcx="4"] object, html[hcx="4"] video {   -webkit-filter: url("#hc_extension_invert_back"); }  html[hc="a5"] {   -webkit-filter: url("#hc_extension_yellow_on_black"); } html[hcx="5"] img[src*="jpg"], html[hcx="5"] img[src*="jpeg"], html[hcx="5"] img.rg_i, html[hcx="5"] svg image, html[hcx="5"] embed, html[hcx="5"] object, html[hcx="5"] video {   -webkit-filter: url("#hc_extension_yellow_on_black_back"); }';
+    'html[hc="a0"] {   filter: url("#hc_extension_off"); } html[hcx="0"] img[src*="jpg"], html[hcx="0"] img[src*="jpeg"], html[hcx="0"] svg image, html[hcx="0"] img.rg_i, html[hcx="0"] embed, html[hcx="0"] object, html[hcx="0"] video {   filter: url("#hc_extension_off"); }  html[hc="a1"] {   filter: url("#hc_extension_highcontrast"); } html[hcx="1"] img[src*="jpg"], html[hcx="1"] img[src*="jpeg"], html[hcx="1"] img.rg_i, html[hcx="1"] svg image, html[hcx="1"] embed, html[hcx="1"] object, html[hcx="1"] video {   filter: url("#hc_extension_highcontrast_back"); }  html[hc="a2"] {   filter: url("#hc_extension_grayscale"); } html[hcx="2"] img[src*="jpg"], html[hcx="2"] img[src*="jpeg"], html[hcx="2"] img.rg_i, html[hcx="2"] svg image, html[hcx="2"] embed, html[hcx="2"] object, html[hcx="2"] video {   filter: url("#hc_extension_grayscale_back"); }  html[hc="a3"] {   filter: url("#hc_extension_invert"); } html[hcx="3"] img[src*="jpg"], html[hcx="3"] img[src*="jpeg"], html[hcx="3"] img.rg_i, html[hcx="3"] svg image, html[hcx="3"] embed, html[hcx="3"] object, html[hcx="3"] video {   filter: url("#hc_extension_invert_back"); }  html[hc="a4"] {   filter: url("#hc_extension_invert_grayscale"); } html[hcx="4"] img[src*="jpg"], html[hcx="4"] img[src*="jpeg"], html[hcx="4"] img.rg_i, html[hcx="4"] svg image, html[hcx="4"] embed, html[hcx="4"] object, html[hcx="4"] video {   filter: url("#hc_extension_invert_back"); }  html[hc="a5"] {   filter: url("#hc_extension_yellow_on_black"); } html[hcx="5"] img[src*="jpg"], html[hcx="5"] img[src*="jpeg"], html[hcx="5"] img.rg_i, html[hcx="5"] svg image, html[hcx="5"] embed, html[hcx="5"] object, html[hcx="5"] video {   filter: url("#hc_extension_yellow_on_black_back"); }';
 
 /**
  * Add the elements to the pgae that make high-contrast adjustments possible.
diff --git a/ui/accessibility/extensions/colorenhancer/src/cvd.js b/ui/accessibility/extensions/colorenhancer/src/cvd.js
index be55e36..3637513 100644
--- a/ui/accessibility/extensions/colorenhancer/src/cvd.js
+++ b/ui/accessibility/extensions/colorenhancer/src/cvd.js
@@ -28,10 +28,10 @@
    */
   static cssContent_ = `
 html[cvd="0"] {
-  -webkit-filter: url('#cvd_extension_0');
+  filter: url('#cvd_extension_0');
 }
 html[cvd="1"] {
-  -webkit-filter: url('#cvd_extension_1');
+  filter: url('#cvd_extension_1');
 }
 `;
 
diff --git a/ui/accessibility/extensions/highcontrast/highcontrast.js b/ui/accessibility/extensions/highcontrast/highcontrast.js
index c87785d..0dc08a9b 100644
--- a/ui/accessibility/extensions/highcontrast/highcontrast.js
+++ b/ui/accessibility/extensions/highcontrast/highcontrast.js
@@ -301,7 +301,7 @@
   /** @const {string} */
   static cssTemplate = `
       html[hc="a0"] {
-        -webkit-filter: url("#hc_extension_off");
+        filter: url("#hc_extension_off");
       }
 
       html[hcx="0"] img[src*="jpg"],
@@ -311,11 +311,11 @@
       html[hcx="0"] embed,
       html[hcx="0"] object,
       html[hcx="0"] video {
-        -webkit-filter: url("#hc_extension_off");
+        filter: url("#hc_extension_off");
       }
 
       html[hc="a1"] {
-        -webkit-filter: url("#hc_extension_highcontrast");
+        filter: url("#hc_extension_highcontrast");
       }
 
       html[hcx="1"] img[src*="jpg"],
@@ -325,11 +325,11 @@
       html[hcx="1"] embed,
       html[hcx="1"] object,
       html[hcx="1"] video {
-        -webkit-filter: url("#hc_extension_highcontrast_back");
+        filter: url("#hc_extension_highcontrast_back");
       }
 
       html[hc="a2"] {
-        -webkit-filter: url("#hc_extension_grayscale");
+        filter: url("#hc_extension_grayscale");
       }
 
       html[hcx="2"] img[src*="jpg"],
@@ -339,11 +339,11 @@
       html[hcx="2"] embed,
       html[hcx="2"] object,
       html[hcx="2"] video {
-        -webkit-filter: url("#hc_extension_grayscale_back");
+        filter: url("#hc_extension_grayscale_back");
       }
 
       html[hc="a3"] {
-        -webkit-filter: url("#hc_extension_invert");
+        filter: url("#hc_extension_invert");
       }
 
       html[hcx="3"] img[src*="jpg"],
@@ -353,11 +353,11 @@
       html[hcx="3"] embed,
       html[hcx="3"] object,
       html[hcx="3"] video {
-        -webkit-filter: url("#hc_extension_invert_back");
+        filter: url("#hc_extension_invert_back");
       }
 
       html[hc="a4"] {
-        -webkit-filter: url("#hc_extension_invert_grayscale");
+        filter: url("#hc_extension_invert_grayscale");
       }
 
       html[hcx="4"] img[src*="jpg"],
@@ -367,11 +367,11 @@
       html[hcx="4"] embed,
       html[hcx="4"] object,
       html[hcx="4"] video {
-        -webkit-filter: url("#hc_extension_invert_back");
+        filter: url("#hc_extension_invert_back");
       }
 
       html[hc="a5"] {
-        -webkit-filter: url("#hc_extension_yellow_on_black");
+        filter: url("#hc_extension_yellow_on_black");
       }
 
       html[hcx="5"] img[src*="jpg"],
@@ -381,7 +381,7 @@
       html[hcx="5"] embed,
       html[hcx="5"] object,
       html[hcx="5"] video {
-        -webkit-filter: url("#hc_extension_yellow_on_black_back");
+        filter: url("#hc_extension_yellow_on_black_back");
       }`;
 }
 
diff --git a/ui/accessibility/platform/automation/automation_ax_tree_wrapper.cc b/ui/accessibility/platform/automation/automation_ax_tree_wrapper.cc
index decd597a..31845b6 100644
--- a/ui/accessibility/platform/automation/automation_ax_tree_wrapper.cc
+++ b/ui/accessibility/platform/automation/automation_ax_tree_wrapper.cc
@@ -63,8 +63,7 @@
     const AXTreeID& tree_id,
     const std::vector<AXTreeUpdate>& updates,
     const std::vector<AXEvent>& events,
-    gfx::Point mouse_location,
-    bool is_active_profile) {
+    gfx::Point mouse_location) {
   TRACE_EVENT0("accessibility",
                "AutomationAXTreeWrapper::OnAccessibilityEvents");
 
@@ -96,14 +95,12 @@
       return false;
     }
 
-    if (is_active_profile) {
       owner_->SendNodesRemovedEvent(ax_tree(), deleted_node_ids_);
 
       if (update.nodes.size() && did_send_tree_change_during_unserialization_) {
         owner_->SendTreeChangeEvent(ax::mojom::Mutation::kSubtreeUpdateEnd,
                                     ax_tree(), ax_tree_->root());
       }
-    }
   }
 
   // Refresh child tree id  mappings.
@@ -112,12 +109,6 @@
     child_tree_id_reverse_map.insert(std::make_pair(child_tree_id, this));
   }
 
-  // Exit early if this isn't the active profile.
-  if (!is_active_profile) {
-    event_generator_.ClearEvents();
-    return true;
-  }
-
   // Perform language detection first thing if we see a load complete event.
   // We have to run *before* we send the load complete event to javascript
   // otherwise code which runs immediately on load complete will not be able
diff --git a/ui/accessibility/platform/automation/automation_ax_tree_wrapper.h b/ui/accessibility/platform/automation/automation_ax_tree_wrapper.h
index ccaad65..cf30f11f 100644
--- a/ui/accessibility/platform/automation/automation_ax_tree_wrapper.h
+++ b/ui/accessibility/platform/automation/automation_ax_tree_wrapper.h
@@ -50,15 +50,14 @@
 
   AutomationTreeManagerOwner* owner() { return owner_; }
 
-  // Called by AutomationInternalCustomBindings::OnAccessibilityEvents on
+  // Called by AutomationInternalCustomBindings::DispatchAccessibilityEvents on
   // the AutomationAXTreeWrapper instance for the correct tree corresponding
   // to this event. Unserializes the tree update and calls back to
   // AutomationTreeManagerOwner to fire any automation events needed.
   bool OnAccessibilityEvents(const AXTreeID& tree_id,
                              const std::vector<AXTreeUpdate>& updates,
                              const std::vector<AXEvent>& events,
-                             gfx::Point mouse_location,
-                             bool is_active_profile);
+                             gfx::Point mouse_location);
 
   // Returns true if this is the desktop tree.
   bool IsDesktopTree() const;
diff --git a/ui/accessibility/platform/automation/automation_tree_manager_owner.cc b/ui/accessibility/platform/automation/automation_tree_manager_owner.cc
index 1f513bf..7d671a36 100644
--- a/ui/accessibility/platform/automation/automation_tree_manager_owner.cc
+++ b/ui/accessibility/platform/automation/automation_tree_manager_owner.cc
@@ -37,10 +37,6 @@
     ax::mojom::Mutation change_type,
     AXTree* tree,
     AXNode* node) {
-  // Don't send tree change events when it's not the active profile.
-  if (!is_active_profile_)
-    return false;
-
   // Notify custom bindings when there's an unloaded tree; js will enable the
   // renderer and wait for it to load.
   std::string child_tree_id_str;
@@ -1009,72 +1005,6 @@
   accessibility_focused_tree_id_ = tree_id;
 }
 
-void AutomationTreeManagerOwner::OnAccessibilityEvents(
-    const AXTreeID& tree_id,
-    const std::vector<AXEvent>& events,
-    const std::vector<AXTreeUpdate>& updates,
-    const gfx::Point& mouse_location,
-    bool is_active_profile) {
-  // TODO(crbug.com/1441696): Refactor
-  // AutomationTreeManagerOwner::OnAccessibilityEvents logic into
-  // AutomationTreeManagerOwner::DispatchAccessibilityEvents.
-  is_active_profile_ = is_active_profile;
-  AutomationAXTreeWrapper* tree_wrapper =
-      GetAutomationAXTreeWrapperFromTreeID(tree_id);
-  bool is_new_tree = tree_wrapper == nullptr;
-  if (is_new_tree) {
-    tree_wrapper = new AutomationAXTreeWrapper(this);
-    CacheAutomationTreeWrapperForTreeID(tree_id, tree_wrapper);
-  }
-
-  if (!tree_wrapper->OnAccessibilityEvents(tree_id, updates, events,
-                                           mouse_location, is_active_profile)) {
-    DLOG(ERROR) << tree_wrapper->ax_tree()->error();
-    GetAutomationV8Bindings()->SendTreeSerializationError(tree_id);
-    return;
-  }
-
-  // Send an initial event to ensure the js-side objects get created for new
-  // trees.
-  if (is_new_tree) {
-    AXEvent initial_event;
-    initial_event.id = -1;
-    initial_event.event_from = ax::mojom::EventFrom::kNone;
-    initial_event.event_type = ax::mojom::Event::kNone;
-    SendAutomationEvent(tree_id, gfx::Point(), initial_event);
-  }
-
-  // After handling events in js, if the client did not add any event listeners,
-  // shut things down.
-  TreeEventListenersChanged(tree_wrapper);
-}
-
-void AutomationTreeManagerOwner::OnAccessibilityLocationChange(
-    const AXTreeID& tree_id,
-    int node_id,
-    AXRelativeBounds new_location) {
-  AutomationAXTreeWrapper* tree_wrapper =
-      GetAutomationAXTreeWrapperFromTreeID(tree_id);
-  if (!tree_wrapper)
-    return;
-  AXNode* node =
-      tree_wrapper->GetNodeFromTree(tree_wrapper->GetTreeID(), node_id);
-  if (!node)
-    return;
-
-  absl::optional<gfx::Rect> previous_accessibility_focused_global_bounds =
-      GetAccessibilityFocusedLocation();
-
-  node->SetLocation(new_location.offset_container_id, new_location.bounds,
-                    new_location.transform.get());
-
-  if (previous_accessibility_focused_global_bounds.has_value() &&
-      previous_accessibility_focused_global_bounds !=
-          GetAccessibilityFocusedLocation()) {
-    SendAccessibilityFocusedLocationChange(gfx::Point());
-  }
-}
-
 void AutomationTreeManagerOwner::CacheAutomationTreeWrapperForTreeID(
     const AXTreeID& tree_id,
     AutomationAXTreeWrapper* tree_wrapper) {
@@ -1154,15 +1084,62 @@
     const std::vector<ui::AXTreeUpdate>& updates,
     const gfx::Point& mouse_location,
     const std::vector<ui::AXEvent>& events) {
-  OnAccessibilityEvents(tree_id, events, updates, mouse_location,
-                        is_active_profile_);
+  AutomationAXTreeWrapper* tree_wrapper =
+      GetAutomationAXTreeWrapperFromTreeID(tree_id);
+  bool is_new_tree = tree_wrapper == nullptr;
+  if (is_new_tree) {
+    tree_wrapper = new AutomationAXTreeWrapper(this);
+    CacheAutomationTreeWrapperForTreeID(tree_id, tree_wrapper);
+  }
+
+  if (!tree_wrapper->OnAccessibilityEvents(tree_id, updates, events,
+                                           mouse_location)) {
+    DLOG(ERROR) << tree_wrapper->ax_tree()->error();
+    GetAutomationV8Bindings()->SendTreeSerializationError(tree_id);
+    return;
+  }
+
+  // Send an initial event to ensure the js-side objects get created for new
+  // trees.
+  if (is_new_tree) {
+    AXEvent initial_event;
+    initial_event.id = -1;
+    initial_event.event_from = ax::mojom::EventFrom::kNone;
+    initial_event.event_type = ax::mojom::Event::kNone;
+    SendAutomationEvent(tree_id, gfx::Point(), initial_event);
+  }
+
+  // After handling events in js, if the client did not add any event listeners,
+  // shut things down.
+  TreeEventListenersChanged(tree_wrapper);
 }
 
 void AutomationTreeManagerOwner::DispatchAccessibilityLocationChange(
     const ui::AXTreeID& tree_id,
     int32_t node_id,
     const ui::AXRelativeBounds& bounds) {
-  OnAccessibilityLocationChange(tree_id, node_id, bounds);
+  AutomationAXTreeWrapper* tree_wrapper =
+      GetAutomationAXTreeWrapperFromTreeID(tree_id);
+  if (!tree_wrapper) {
+    return;
+  }
+  AXNode* node =
+      tree_wrapper->GetNodeFromTree(tree_wrapper->GetTreeID(), node_id);
+  if (!node) {
+    return;
+  }
+
+  absl::optional<gfx::Rect> previous_accessibility_focused_global_bounds =
+      GetAccessibilityFocusedLocation();
+
+  node->SetLocation(bounds.offset_container_id, bounds.bounds,
+                    bounds.transform.get());
+
+  if (previous_accessibility_focused_global_bounds.has_value() &&
+      previous_accessibility_focused_global_bounds !=
+          GetAccessibilityFocusedLocation()) {
+    SendAccessibilityFocusedLocationChange(gfx::Point());
+  }
 }
 
 void AutomationTreeManagerOwner::DispatchActionResult(
diff --git a/ui/accessibility/platform/automation/automation_tree_manager_owner.h b/ui/accessibility/platform/automation/automation_tree_manager_owner.h
index 6ff2803..ca41dea 100644
--- a/ui/accessibility/platform/automation/automation_tree_manager_owner.h
+++ b/ui/accessibility/platform/automation/automation_tree_manager_owner.h
@@ -173,16 +173,6 @@
  protected:
   friend class AutomationTreeManagerOwnerTest;
 
-  void OnAccessibilityEvents(const ui::AXTreeID& tree_id,
-                             const std::vector<AXEvent>& events,
-                             const std::vector<AXTreeUpdate>& updates,
-                             const gfx::Point& mouse_location,
-                             bool is_active_profile);
-
-  void OnAccessibilityLocationChange(const ui::AXTreeID& tree_id,
-                                     int node_id,
-                                     AXRelativeBounds new_location);
-
   // Invalidates this AutomationTreeManagerOnwer.
   void Invalidate();
 
@@ -267,8 +257,6 @@
 
   // The global focused node id.
   int32_t focus_id_ = -1;
-
-  bool is_active_profile_ = true;
 };
 
 }  // namespace ui
diff --git a/ui/accessibility/platform/automation/automation_tree_manager_owner_unittest.cc b/ui/accessibility/platform/automation/automation_tree_manager_owner_unittest.cc
index 2b6e84e..debfb2f 100644
--- a/ui/accessibility/platform/automation/automation_tree_manager_owner_unittest.cc
+++ b/ui/accessibility/platform/automation/automation_tree_manager_owner_unittest.cc
@@ -239,12 +239,12 @@
     return tree_manager_owner_->tree_id_to_tree_wrapper_map_;
   }
 
-  void SendOnAccessibilityEvents(const ui::AXTreeID& tree_id,
-                                 const std::vector<ui::AXTreeUpdate>& updates,
-                                 const gfx::Point& mouse_location,
-                                 const std::vector<ui::AXEvent>& events) {
-    tree_manager_owner_->OnAccessibilityEvents(tree_id, events, updates,
-                                               mouse_location, true);
+  void SendAccessibilityEvents(const ui::AXTreeID& tree_id,
+                               const std::vector<ui::AXTreeUpdate>& updates,
+                               const gfx::Point& mouse_location,
+                               const std::vector<ui::AXEvent>& events) {
+    tree_manager_owner_->DispatchAccessibilityEvents(tree_id, updates,
+                                                     mouse_location, events);
   }
 
   void SendOnTreeDestroyedEvent(const ui::AXTreeID& tree_id) {
@@ -314,7 +314,7 @@
   node_data.role = ax::mojom::Role::kDesktop;
   node_data.id = 1;
   std::vector<ui::AXEvent> events;
-  SendOnAccessibilityEvents(tree_data.tree_id, updates, gfx::Point(), events);
+  SendAccessibilityEvents(tree_data.tree_id, updates, gfx::Point(), events);
 
   ASSERT_EQ(1U, GetTreeIDToTreeMap().size());
 
@@ -344,7 +344,7 @@
   node_data2.id = 2;
   node_data2.role = ax::mojom::Role::kButton;
   std::vector<ui::AXEvent> events;
-  SendOnAccessibilityEvents(tree_data.tree_id, updates, gfx::Point(), events);
+  SendAccessibilityEvents(tree_data.tree_id, updates, gfx::Point(), events);
 
   ASSERT_EQ(1U, GetTreeIDToTreeMap().size());
 
@@ -364,7 +364,7 @@
   focused_wrapper = nullptr;
   focused_node = nullptr;
   tree_data.focus_id = 1;
-  SendOnAccessibilityEvents(tree_data.tree_id, updates, gfx::Point(), events);
+  SendAccessibilityEvents(tree_data.tree_id, updates, gfx::Point(), events);
   CallGetFocusInternal(desktop, &focused_wrapper, &focused_node);
   ASSERT_TRUE(focused_wrapper);
   ASSERT_TRUE(focused_node);
@@ -375,7 +375,7 @@
   focused_wrapper = nullptr;
   focused_node = nullptr;
   tree_data.focus_id = 100;
-  SendOnAccessibilityEvents(tree_data.tree_id, updates, gfx::Point(), events);
+  SendAccessibilityEvents(tree_data.tree_id, updates, gfx::Point(), events);
   CallGetFocusInternal(desktop, &focused_wrapper, &focused_node);
   ASSERT_FALSE(focused_wrapper);
   ASSERT_FALSE(focused_node);
@@ -423,8 +423,8 @@
 
   std::vector<ui::AXEvent> empty_events;
   for (auto& updates : updates_list) {
-    SendOnAccessibilityEvents(updates[0].tree_data.tree_id, updates,
-                              gfx::Point(), empty_events);
+    SendAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
+                            empty_events);
   }
 
   ASSERT_EQ(3U, GetTreeIDToTreeMap().size());
@@ -454,8 +454,8 @@
 
   // The link in wrapper 0 which has a child tree id pointing to wrapper 2.
   updates_list[0][0].tree_data.focus_id = 3;
-  SendOnAccessibilityEvents(updates_list[0][0].tree_data.tree_id,
-                            updates_list[0], gfx::Point(), empty_events);
+  SendAccessibilityEvents(updates_list[0][0].tree_data.tree_id, updates_list[0],
+                          gfx::Point(), empty_events);
   CallGetFocusInternal(wrapper_0, &focused_wrapper, &focused_node);
   ASSERT_TRUE(focused_wrapper);
   ASSERT_TRUE(focused_node);
@@ -518,8 +518,8 @@
 
   std::vector<ui::AXEvent> empty_events;
   for (auto& updates : updates_list) {
-    SendOnAccessibilityEvents(updates[0].tree_data.tree_id, updates,
-                              gfx::Point(), empty_events);
+    SendAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
+                            empty_events);
   }
 
   ASSERT_EQ(3U, GetTreeIDToTreeMap().size());
@@ -552,8 +552,8 @@
 
   // The link in wrapper 0 which has a child tree id pointing to wrapper 2.
   updates_list[0][0].tree_data.focus_id = 3;
-  SendOnAccessibilityEvents(updates_list[0][0].tree_data.tree_id,
-                            updates_list[0], gfx::Point(), empty_events);
+  SendAccessibilityEvents(updates_list[0][0].tree_data.tree_id, updates_list[0],
+                          gfx::Point(), empty_events);
   CallGetFocusInternal(wrapper_0, &focused_wrapper, &focused_node);
   ASSERT_TRUE(focused_wrapper);
   ASSERT_TRUE(focused_node);
@@ -605,8 +605,8 @@
 
   std::vector<ui::AXEvent> empty_events;
   for (auto& updates : updates_list) {
-    SendOnAccessibilityEvents(updates[0].tree_data.tree_id, updates,
-                              gfx::Point(), empty_events);
+    SendAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
+                            empty_events);
   }
 
   ASSERT_EQ(2U, GetTreeIDToTreeMap().size());
@@ -686,8 +686,8 @@
 
   std::vector<ui::AXEvent> empty_events;
   for (auto& updates : updates_list) {
-    SendOnAccessibilityEvents(updates[0].tree_data.tree_id, updates,
-                              gfx::Point(), empty_events);
+    SendAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
+                            empty_events);
   }
 
   ASSERT_EQ(2U, GetTreeIDToTreeMap().size());
@@ -762,8 +762,8 @@
 
   std::vector<ui::AXEvent> empty_events;
   for (auto& updates : updates_list) {
-    SendOnAccessibilityEvents(updates[0].tree_data.tree_id, updates,
-                              gfx::Point(), empty_events);
+    SendAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
+                            empty_events);
   }
 
   ASSERT_EQ(3U, GetTreeIDToTreeMap().size());
@@ -847,8 +847,8 @@
 
   std::vector<ui::AXEvent> empty_events;
   for (auto& updates : updates_list) {
-    SendOnAccessibilityEvents(updates[0].tree_data.tree_id, updates,
-                              gfx::Point(), empty_events);
+    SendAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
+                            empty_events);
   }
 
   ASSERT_EQ(2U, GetTreeIDToTreeMap().size());
@@ -898,8 +898,8 @@
       [&](const std::string& event) { events.push_back(event); }));
 
   std::vector<ui::AXEvent> ax_events;
-  SendOnAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
-                            ax_events);
+  SendAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
+                          ax_events);
 
   // We aren't listening for any events yet, but we should still get one that
   // gets fired on initial tree creation.
@@ -913,8 +913,8 @@
 
   // Trigger a role change.
   tree_update.nodes[0].role = ax::mojom::Role::kSwitch;
-  SendOnAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
-                            ax_events);
+  SendAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
+                          ax_events);
 
   // There should be no events since there are no listeners and this isn't the
   // initial tree.
@@ -930,8 +930,8 @@
   EXPECT_EQ(1U, wrapper->EventListenerCount());
   EXPECT_TRUE(wrapper->HasEventListener(event_type, tree->GetFromId(2)));
   tree_update.nodes[0].role = ax::mojom::Role::kButton;
-  SendOnAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
-                            ax_events);
+  SendAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
+                          ax_events);
 
   // We should now have exactly one event.
   ASSERT_EQ(1U, events.size());
@@ -947,8 +947,8 @@
           ax::mojom::Event::kLoadComplete, ui::AXEventGenerator::Event::NONE),
       tree->GetFromId(1));
   tree_update.nodes[0].role = ax::mojom::Role::kSwitch;
-  SendOnAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
-                            ax_events);
+  SendAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
+                          ax_events);
 
   // We should have no events.
   ASSERT_TRUE(events.empty());
@@ -963,8 +963,8 @@
   auto& event = ax_events.back();
   event.event_type = ax::mojom::Event::kClicked;
   event.id = 2;
-  SendOnAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
-                            ax_events);
+  SendAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
+                          ax_events);
 
   // No event.
   ASSERT_TRUE(events.empty());
@@ -975,8 +975,8 @@
       std::tuple<ax::mojom::Event, ui::AXEventGenerator::Event>(
           ax::mojom::Event::kClicked, ui::AXEventGenerator::Event::NONE),
       tree->GetFromId(1));
-  SendOnAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
-                            ax_events);
+  SendAccessibilityEvents(updates[0].tree_data.tree_id, updates, gfx::Point(),
+                          ax_events);
 
   ASSERT_EQ(1U, events.size());
   EXPECT_EQ("clicked none", events[0]);
diff --git a/ui/base/clipboard/clipboard_test_template.h b/ui/base/clipboard/clipboard_test_template.h
index 68bbf10..6c145b2 100644
--- a/ui/base/clipboard/clipboard_test_template.h
+++ b/ui/base/clipboard/clipboard_test_template.h
@@ -114,14 +114,14 @@
                     base::optional_ref<const DataTransferEndpoint> data_dst,
                     const absl::optional<size_t> size));
   MOCK_METHOD5(PasteIfAllowed,
-               void(const DataTransferEndpoint* const data_src,
-                    const DataTransferEndpoint* const data_dst,
+               void(base::optional_ref<const DataTransferEndpoint> data_src,
+                    base::optional_ref<const DataTransferEndpoint> data_dst,
                     const absl::optional<size_t> size,
                     content::RenderFrameHost* rfh,
                     base::OnceCallback<void(bool)> callback));
   MOCK_METHOD3(DropIfAllowed,
                void(const ui::OSExchangeData* drag_data,
-                    const ui::DataTransferEndpoint* data_dst,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::OnceClosure drop_cb));
 };
 
diff --git a/ui/base/data_transfer_policy/data_transfer_policy_controller.h b/ui/base/data_transfer_policy/data_transfer_policy_controller.h
index 3608e59..05e9a6b 100644
--- a/ui/base/data_transfer_policy/data_transfer_policy_controller.h
+++ b/ui/base/data_transfer_policy/data_transfer_policy_controller.h
@@ -52,20 +52,22 @@
   // true. Otherwise `callback` will be invoked with false.
   // If the WebContents of `rfh` got destroyed before `callback` is invoked, the
   // notification will get closed.
-  virtual void PasteIfAllowed(const DataTransferEndpoint* data_src,
-                              const DataTransferEndpoint* data_dst,
-                              absl::optional<size_t> size,
-                              content::RenderFrameHost* rfh,
-                              base::OnceCallback<void(bool)> callback) = 0;
+  virtual void PasteIfAllowed(
+      base::optional_ref<const DataTransferEndpoint> data_src,
+      base::optional_ref<const DataTransferEndpoint> data_dst,
+      absl::optional<size_t> size,
+      content::RenderFrameHost* rfh,
+      base::OnceCallback<void(bool)> callback) = 0;
 
   // `drag_data` can't be nullptr. nullptr can be passed instead of `data_dst`.
   // If dropping the data is not allowed, this function will show a notification
   // to the user. If the drop is allowed, `drop_cb` will be run. Otherwise
   // `drop_cb` will be reset. `drop_cb` may be run asynchronously after the user
   // comfirms they want to drop the data.
-  virtual void DropIfAllowed(const ui::OSExchangeData* drag_data,
-                             const DataTransferEndpoint* data_dst,
-                             base::OnceClosure drop_cb) = 0;
+  virtual void DropIfAllowed(
+      const ui::OSExchangeData* drag_data,
+      base::optional_ref<const DataTransferEndpoint> data_dst,
+      base::OnceClosure drop_cb) = 0;
 
  protected:
   DataTransferPolicyController();
diff --git a/ui/base/data_transfer_policy/mock_data_transfer_policy_controller.h b/ui/base/data_transfer_policy/mock_data_transfer_policy_controller.h
index e85486f..a832cf2 100644
--- a/ui/base/data_transfer_policy/mock_data_transfer_policy_controller.h
+++ b/ui/base/data_transfer_policy/mock_data_transfer_policy_controller.h
@@ -29,8 +29,8 @@
               (override));
   MOCK_METHOD(void,
               PasteIfAllowed,
-              (const ui::DataTransferEndpoint* const data_src,
-               const ui::DataTransferEndpoint* const data_dst,
+              (base::optional_ref<const ui::DataTransferEndpoint> data_src,
+               base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                const absl::optional<size_t> size,
                content::RenderFrameHost* rfh,
                base::OnceCallback<void(bool)> callback),
@@ -38,7 +38,7 @@
   MOCK_METHOD(void,
               DropIfAllowed,
               (const ui::OSExchangeData* drag_data,
-               const ui::DataTransferEndpoint* data_dst,
+               base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                base::OnceClosure drop_cb),
               (override));
 };
diff --git a/ui/base/device_form_factor_android.cc b/ui/base/device_form_factor_android.cc
index 8c6492f..38ba94d 100644
--- a/ui/base/device_form_factor_android.cc
+++ b/ui/base/device_form_factor_android.cc
@@ -10,6 +10,11 @@
 
 namespace ui {
 
+// TODO(crbug.com/1501069): Need to land a long-term solution to return
+// foldable, either by exposing ui_mode or returning foldable here after
+// auditing usages. Currently we are temporarily returning the foldable form
+// factor in VariationsServiceClient::GetCurrentFormFactor() and
+// FormFactorMetricsProvider::GetFormFactor() for UMA.
 DeviceFormFactor GetDeviceFormFactor() {
   if (base::android::BuildInfo::GetInstance()->is_tv()) {
     return DEVICE_FORM_FACTOR_TV;
diff --git a/ui/display/manager/BUILD.gn b/ui/display/manager/BUILD.gn
index 1dd366d9..8b47604b 100644
--- a/ui/display/manager/BUILD.gn
+++ b/ui/display/manager/BUILD.gn
@@ -56,7 +56,6 @@
       "display_layout_store.h",
       "display_manager.cc",
       "display_manager.h",
-      "display_manager_observer.cc",
       "display_manager_observer.h",
       "display_port_observer.cc",
       "display_port_observer.h",
diff --git a/ui/display/manager/display_manager.cc b/ui/display/manager/display_manager.cc
index 6bee063..edebbd03 100644
--- a/ui/display/manager/display_manager.cc
+++ b/ui/display/manager/display_manager.cc
@@ -344,53 +344,16 @@
     DisplayManager* display_manager)
     : display_manager_(display_manager) {
   if (display_manager_->notify_depth_++ == 0) {
-    CHECK(!display_manager_->pending_display_changes_.has_value());
-    display_manager_->pending_display_changes_.emplace();
     display_manager_->NotifyWillProcessDisplayChanges();
   }
 }
 
 DisplayManager::BeginEndNotifier::~BeginEndNotifier() {
   if (--display_manager_->notify_depth_ == 0) {
-    CHECK(display_manager_->pending_display_changes_.has_value());
-    DisplayManagerObserver::DisplayConfigurationChange config_change =
-        CreateConfigChange();
-    display_manager_->pending_display_changes_.reset();
-    display_manager_->NotifyDidProcessDisplayChanges(config_change);
+    display_manager_->NotifyDidProcessDisplayChanges();
   }
 }
 
-DisplayManagerObserver::DisplayConfigurationChange
-DisplayManager::BeginEndNotifier::CreateConfigChange() const {
-  CHECK(display_manager_->pending_display_changes_.has_value());
-  PendingDisplayChanges& pending_changes =
-      display_manager_->pending_display_changes_.value();
-
-  Displays added_displays;
-  for (int64_t display_id : pending_changes.added_display_ids) {
-    CHECK(display_manager_->IsDisplayIdValid(display_id));
-    added_displays.emplace_back(display_manager_->GetDisplayForId(display_id));
-  }
-
-  std::vector<DisplayManagerObserver::DisplayMetricsChange>
-      display_metrics_changes;
-  for (const auto& pair : pending_changes.display_metrics_changes) {
-    if (display_manager_->IsDisplayIdValid(pair.first)) {
-      display_metrics_changes.emplace_back(
-          DisplayManagerObserver::DisplayMetricsChange(
-              display_manager_->GetDisplayForId(pair.first), pair.second));
-    }
-  }
-
-  return {std::move(added_displays),
-          std::move(pending_changes.removed_displays),
-          std::move(display_metrics_changes)};
-}
-
-DisplayManager::PendingDisplayChanges::PendingDisplayChanges() = default;
-
-DisplayManager::PendingDisplayChanges::~PendingDisplayChanges() = default;
-
 DisplayManager::DisplayManager(std::unique_ptr<Screen> screen)
     : screen_(std::move(screen)), layout_store_(new DisplayLayoutStore) {
   SetConfigureDisplays(base::SysInfo::IsRunningOnChromeOS());
@@ -504,8 +467,6 @@
   if (GetNumDisplays() == 1) {
     return;
   }
-  // TODO(tluk): Move instantiating this to after checking whether the current
-  // layout has the same placement list.
   BeginEndNotifier notifier(this);
 
   const DisplayIdList list = GetConnectedDisplayIdList();
@@ -533,10 +494,6 @@
     NotifyMetricsChanged(GetDisplayForId(id),
                          DisplayObserver::DISPLAY_METRIC_BOUNDS |
                              DisplayObserver::DISPLAY_METRIC_WORK_AREA);
-    CHECK(pending_display_changes_.has_value());
-    pending_display_changes_->display_metrics_changes[id] |=
-        DisplayObserver::DISPLAY_METRIC_BOUNDS |
-        DisplayObserver::DISPLAY_METRIC_WORK_AREA;
   }
 
   if (delegate_) {
@@ -579,10 +536,6 @@
   bool workarea_changed = old_work_area != display->work_area();
   if (workarea_changed) {
     NotifyMetricsChanged(*display, DisplayObserver::DISPLAY_METRIC_WORK_AREA);
-
-    CHECK(pending_display_changes_.has_value());
-    pending_display_changes_->display_metrics_changes[display_id] |=
-        DisplayObserver::DISPLAY_METRIC_WORK_AREA;
   }
   return workarea_changed;
 }
@@ -872,6 +825,7 @@
       //   disconnected.
       // The display will be updated when one of displays is turned on, and the
       // display list will be updated correctly.
+
       BeginEndNotifier notifier(this);
       for (auto& display : active_display_list_) {
         if (display.detected()) {
@@ -881,9 +835,6 @@
           InsertAndUpdateDisplayInfo(info);
           NotifyMetricsChanged(display,
                                DisplayObserver::DISPLAY_METRIC_DETECTED);
-          CHECK(pending_display_changes_.has_value());
-          pending_display_changes_->display_metrics_changes[display.id()] |=
-              DisplayObserver::DISPLAY_METRIC_DETECTED;
         }
       }
     }
@@ -1244,22 +1195,25 @@
   }
 
   UpdatePrimaryDisplayIdIfNecessary();
-  const Display& primary = screen_->GetPrimaryDisplay();
-  bool notify_primary_change = delegate_ && old_primary.id() != primary.id();
 
-  for (auto& change : display_changes) {
-    Display& updated_display = active_display_list_[change.first];
-    uint32_t& updated_display_metrics = change.second;
+  bool notify_primary_change =
+      delegate_ ? old_primary.id() != screen_->GetPrimaryDisplay().id() : false;
 
-    if (notify_primary_change && updated_display.id() == primary.id()) {
-      updated_display_metrics |= DisplayObserver::DISPLAY_METRIC_PRIMARY;
+  for (auto iter = display_changes.begin(); iter != display_changes.end();
+       ++iter) {
+    uint32_t metrics = iter->second;
+    Display& updated_display = active_display_list_[iter->first];
+
+    if (notify_primary_change &&
+        updated_display.id() == screen_->GetPrimaryDisplay().id()) {
+      metrics |= DisplayObserver::DISPLAY_METRIC_PRIMARY;
       notify_primary_change = false;
     }
     if (!updated_display.detected()) {
       updated_display.set_detected(true);
-      updated_display_metrics |= DisplayObserver::DISPLAY_METRIC_DETECTED;
+      metrics |= DisplayObserver::DISPLAY_METRIC_DETECTED;
     }
-    NotifyMetricsChanged(updated_display, updated_display_metrics);
+    NotifyMetricsChanged(updated_display, metrics);
   }
 
   uint32_t primary_metrics = 0;
@@ -1267,6 +1221,7 @@
   if (notify_primary_change) {
     // This happens when a primary display has moved to anther display without
     // bounds change.
+    const Display& primary = screen_->GetPrimaryDisplay();
     if (primary.id() != old_primary.id()) {
       primary_metrics = DisplayObserver::DISPLAY_METRIC_PRIMARY;
       if (primary.size() != old_primary.size()) {
@@ -1287,13 +1242,6 @@
 
   if (delegate_ && primary_metrics) {
     NotifyMetricsChanged(screen_->GetPrimaryDisplay(), primary_metrics);
-
-    const auto primary_index_it = std::find(
-        active_display_list_.begin(), active_display_list_.end(), primary);
-    CHECK(primary_index_it != active_display_list_.end());
-    const size_t primary_index =
-        std::distance(active_display_list_.begin(), primary_index_it);
-    display_changes[primary_index] |= primary_metrics;
   }
 
   UpdateInfoForRestoringMirrorMode();
@@ -1302,24 +1250,6 @@
     delegate_->PostDisplayConfigurationChange();
   }
 
-  // Populate the pending change structure.
-  {
-    CHECK(pending_display_changes_.has_value());
-    // Currently removed displays should only be populated in
-    // `UpdateDisplaysWith()`.
-    CHECK(pending_display_changes_->removed_displays.empty());
-    pending_display_changes_->removed_displays = std::move(removed_displays);
-    base::ranges::transform(
-        added_display_indices,
-        std::back_inserter(pending_display_changes_->added_display_ids),
-        [this](size_t index) { return active_display_list_[index].id(); });
-    for (const auto& pair : display_changes) {
-      int64_t display_id = active_display_list_[pair.first].id();
-      pending_display_changes_->display_metrics_changes[display_id] |=
-          pair.second;
-    }
-  }
-
   if (mirror_mode) {
     UMA_HISTOGRAM_ENUMERATION(kMirroringImplementationHistogram,
                               IsInSoftwareMirrorMode()
@@ -1844,9 +1774,6 @@
   display->SetSize(display_info_[display_id].size_in_pixel());
   BeginEndNotifier notifier(this);
   NotifyMetricsChanged(*display, DisplayObserver::DISPLAY_METRIC_BOUNDS);
-  CHECK(pending_display_changes_.has_value());
-  pending_display_changes_->display_metrics_changes[display->id()] |=
-      DisplayObserver::DISPLAY_METRIC_BOUNDS;
   return true;
 }
 
@@ -2446,10 +2373,9 @@
   }
 }
 
-void DisplayManager::NotifyDidProcessDisplayChanges(
-    const DisplayManagerObserver::DisplayConfigurationChange& config_change) {
+void DisplayManager::NotifyDidProcessDisplayChanges() {
   for (auto& manager_observer : manager_observers_) {
-    manager_observer.OnDidProcessDisplayChanges(config_change);
+    manager_observer.OnDidProcessDisplayChanges();
   }
 }
 
diff --git a/ui/display/manager/display_manager.h b/ui/display/manager/display_manager.h
index bb8e126..349254f 100644
--- a/ui/display/manager/display_manager.h
+++ b/ui/display/manager/display_manager.h
@@ -30,7 +30,6 @@
 #include "ui/display/display_observer.h"
 #include "ui/display/manager/display_configurator.h"
 #include "ui/display/manager/display_manager_export.h"
-#include "ui/display/manager/display_manager_observer.h"
 #include "ui/display/manager/managed_display_info.h"
 #include "ui/display/manager/touch_device_manager.h"
 #include "ui/display/manager/util/display_manager_util.h"
@@ -47,6 +46,7 @@
 
 class DisplayChangeObserver;
 class DisplayLayoutStore;
+class DisplayManagerObserver;
 class DisplayObserver;
 class NativeDisplayDelegate;
 class Screen;
@@ -498,8 +498,7 @@
   void NotifyDisplayAdded(const Display& display);
   void NotifyDisplayRemoved(const Display& display);
   void NotifyWillProcessDisplayChanges();
-  void NotifyDidProcessDisplayChanges(
-      const DisplayManagerObserver::DisplayConfigurationChange& config_change);
+  void NotifyDidProcessDisplayChanges();
 
   // Delegated from the Screen implementation.
   void AddObserver(DisplayObserver* observer);
@@ -526,34 +525,9 @@
     ~BeginEndNotifier();
 
    private:
-    // Uses the pending display change data in display manager to create the
-    // config change object propagated to observers.
-    DisplayManagerObserver::DisplayConfigurationChange CreateConfigChange()
-        const;
-
     raw_ptr<DisplayManager, ExperimentalAsh> display_manager_;
   };
 
-  // Tracks the in-progress change to the current display configuration. This is
-  // reported to observers when the last BeginEndNotifier goes out of scope.
-  struct PendingDisplayChanges {
-    PendingDisplayChanges();
-    PendingDisplayChanges(const PendingDisplayChanges&) = delete;
-    PendingDisplayChanges& operator=(const PendingDisplayChanges&) = delete;
-    ~PendingDisplayChanges();
-
-    // Store added display_ids to avoid copying potentially stale display
-    // objects while update state is accumulated.
-    DisplayIdList added_display_ids;
-
-    // Store displays by value as removed displays are no longer persisted by
-    // the manager once removed from the `active_display_list_`.
-    Displays removed_displays;
-
-    // Maps the display_id to its metrics change.
-    base::flat_map<int64_t, uint32_t> display_metrics_changes;
-  };
-
   void set_change_display_upon_host_resize(bool value) {
     change_display_upon_host_resize_ = value;
   }
@@ -742,11 +716,6 @@
   // OnWillProcessDisplayChanges() and OnDidProcessDisplayChanges().
   int notify_depth_ = 0;
 
-  // State accumulated during a display configuration update. Created when
-  // BeginEndNotifier is created and propagated in OnDidProcessDisplayChanges()
-  // when the last BeginEndNotifier is destroyed.
-  absl::optional<PendingDisplayChanges> pending_display_changes_;
-
   std::unique_ptr<display::DisplayConfigurator> display_configurator_;
 
   std::unique_ptr<TouchDeviceManager> touch_device_manager_;
diff --git a/ui/display/manager/display_manager_observer.cc b/ui/display/manager/display_manager_observer.cc
deleted file mode 100644
index a00e546..0000000
--- a/ui/display/manager/display_manager_observer.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ui/display/manager/display_manager_observer.h"
-
-namespace display {
-
-DisplayManagerObserver::DisplayMetricsChange::DisplayMetricsChange(
-    const Display& display,
-    uint32_t changed_metrics)
-    : display(display), changed_metrics(changed_metrics) {}
-
-DisplayManagerObserver::DisplayConfigurationChange::DisplayConfigurationChange(
-    Displays added_displays,
-    Displays removed_displays,
-    std::vector<DisplayMetricsChange> display_metrics_changes)
-    : added_displays(added_displays),
-      removed_displays(removed_displays),
-      display_metrics_changes(display_metrics_changes) {}
-
-DisplayManagerObserver::DisplayConfigurationChange::
-    ~DisplayConfigurationChange() = default;
-
-}  // namespace display
diff --git a/ui/display/manager/display_manager_observer.h b/ui/display/manager/display_manager_observer.h
index 983f696..82724da 100644
--- a/ui/display/manager/display_manager_observer.h
+++ b/ui/display/manager/display_manager_observer.h
@@ -5,11 +5,7 @@
 #ifndef UI_DISPLAY_MANAGER_DISPLAY_MANAGER_OBSERVER_H_
 #define UI_DISPLAY_MANAGER_DISPLAY_MANAGER_OBSERVER_H_
 
-#include <vector>
-
-#include "base/memory/raw_ref.h"
 #include "base/observer_list_types.h"
-#include "ui/display/display.h"
 #include "ui/display/manager/display_manager_export.h"
 
 namespace display {
@@ -17,37 +13,13 @@
 class DISPLAY_MANAGER_EXPORT DisplayManagerObserver
     : public base::CheckedObserver {
  public:
-  using Displays = std::vector<Display>;
-
-  // Wraps updated metrics for `display`. `changed_metrics` is a bitmask of
-  // DisplayObserver::DisplayMetric types.
-  struct DISPLAY_EXPORT DisplayMetricsChange {
-    DisplayMetricsChange(const Display& display, uint32_t changed_metrics);
-    const raw_ref<const Display> display;
-    const uint32_t changed_metrics;
-  };
-
-  // Represents an atomic change in the display configuration of the user's
-  // desktop environment maintained by DisplayManager.
-  struct DISPLAY_EXPORT DisplayConfigurationChange {
-    DisplayConfigurationChange(
-        Displays added_displays,
-        Displays removed_displays,
-        std::vector<DisplayMetricsChange> display_metrics_changes);
-    ~DisplayConfigurationChange();
-    const Displays added_displays;
-    const Displays removed_displays;
-    const std::vector<DisplayMetricsChange> display_metrics_changes;
-  };
-
   // Called before the DisplayManager begins processing a change / update to
   // the current display configuration.
   virtual void OnWillProcessDisplayChanges() {}
 
   // Called after the display configuration changes processed by the
   // DisplayManager have completed.
-  virtual void OnDidProcessDisplayChanges(
-      const DisplayConfigurationChange& configuration_change) {}
+  virtual void OnDidProcessDisplayChanges() {}
 };
 
 }  // namespace display
diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
index 6fd963d1..4b44f33e 100644
--- a/ui/gfx/render_text.cc
+++ b/ui/gfx/render_text.cc
@@ -1357,7 +1357,7 @@
 
 bool RenderText::GetWordLookupDataAtPoint(const Point& point,
                                           DecoratedText* decorated_word,
-                                          Point* baseline_point) {
+                                          Rect* rect) {
   if (obscured())
     return false;
 
@@ -1372,12 +1372,12 @@
   DCHECK(!word_range.is_reversed());
   DCHECK(!word_range.is_empty());
 
-  return GetLookupDataForRange(word_range, decorated_word, baseline_point);
+  return GetLookupDataForRange(word_range, decorated_word, rect);
 }
 
 bool RenderText::GetLookupDataForRange(const Range& range,
                                        DecoratedText* decorated_text,
-                                       Point* baseline_point) {
+                                       Rect* rect) {
   const internal::ShapedText* shaped_text = GetShapedText();
 
   const std::vector<Rect> word_bounds = GetSubstringBounds(range);
@@ -1395,8 +1395,9 @@
   if (line_index < 0 ||
       line_index >= static_cast<int>(shaped_text->lines().size()))
     return false;
-  *baseline_point = left_rect->origin() +
-                    Vector2d(0, shaped_text->lines()[line_index].baseline);
+  *rect = Rect(left_rect->origin() +
+                   Vector2d(0, shaped_text->lines()[line_index].baseline),
+               left_rect->size());
   return true;
 }
 
diff --git a/ui/gfx/render_text.h b/ui/gfx/render_text.h
index 1dd38e7..cf21efd 100644
--- a/ui/gfx/render_text.h
+++ b/ui/gfx/render_text.h
@@ -598,22 +598,21 @@
 
   // Retrieves the word displayed at the given |point| along with its styling
   // information. |point| is in the view's coordinates. If no word is displayed
-  // at the point, returns a nearby word. |baseline_point| should correspond to
-  // the baseline point of the leftmost glyph of the |word| in the view's
-  // coordinates. Returns false, if no word can be retrieved.
+  // at the point, returns a nearby word. |rect| should correspond to the space
+  // used by the glyph of the |word| in the view's coordinates. Returns false,
+  // if no word can be retrieved.
   bool GetWordLookupDataAtPoint(const Point& point,
                                 DecoratedText* decorated_word,
-                                Point* baseline_point);
+                                Rect* rect);
 
   // Retrieves the text at |range| along with its styling information.
-  // |baseline_point| should correspond to the baseline point of
-  // the leftmost glyph of the text in the view's coordinates. If the text
-  // spans multiple lines, |baseline_point| will correspond with the leftmost
-  // glyph on the first line in the range. Returns false, if no text can be
-  // retrieved.
+  // |rect| should correspond to the space used by the glyph of the text in the
+  // view's coordinates. If the text spans multiple lines, |rect| will
+  // correspond with the leftmost glyph on the first line in the range. Returns
+  // false, if no text can be retrieved.
   bool GetLookupDataForRange(const Range& range,
                              DecoratedText* decorated_text,
-                             Point* baseline_point);
+                             Rect* rect);
 
   // Retrieves the text in the given |range|.
   std::u16string GetTextFromRange(const Range& range) const;
diff --git a/ui/gfx/render_text_unittest.cc b/ui/gfx/render_text_unittest.cc
index 04214e6d..e9809fd 100644
--- a/ui/gfx/render_text_unittest.cc
+++ b/ui/gfx/render_text_unittest.cc
@@ -7815,21 +7815,21 @@
       SelectionModel(kWordTwoStartIndex, CURSOR_FORWARD), false);
 
   DecoratedText decorated_word;
-  Point baseline_point;
+  Rect rect;
 
   {
     SCOPED_TRACE(base::StringPrintf("Query to the left of text bounds"));
-    EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(
-        Point(-5, cursor_y), &decorated_word, &baseline_point));
+    EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(Point(-5, cursor_y),
+                                                      &decorated_word, &rect));
     VerifyDecoratedWordsAreEqual(expected_word_1, decorated_word);
-    EXPECT_TRUE(left_glyph_word_1.Contains(baseline_point));
+    EXPECT_TRUE(left_glyph_word_1.Contains(rect.origin()));
   }
   {
     SCOPED_TRACE(base::StringPrintf("Query to the right of text bounds"));
-    EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(
-        Point(105, cursor_y), &decorated_word, &baseline_point));
+    EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(Point(105, cursor_y),
+                                                      &decorated_word, &rect));
     VerifyDecoratedWordsAreEqual(expected_word_2, decorated_word);
-    EXPECT_TRUE(left_glyph_word_2.Contains(baseline_point));
+    EXPECT_TRUE(left_glyph_word_2.Contains(rect.origin()));
   }
 
   for (size_t i = 0; i < render_text->text().length(); i++) {
@@ -7839,15 +7839,15 @@
         render_text->GetCursorBounds(SelectionModel(i, CURSOR_FORWARD), false)
             .origin();
 
-    EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(query, &decorated_word,
-                                                      &baseline_point));
+    EXPECT_TRUE(
+        render_text->GetWordLookupDataAtPoint(query, &decorated_word, &rect));
 
     if (i < kWordTwoStartIndex) {
       VerifyDecoratedWordsAreEqual(expected_word_1, decorated_word);
-      EXPECT_TRUE(left_glyph_word_1.Contains(baseline_point));
+      EXPECT_TRUE(left_glyph_word_1.Contains(rect.origin()));
     } else {
       VerifyDecoratedWordsAreEqual(expected_word_2, decorated_word);
-      EXPECT_TRUE(left_glyph_word_2.Contains(baseline_point));
+      EXPECT_TRUE(left_glyph_word_2.Contains(rect.origin()));
     }
   }
 }
@@ -7898,21 +7898,21 @@
       SelectionModel(kWordTwoStartIndex, CURSOR_FORWARD), false);
 
   DecoratedText decorated_word;
-  Point baseline_point;
+  Rect rect;
 
   {
     SCOPED_TRACE(base::StringPrintf("Query to the left of text bounds"));
-    EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(
-        Point(-5, cursor_y), &decorated_word, &baseline_point));
+    EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(Point(-5, cursor_y),
+                                                      &decorated_word, &rect));
     VerifyDecoratedWordsAreEqual(expected_word_2, decorated_word);
-    EXPECT_TRUE(left_glyph_word_2.Contains(baseline_point));
+    EXPECT_TRUE(left_glyph_word_2.Contains(rect.origin()));
   }
   {
     SCOPED_TRACE(base::StringPrintf("Query to the right of text bounds"));
-    EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(
-        Point(105, cursor_y), &decorated_word, &baseline_point));
+    EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(Point(105, cursor_y),
+                                                      &decorated_word, &rect));
     VerifyDecoratedWordsAreEqual(expected_word_1, decorated_word);
-    EXPECT_TRUE(left_glyph_word_1.Contains(baseline_point));
+    EXPECT_TRUE(left_glyph_word_1.Contains(rect.origin()));
   }
 
   for (size_t i = 0; i < render_text->text().length(); i++) {
@@ -7924,14 +7924,14 @@
         render_text->GetCursorBounds(SelectionModel(i, CURSOR_FORWARD), false)
             .top_right();
 
-    EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(query, &decorated_word,
-                                                      &baseline_point));
+    EXPECT_TRUE(
+        render_text->GetWordLookupDataAtPoint(query, &decorated_word, &rect));
     if (i < kWordTwoStartIndex) {
       VerifyDecoratedWordsAreEqual(expected_word_1, decorated_word);
-      EXPECT_TRUE(left_glyph_word_1.Contains(baseline_point));
+      EXPECT_TRUE(left_glyph_word_1.Contains(rect.origin()));
     } else {
       VerifyDecoratedWordsAreEqual(expected_word_2, decorated_word);
-      EXPECT_TRUE(left_glyph_word_2.Contains(baseline_point));
+      EXPECT_TRUE(left_glyph_word_2.Contains(rect.origin()));
     }
   }
 }
@@ -7983,34 +7983,34 @@
       GetSubstringBoundsUnion(Range(kWordThreeIndex, kWordThreeIndex + 1));
 
   DecoratedText decorated_word;
-  Point baseline_point;
+  Rect rect;
   {
     // Query to the left of the first line.
     EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(
-        Point(-5, GetCursorYForTesting(0)), &decorated_word, &baseline_point));
+        Point(-5, GetCursorYForTesting(0)), &decorated_word, &rect));
     VerifyDecoratedWordsAreEqual(expected_word_1, decorated_word);
-    EXPECT_TRUE(left_glyph_word_1.Contains(baseline_point));
+    EXPECT_TRUE(left_glyph_word_1.Contains(rect.origin()));
   }
   {
     // Query on the second line.
     EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(
-        Point(5, GetCursorYForTesting(1)), &decorated_word, &baseline_point));
+        Point(5, GetCursorYForTesting(1)), &decorated_word, &rect));
     VerifyDecoratedWordsAreEqual(expected_word_2, decorated_word);
-    EXPECT_TRUE(left_glyph_word_2.Contains(baseline_point));
+    EXPECT_TRUE(left_glyph_word_2.Contains(rect.origin()));
   }
   {
     // Query at the center point of the character 'c'.
     EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(
-        left_glyph_word_3.CenterPoint(), &decorated_word, &baseline_point));
+        left_glyph_word_3.CenterPoint(), &decorated_word, &rect));
     VerifyDecoratedWordsAreEqual(expected_word_3, decorated_word);
-    EXPECT_TRUE(left_glyph_word_3.Contains(baseline_point));
+    EXPECT_TRUE(left_glyph_word_3.Contains(rect.origin()));
   }
   {
     // Query to the right of the third line.
     EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(
-        Point(505, GetCursorYForTesting(2)), &decorated_word, &baseline_point));
+        Point(505, GetCursorYForTesting(2)), &decorated_word, &rect));
     VerifyDecoratedWordsAreEqual(expected_word_3, decorated_word);
-    EXPECT_TRUE(left_glyph_word_3.Contains(baseline_point));
+    EXPECT_TRUE(left_glyph_word_3.Contains(rect.origin()));
   }
 }
 
@@ -8020,27 +8020,27 @@
   render_text->SetText(u"...");
 
   DecoratedText decorated_word;
-  Point baseline_point;
+  Rect rect;
 
   // False should be returned, when the text does not contain any word.
   Point query =
       render_text->GetCursorBounds(SelectionModel(0, CURSOR_FORWARD), false)
           .origin();
-  EXPECT_FALSE(render_text->GetWordLookupDataAtPoint(query, &decorated_word,
-                                                     &baseline_point));
+  EXPECT_FALSE(
+      render_text->GetWordLookupDataAtPoint(query, &decorated_word, &rect));
 
   render_text->SetText(u"abc");
   query = render_text->GetCursorBounds(SelectionModel(0, CURSOR_FORWARD), false)
               .origin();
-  EXPECT_TRUE(render_text->GetWordLookupDataAtPoint(query, &decorated_word,
-                                                    &baseline_point));
+  EXPECT_TRUE(
+      render_text->GetWordLookupDataAtPoint(query, &decorated_word, &rect));
 
   // False should be returned for obscured text.
   render_text->SetObscured(true);
   query = render_text->GetCursorBounds(SelectionModel(0, CURSOR_FORWARD), false)
               .origin();
-  EXPECT_FALSE(render_text->GetWordLookupDataAtPoint(query, &decorated_word,
-                                                     &baseline_point));
+  EXPECT_FALSE(
+      render_text->GetWordLookupDataAtPoint(query, &decorated_word, &rect));
 }
 
 // Test that GetLookupDataAtPoint behaves correctly when the range spans lines.
@@ -8087,27 +8087,73 @@
       Font::Weight::NORMAL, UNDERLINE_MASK));
 
   DecoratedText decorated_word;
-  Point baseline_point;
+  Rect rect;
   {
     // Query for the range of the first word.
-    EXPECT_TRUE(render_text->GetLookupDataForRange(
-        kWordOneRange, &decorated_word, &baseline_point));
+    EXPECT_TRUE(render_text->GetLookupDataForRange(kWordOneRange,
+                                                   &decorated_word, &rect));
     VerifyDecoratedWordsAreEqual(expected_word_1, decorated_word);
-    EXPECT_TRUE(left_glyph_word_1.Contains(baseline_point));
+    EXPECT_TRUE(left_glyph_word_1.Contains(rect.origin()));
   }
   {
     // Query for the range of the second word.
-    EXPECT_TRUE(render_text->GetLookupDataForRange(
-        kWordTwoRange, &decorated_word, &baseline_point));
+    EXPECT_TRUE(render_text->GetLookupDataForRange(kWordTwoRange,
+                                                   &decorated_word, &rect));
     VerifyDecoratedWordsAreEqual(expected_word_2, decorated_word);
-    EXPECT_TRUE(left_glyph_word_2.Contains(baseline_point));
+    EXPECT_TRUE(left_glyph_word_2.Contains(rect.origin()));
   }
   {
     // Query the entire text range.
-    EXPECT_TRUE(render_text->GetLookupDataForRange(kTextRange, &decorated_word,
-                                                   &baseline_point));
+    EXPECT_TRUE(
+        render_text->GetLookupDataForRange(kTextRange, &decorated_word, &rect));
     VerifyDecoratedWordsAreEqual(expected_entire_text, decorated_word);
-    EXPECT_TRUE(left_glyph_word_1.Contains(baseline_point));
+    EXPECT_TRUE(left_glyph_word_1.Contains(rect.origin()));
+  }
+}
+
+// Test that GetLookupDataForRange returns the expected sizes for each range.
+TEST_F(RenderTextTest, GetLookupDataAtRange_Size) {
+  const char16_t kText[] = u"a\U0001F44D\uFE0Fb";
+  const size_t kGlyphCount = 3;
+  constexpr Range kRange1 = Range(0, 1);  // Range of character 'a'.
+  constexpr Range kRange2 = Range(1, 4);  // Range of the middle glyph.
+  constexpr Range kRange3 = Range(4, 5);  // Range of character 'b'.
+  constexpr Range kRange4 = Range(0, 5);  // Range of the entire text.
+
+  const int kGlyphWidth = 6;
+  const int kGlyphHeight = 10;
+  SetGlyphWidth(kGlyphWidth);
+  SetGlyphHeight(kGlyphHeight);
+  RenderText* render_text = GetRenderText();
+  render_text->SetDisplayRect(Rect(500, 500));
+  render_text->SetText(kText);
+
+  Size expected_size_1 = Size(kGlyphWidth, kGlyphHeight);
+  Size expected_size_2 = Size(kGlyphWidth, kGlyphHeight);
+  Size expected_size_3 = Size(kGlyphWidth, kGlyphHeight);
+  Size expected_size_4 = Size(kGlyphWidth * kGlyphCount, kGlyphHeight);
+
+  DecoratedText decorated_word;
+  Rect rect;
+  {
+    EXPECT_TRUE(
+        render_text->GetLookupDataForRange(kRange1, &decorated_word, &rect));
+    EXPECT_EQ(expected_size_1, rect.size());
+  }
+  {
+    EXPECT_TRUE(
+        render_text->GetLookupDataForRange(kRange2, &decorated_word, &rect));
+    EXPECT_EQ(expected_size_2, rect.size());
+  }
+  {
+    EXPECT_TRUE(
+        render_text->GetLookupDataForRange(kRange3, &decorated_word, &rect));
+    EXPECT_EQ(expected_size_3, rect.size());
+  }
+  {
+    EXPECT_TRUE(
+        render_text->GetLookupDataForRange(kRange4, &decorated_word, &rect));
+    EXPECT_EQ(expected_size_4, rect.size());
   }
 }
 
@@ -8697,25 +8743,25 @@
                               Font::Weight::NORMAL, UNDERLINE_MASK));
 
     DecoratedText decorated_word;
-    Point baseline_point;
+    Rect rect;
 
     // Validation for the first word, u"a".
     EXPECT_TRUE(render_text->GetLookupDataForRange(kWordRange1, &decorated_word,
-                                                   &baseline_point));
+                                                   &rect));
     VerifyDecoratedWordsAreEqual(expected_word_1, decorated_word);
-    EXPECT_EQ(baseline_point, Point(0, 5));
+    EXPECT_EQ(rect.origin(), Point(0, 5));
 
     // Validation for the middle word, u"\U0001F44D\uFE0F" (thumbs up emoji).
     EXPECT_TRUE(render_text->GetLookupDataForRange(kWordRange2, &decorated_word,
-                                                   &baseline_point));
+                                                   &rect));
     VerifyDecoratedWordsAreEqual(expected_word_2, decorated_word);
-    EXPECT_EQ(baseline_point, Point(5, 5));
+    EXPECT_EQ(rect.origin(), Point(5, 5));
 
     // Validation for the last word, u"b".
     EXPECT_TRUE(render_text->GetLookupDataForRange(kWordRange3, &decorated_word,
-                                                   &baseline_point));
+                                                   &rect));
     VerifyDecoratedWordsAreEqual(expected_word_3, decorated_word);
-    EXPECT_EQ(baseline_point, Point(10, 5));
+    EXPECT_EQ(rect.origin(), Point(10, 5));
   };
 
   render_text->SetObscured(false);
diff --git a/ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.cc b/ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.cc
index d709737..360f337 100644
--- a/ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.cc
+++ b/ui/ozone/platform/flatland/flatland_sysmem_buffer_collection.cc
@@ -7,9 +7,9 @@
 #include <fuchsia/sysmem/cpp/fidl.h>
 #include <lib/zx/eventpair.h>
 
+#include <bit>
 #include <tuple>
 
-#include "base/bits.h"
 #include "base/fuchsia/fuchsia_logging.h"
 #include "base/fuchsia/koid.h"
 #include "base/task/current_thread.h"
@@ -426,7 +426,7 @@
 
   uint32_t viable_memory_types =
       properties.memoryTypeBits & requirements.memoryTypeBits;
-  uint32_t memory_type = base::bits::CountTrailingZeroBits(viable_memory_types);
+  uint32_t memory_type = std::countr_zero(viable_memory_types);
 
   VkMemoryDedicatedAllocateInfoKHR dedicated_allocate = {
       VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR};
diff --git a/ui/views/cocoa/native_widget_mac_ns_window_host.mm b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
index b3fa0a3..efbbc2f 100644
--- a/ui/views/cocoa/native_widget_mac_ns_window_host.mm
+++ b/ui/views/cocoa/native_widget_mac_ns_window_host.mm
@@ -1129,11 +1129,14 @@
 
   gfx::Point location_in_target = location_in_content;
   views::View::ConvertPointToTarget(root_view_, target, &location_in_target);
-  if (!word_lookup_client->GetWordLookupDataAtPoint(
-          location_in_target, decorated_word, baseline_point)) {
+  gfx::Rect rect;
+  if (!word_lookup_client->GetWordLookupDataAtPoint(location_in_target,
+                                                    decorated_word, &rect)) {
     return;
   }
 
+  // We only care about the baseline of the glyph, not the space it occupies.
+  *baseline_point = rect.origin();
   // Convert |baselinePoint| to the coordinate system of |root_view_|.
   views::View::ConvertPointToTarget(target, root_view_, baseline_point);
   *found_word = true;
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc
index 6c07235..0dd0a9b9 100644
--- a/ui/views/controls/label.cc
+++ b/ui/views/controls/label.cc
@@ -1039,22 +1039,20 @@
 
 bool Label::GetWordLookupDataAtPoint(const gfx::Point& point,
                                      gfx::DecoratedText* decorated_word,
-                                     gfx::Point* baseline_point) {
+                                     gfx::Rect* rect) {
   gfx::RenderText* render_text = GetRenderTextForSelectionController();
   if (render_text && !render_text->obscured()) {
-    return render_text->GetWordLookupDataAtPoint(point, decorated_word,
-                                                 baseline_point);
+    return render_text->GetWordLookupDataAtPoint(point, decorated_word, rect);
   }
   return false;
 }
 
 bool Label::GetWordLookupDataFromSelection(gfx::DecoratedText* decorated_text,
-                                           gfx::Point* baseline_point) {
+                                           gfx::Rect* rect) {
   gfx::RenderText* render_text = GetRenderTextForSelectionController();
-  return render_text
-             ? render_text->GetLookupDataForRange(
-                   render_text->selection(), decorated_text, baseline_point)
-             : false;
+  return render_text ? render_text->GetLookupDataForRange(
+                           render_text->selection(), decorated_text, rect)
+                     : false;
 }
 
 gfx::RenderText* Label::GetRenderTextForSelectionController() {
diff --git a/ui/views/controls/label.h b/ui/views/controls/label.h
index 0f1f9cb..0fba633 100644
--- a/ui/views/controls/label.h
+++ b/ui/views/controls/label.h
@@ -391,10 +391,10 @@
   // WordLookupClient overrides:
   bool GetWordLookupDataAtPoint(const gfx::Point& point,
                                 gfx::DecoratedText* decorated_word,
-                                gfx::Point* baseline_point) override;
+                                gfx::Rect* rect) override;
 
   bool GetWordLookupDataFromSelection(gfx::DecoratedText* decorated_text,
-                                      gfx::Point* baseline_point) override;
+                                      gfx::Rect* rect) override;
 
   // SelectionControllerDelegate overrides:
   gfx::RenderText* GetRenderTextForSelectionController() override;
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc
index afec097..c42908b1 100644
--- a/ui/views/controls/textfield/textfield.cc
+++ b/ui/views/controls/textfield/textfield.cc
@@ -1248,19 +1248,18 @@
 
 bool Textfield::GetWordLookupDataAtPoint(const gfx::Point& point,
                                          gfx::DecoratedText* decorated_word,
-                                         gfx::Point* baseline_point) {
-  return GetRenderText()->GetWordLookupDataAtPoint(point, decorated_word,
-                                                   baseline_point);
+                                         gfx::Rect* rect) {
+  return GetRenderText()->GetWordLookupDataAtPoint(point, decorated_word, rect);
 }
 
 bool Textfield::GetWordLookupDataFromSelection(
     gfx::DecoratedText* decorated_text,
-    gfx::Point* baseline_point) {
+    gfx::Rect* rect) {
   if (GetRenderText()->obscured()) {
     return false;
   }
   return GetRenderText()->GetLookupDataForRange(GetRenderText()->selection(),
-                                                decorated_text, baseline_point);
+                                                decorated_text, rect);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/ui/views/controls/textfield/textfield.h b/ui/views/controls/textfield/textfield.h
index 09b64b0..a61f1cf 100644
--- a/ui/views/controls/textfield/textfield.h
+++ b/ui/views/controls/textfield/textfield.h
@@ -381,9 +381,9 @@
   // WordLookupClient overrides:
   bool GetWordLookupDataAtPoint(const gfx::Point& point,
                                 gfx::DecoratedText* decorated_word,
-                                gfx::Point* baseline_point) override;
+                                gfx::Rect* rect) override;
   bool GetWordLookupDataFromSelection(gfx::DecoratedText* decorated_text,
-                                      gfx::Point* baseline_point) override;
+                                      gfx::Rect* rect) override;
 
   // SelectionControllerDelegate overrides:
   bool HasTextBeingDragged() const override;
diff --git a/ui/views/controls/views_text_services_context_menu_mac.mm b/ui/views/controls/views_text_services_context_menu_mac.mm
index 4b560803..21b66a2 100644
--- a/ui/views/controls/views_text_services_context_menu_mac.mm
+++ b/ui/views/controls/views_text_services_context_menu_mac.mm
@@ -133,9 +133,12 @@
 
 void ViewsTextServicesContextMenuMac::LookUpInDictionary() {
   gfx::DecoratedText text;
-  gfx::Point baseline_point;
-  if (client()->GetWordLookupDataFromSelection(&text, &baseline_point)) {
+  gfx::Rect rect;
+  if (client()->GetWordLookupDataFromSelection(&text, &rect)) {
     Widget* widget = client()->GetWidget();
+
+    // We only care about the baseline of the glyph, not the space it occupies.
+    gfx::Point baseline_point = rect.origin();
     views::View::ConvertPointToTarget(client(), widget->GetRootView(),
                                       &baseline_point);
     NSView* view = widget->GetNativeView().GetNativeNSView();
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.cc
index 7c96c9f..a30c2f13 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_ozone.cc
@@ -298,8 +298,9 @@
             base::BindOnce(&DesktopDragDropClientOzone::DragCancel,
                            weak_factory_.GetWeakPtr()));
 
+        auto* data_to_drop_raw = data_to_drop_.get();
         DropIfAllowed(
-            data_to_drop_.get(), current_drag_info_,
+            data_to_drop_raw, current_drag_info_,
             base::BindOnce(&PerformDrop, std::move(drop_cb),
                            std::move(data_to_drop_), std::move(drag_cancel)));
       }
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 0b4fb415..12460e2 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
@@ -480,14 +480,14 @@
                     base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     const absl::optional<size_t> size));
   MOCK_METHOD5(PasteIfAllowed,
-               void(const ui::DataTransferEndpoint* const data_src,
-                    const ui::DataTransferEndpoint* const data_dst,
+               void(base::optional_ref<const ui::DataTransferEndpoint> data_src,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     const absl::optional<size_t> size,
                     content::RenderFrameHost* rfh,
                     base::OnceCallback<void(bool)> callback));
   MOCK_METHOD3(DropIfAllowed,
                void(const ui::OSExchangeData* drag_data,
-                    const ui::DataTransferEndpoint* data_dst,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::OnceClosure drop_cb));
 };
 
@@ -499,7 +499,7 @@
   // Data Leak Prevention stack allows the drop.
   EXPECT_CALL(dtp_controller, DropIfAllowed(testing::_, testing::_, testing::_))
       .WillOnce([&](const ui::OSExchangeData* drag_data,
-                    const ui::DataTransferEndpoint* data_dst,
+                    base::optional_ref<const ui::DataTransferEndpoint> data_dst,
                     base::OnceClosure drop_cb) { std::move(drop_cb).Run(); });
 
   // Set the operation which the destination can accept.
diff --git a/ui/views/word_lookup_client.h b/ui/views/word_lookup_client.h
index 11d1e74..3a2f6ad2 100644
--- a/ui/views/word_lookup_client.h
+++ b/ui/views/word_lookup_client.h
@@ -19,16 +19,16 @@
  public:
   // Retrieves the word displayed at the given |point| along with its styling
   // information. |point| is in the coordinate system of the view. If no word is
-  // displayed at the point, returns a nearby word. |baseline_point| should
-  // correspond to the baseline point of the leftmost glyph of the |word| in the
-  // view's coordinates. Returns false, if no word can be retrieved.
+  // displayed at the point, returns a nearby word. |rect| should correspond to
+  // the space used by the leftmost glyph of the |word| in the view's
+  // coordinates. Returns false, if no word can be retrieved.
   virtual bool GetWordLookupDataAtPoint(const gfx::Point& point,
                                         gfx::DecoratedText* decorated_word,
-                                        gfx::Point* baseline_point) = 0;
+                                        gfx::Rect* rect) = 0;
 
   virtual bool GetWordLookupDataFromSelection(
       gfx::DecoratedText* decorated_text,
-      gfx::Point* baseline_point) = 0;
+      gfx::Rect* rect) = 0;
 
  protected:
   virtual ~WordLookupClient() = default;
diff --git a/ui/webui/resources/cr_elements/BUILD.gn b/ui/webui/resources/cr_elements/BUILD.gn
index 9b35e67..877d78df 100644
--- a/ui/webui/resources/cr_elements/BUILD.gn
+++ b/ui/webui/resources/cr_elements/BUILD.gn
@@ -30,6 +30,7 @@
       "cr_dialog/cr_dialog.ts",
       "cr_drawer/cr_drawer.ts",
       "cr_expand_button/cr_expand_button.ts",
+      "cr_feedback_buttons/cr_feedback_buttons.ts",
       "cr_fingerprint/cr_fingerprint_progress_arc.ts",
       "cr_grid/cr_grid.ts",
       "cr_icon_button/cr_icon_button.ts",
diff --git a/ui/webui/resources/cr_elements/cr_feedback_buttons/cr_feedback_buttons.html b/ui/webui/resources/cr_elements/cr_feedback_buttons/cr_feedback_buttons.html
new file mode 100644
index 0000000..e718dfd
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_feedback_buttons/cr_feedback_buttons.html
@@ -0,0 +1,32 @@
+<style>
+  .buttons {
+    --cr-feedback-buttons-icon-size_: 16px;
+    display: grid;
+    grid-auto-columns: var(--cr-feedback-buttons-icon-size_);
+    grid-auto-rows: var(--cr-feedback-buttons-icon-size_);
+    grid-auto-flow: column;
+    gap: 12px;
+    align-items: center;
+    justify-items: center;
+  }
+
+  cr-icon-button {
+    --cr-icon-button-fill-color: var(--cr-secondary-text-color);
+    --cr-icon-button-icon-size: var(--cr-feedback-buttons-icon-size_);
+    margin: 0;
+  }
+</style>
+
+<div class="buttons">
+  <cr-icon-button id="thumbsUp" iron-icon="[[getThumbsUpIcon_(selectedOption)]]"
+      aria-label="[[thumbsUpLabel_]]"
+      aria-pressed="[[getThumbsUpAriaPressed_(selectedOption)]]"
+      on-click="onThumbsUpClick_">
+  </cr-icon-button>
+  <cr-icon-button id="thumbsDown"
+      iron-icon="[[getThumbsDownIcon_(selectedOption)]]"
+      aria-label="[[thumbsDownLabel_]]"
+      aria-pressed="[[getThumbsDownAriaPressed_(selectedOption)]]"
+      on-click="onThumbsDownClick_">
+  </cr-icon-button>
+</div>
diff --git a/ui/webui/resources/cr_elements/cr_feedback_buttons/cr_feedback_buttons.ts b/ui/webui/resources/cr_elements/cr_feedback_buttons/cr_feedback_buttons.ts
new file mode 100644
index 0000000..8812b0c
--- /dev/null
+++ b/ui/webui/resources/cr_elements/cr_feedback_buttons/cr_feedback_buttons.ts
@@ -0,0 +1,108 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import '../cr_icon_button/cr_icon_button.js';
+import '../cr_shared_vars.css.js';
+import '../icons.html.js';
+
+import {loadTimeData} from '//resources/js/load_time_data.js';
+import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {CrIconButtonElement} from '../cr_icon_button/cr_icon_button.js';
+
+import {getTemplate} from './cr_feedback_buttons.html.js';
+
+export enum CrFeedbackOption {
+  THUMBS_DOWN = 0,
+  THUMBS_UP = 1,
+  UNSPECIFIED = 2,
+}
+
+export interface CrFeedbackButtonsElement {
+  $: {
+    thumbsDown: CrIconButtonElement,
+    thumbsUp: CrIconButtonElement,
+  };
+}
+
+export class CrFeedbackButtonsElement extends PolymerElement {
+  static get is() {
+    return 'cr-feedback-buttons';
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  static get properties() {
+    return {
+      selectedOption: {
+        type: String,
+        value: CrFeedbackOption.UNSPECIFIED,
+      },
+      thumbsDownLabel_: {
+        type: String,
+        value: () => loadTimeData.getString('thumbsDown'),
+      },
+      thumbsUpLabel_: {
+        type: String,
+        value: () => loadTimeData.getString('thumbsUp'),
+      },
+    };
+  }
+
+  selectedOption: CrFeedbackOption;
+  private thumbsDownLabel_: string;
+  private thumbsUpLabel_: string;
+
+  private getThumbsDownAriaPressed_(): boolean {
+    return this.selectedOption === CrFeedbackOption.THUMBS_DOWN;
+  }
+
+  private getThumbsDownIcon_(): string {
+    return this.selectedOption === CrFeedbackOption.THUMBS_DOWN ?
+        'cr:thumbs-down-filled' :
+        'cr:thumbs-down';
+  }
+
+  private getThumbsUpAriaPressed_(): boolean {
+    return this.selectedOption === CrFeedbackOption.THUMBS_UP;
+  }
+
+  private getThumbsUpIcon_(): string {
+    return this.selectedOption === CrFeedbackOption.THUMBS_UP ?
+        'cr:thumbs-up-filled' :
+        'cr:thumbs-up';
+  }
+
+  private notifySelectedOptionChanged_() {
+    this.dispatchEvent(new CustomEvent('selected-option-changed', {
+      bubbles: true,
+      composed: true,
+      detail: {value: this.selectedOption},
+    }));
+  }
+
+  private onThumbsDownClick_() {
+    this.selectedOption = this.selectedOption === CrFeedbackOption.THUMBS_DOWN ?
+        CrFeedbackOption.UNSPECIFIED :
+        CrFeedbackOption.THUMBS_DOWN;
+    this.notifySelectedOptionChanged_();
+  }
+
+  private onThumbsUpClick_() {
+    this.selectedOption = this.selectedOption === CrFeedbackOption.THUMBS_UP ?
+        CrFeedbackOption.UNSPECIFIED :
+        CrFeedbackOption.THUMBS_UP;
+    this.notifySelectedOptionChanged_();
+  }
+}
+
+declare global {
+  interface HTMLElementTagNameMap {
+    'cr-feedback-buttons': CrFeedbackButtonsElement;
+  }
+}
+
+customElements.define(CrFeedbackButtonsElement.is, CrFeedbackButtonsElement);
diff --git a/ui/webui/resources/cr_elements/cr_tree/cr_tree_base.ts b/ui/webui/resources/cr_elements/cr_tree/cr_tree_base.ts
index 26b000cc..b613c49a 100644
--- a/ui/webui/resources/cr_elements/cr_tree/cr_tree_base.ts
+++ b/ui/webui/resources/cr_elements/cr_tree/cr_tree_base.ts
@@ -33,8 +33,8 @@
   }
 
   get items(): CrTreeBaseElement[] {
-    return Array.from(this.itemsRoot.querySelectorAll('cr-tree-item')) as
-        CrTreeBaseElement[];
+    return Array.from(
+        this.itemsRoot.querySelectorAll<CrTreeBaseElement>('cr-tree-item'));
   }
 
   abstract get depth(): number;
diff --git a/ui/webui/resources/cr_elements/icons.html b/ui/webui/resources/cr_elements/icons.html
index b0fdde2..b0c72fa1 100644
--- a/ui/webui/resources/cr_elements/icons.html
+++ b/ui/webui/resources/cr_elements/icons.html
@@ -313,11 +313,20 @@
             d="M6 3h11v13l-7 7-1.25-1.25a1.454 1.454 0 0 1-.3-.475c-.067-.2-.1-.392-.1-.575v-.35L9.45 16H3c-.533 0-1-.2-1.4-.6-.4-.4-.6-.867-.6-1.4v-2c0-.117.017-.242.05-.375s.067-.258.1-.375l3-7.05c.15-.333.4-.617.75-.85C5.25 3.117 5.617 3 6 3Zm9 2H6l-3 7v2h9l-1.35 5.5L15 15.15V5Zm0 10.15V5v10.15Zm2 .85v-2h3V5h-3V3h5v13h-5Z">
         </path>
       </g>
+      <g id="thumbs-down-filled">
+        <path
+            d="M6 3h10v13l-7 7-1.25-1.25a1.336 1.336 0 0 1-.29-.477 1.66 1.66 0 0 1-.108-.574v-.347L8.449 16H3c-.535 0-1-.2-1.398-.602C1.199 15 1 14.535 1 14v-2c0-.117.012-.242.04-.375.022-.133.062-.258.108-.375l3-7.05c.153-.333.403-.618.75-.848A1.957 1.957 0 0 1 6 3Zm12 13V3h4v13Zm0 0">
+        </path>
+      </g>
       <g id="thumbs-up">
         <path
             d="M18 21H7V8l7-7 1.25 1.25c.117.117.208.275.275.475.083.2.125.392.125.575v.35L14.55 8H21c.533 0 1 .2 1.4.6.4.4.6.867.6 1.4v2c0 .117-.017.242-.05.375s-.067.258-.1.375l-3 7.05c-.15.333-.4.617-.75.85-.35.233-.717.35-1.1.35Zm-9-2h9l3-7v-2h-9l1.35-5.5L9 8.85V19ZM9 8.85V19 8.85ZM7 8v2H4v9h3v2H2V8h5Z">
         </path>
       </g>
+      <g id="thumbs-up-filled">
+        <path
+            d="M18 21H8V8l7-7 1.25 1.25c.117.117.21.273.29.477.073.199.108.39.108.574v.347L15.551 8H21c.535 0 1 .2 1.398.602C22.801 9 23 9.465 23 10v2c0 .117-.012.242-.04.375a1.897 1.897 0 0 1-.108.375l-3 7.05a2.037 2.037 0 0 1-.75.848A1.957 1.957 0 0 1 18 21ZM6 8v13H2V8Zm0 0">
+      </g>
       <g id="videocam">
         <path
           d="M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z">
diff --git a/ui/webui/resources/css/list.css b/ui/webui/resources/css/list.css
index fb244c5..4944df1 100644
--- a/ui/webui/resources/css/list.css
+++ b/ui/webui/resources/css/list.css
@@ -61,8 +61,8 @@
 list > [selected],
 grid > [selected] {
   background-color: hsl(0, 0%, 90%);
-  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.8),
-                                            rgba(255, 255, 255, 0));
+  background-image: linear-gradient(rgba(255, 255, 255, 0.8),
+                                    rgba(255, 255, 255, 0));
   border-color: hsl(0, 0%, 85%);
   z-index: 2;
 }
diff --git a/ui/webui/resources/css/menu.css b/ui/webui/resources/css/menu.css
index 80b60cb..db17af58 100644
--- a/ui/webui/resources/css/menu.css
+++ b/ui/webui/resources/css/menu.css
@@ -43,9 +43,9 @@
 }
 
 cr-menu > hr {
-  background: -webkit-linear-gradient(left,
-                                      rgba(0, 0, 0, .10),
-                                      rgba(0, 0, 0, .02) 96%);
+  background: linear-gradient(to right,
+                              rgba(0, 0, 0, .10),
+                              rgba(0, 0, 0, .02) 96%);
   border: 0;
   height: 1px;
   margin: 8px 0;
diff --git a/ui/webui/resources/css/widgets.css b/ui/webui/resources/css/widgets.css
index 111f149..aa952a7 100644
--- a/ui/webui/resources/css/widgets.css
+++ b/ui/webui/resources/css/widgets.css
@@ -17,7 +17,7 @@
 input[type='checkbox'],
 input[type='radio'] {
   -webkit-appearance: none;
-  background-image: -webkit-linear-gradient(#ededed, #ededed 38%, #dedede);
+  background-image: linear-gradient(#ededed, #ededed 38%, #dedede);
   border: 1px solid rgba(0, 0, 0, 0.25);
   border-radius: 2px;
   box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08),
@@ -60,7 +60,7 @@
       -webkit-image-set(
           url(../images/select.png) 1x,
           url(../images/2x/select.png) 2x),
-      -webkit-linear-gradient(#ededed, #ededed 38%, #dedede);
+      linear-gradient(#ededed, #ededed 38%, #dedede);
   background-position: right center;
   background-repeat: no-repeat;
   padding-inline-end: 24px;
@@ -165,7 +165,7 @@
         button,
         input[type='button'],
         input[type='submit']):not(.custom-appearance)) {
-  background-image: -webkit-linear-gradient(#f0f0f0, #f0f0f0 38%, #e0e0e0);
+  background-image: linear-gradient(#f0f0f0, #f0f0f0 38%, #e0e0e0);
   border-color: rgba(0, 0, 0, 0.3);
   box-shadow: 0 1px 0 rgba(0, 0, 0, 0.12),
       inset 0 1px 2px rgba(255, 255, 255, 0.95);
@@ -178,7 +178,7 @@
       -webkit-image-set(
           url(../images/select.png) 1x,
           url(../images/2x/select.png) 2x),
-      -webkit-linear-gradient(#f0f0f0, #f0f0f0 38%, #e0e0e0);
+      linear-gradient(#f0f0f0, #f0f0f0 38%, #e0e0e0);
 }
 </if>
 
@@ -192,7 +192,7 @@
         button,
         input[type='button'],
         input[type='submit']):not(.custom-appearance)) {
-  background-image: -webkit-linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7);
+  background-image: linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7);
   box-shadow: none;
   text-shadow: none;
 }
@@ -200,7 +200,7 @@
 :enabled:active:-webkit-any(select) {
   /* OVERRIDE */
   background-image: url(../images/select.png),
-      -webkit-linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7);
+      linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7);
 }
 
 /* Disabled *******************************************************************/
@@ -210,7 +210,7 @@
     input[type='button'],
     input[type='submit']):not(.custom-appearance),
 select:disabled {
-  background-image: -webkit-linear-gradient(#f1f1f1, #f1f1f1 38%, #e6e6e6);
+  background-image: linear-gradient(#f1f1f1, #f1f1f1 38%, #e6e6e6);
   border-color: rgba(80, 80, 80, 0.2);
   box-shadow: 0 1px 0 rgba(80, 80, 80, 0.08),
       inset 0 1px 2px rgba(255, 255, 255, 0.75);
@@ -223,7 +223,7 @@
       -webkit-image-set(
           url(../images/disabled_select.png) 1x,
           url(../images/2x/disabled_select.png) 2x),
-      -webkit-linear-gradient(#f1f1f1, #f1f1f1 38%, #e6e6e6);
+      linear-gradient(#f1f1f1, #f1f1f1 38%, #e6e6e6);
 }
 
 input:disabled:-webkit-any([type='checkbox'],