Version 2.8.0-dev.18.0

Merge commit 'f6acefa078be0cf448f18697a025684fbf5d0ea0' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6e4afcd..9f68bb1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,306 +1,303 @@
-## Next release
-(Add new changes here, and they will be copied to the change section for the
- next release)
+## 2.8.0
+
+Much of the changes in this release are in preparation for non-nullable types,
+which will arrive in a future version. In anticipation of that, we have made a
+number of small but technically breaking changes to several core library APIs in
+order to make them easier to use in a world with non-nullable types. Almost all
+existing Dart code will be unaffected by these changes, but if you see
+unexpected failures, note the breaking changes listed below.
 
 ### Language
 
+There are no language changes in this release.
+
 ### Core libraries
 
 #### `dart:async`
 
-* Make stack traces non-null. Where methods like `completer.completeError`
-  allows omitting a stack trace, the platform will now insert a default
-  stack trace rather than propagate a `null` value.
-  Error handling functions need no longer be prepared for `null` stack traces.
+*   Make stack traces non-null. Where methods like `completer.completeError()`
+    allow omitting a stack trace, the platform will now insert a default stack
+    trace rather than propagate a `null` value.
+
+    Error handling functions need no longer be prepared for `null` stack traces.
+
+*   **Breaking change** [#40681][]: The `runZoned()` function is split into two
+    functions: `runZoned()` and `runZonedGuarded()`, where the latter has a
+    required `onError` parameter, and the former has none. This prepares the
+    functions for Null Safety where the two functions will differ in the
+    nullability of their return types.
+
+[#40681]: https://github.com/dart-lang/sdk/issues/40681
 
 #### `dart:core`
 
-* Adds `StackTrace.empty` constant which is the stack trace used as default
-  stack trace when no better alternative is available.
+* The class `CastError` is deprecated, and all implementation specific
+    classes implementing `TypeError` or `CastError` now implement both.  In
+    a future release, `CastError` will be removed.  See issue [40763][] for
+    details.
 
-* The class `TypeError` no longer extends `AssertionError`.
-  This also means that it no longer inherits the spurious `message` getter
-  which was added to `AssertionError` when the second operand to `assert`
-  was allowed. The value of that getter on a `TypeError` was the same
-  string as returned by `toString`, so it is still available.
-* `ArgumentError.checkNotNull` and the `RangeError` static methods
-  `checkValueInInterval`, `checkValidIndex` and `checkNotNegative`
-  all return their first argument on success.
-  This makes these functions more convenient to use in-line in,
-  for example, `=>` function bodies or constructor initialization lists.
+*   Adds `StackTrace.empty` constant which is the stack trace used as default
+    stack trace when no better alternative is available.
+
+*   The class `TypeError` no longer extends `AssertionError`. This also means
+    that it no longer inherits the spurious `message` getter which was added to
+    `AssertionError` when the second operand to `assert` was allowed. The value
+    of that getter on a `TypeError` was the same string as returned by
+    `toString()`, so it is still available.
+
+*   `ArgumentError.checkNotNull()` and the `RangeError` static methods
+    `checkValueInInterval()`, `checkValidIndex()` and `checkNotNegative()` all
+    return their first argument on success. This makes these functions more
+    convenient to use in-line in, for example, `=>` function bodies or
+    constructor initialization lists.
+
+[40763]: https://github.com/dart-lang/sdk/issues/40763
 
 #### `dart:developer`
 
-* The constructors for `TimelineTask` now accept an optional `filterKey`
-  parameter. If provided, the arguments for all events associated with the task
-  will contain an entry named `filterKey`, set to the value of the `filterKey`
-  parameter provided in the constructor. This will be used by tooling to allow
-  for better filtering of timeline events.
+*   The constructors for `TimelineTask` now accept an optional `filterKey`
+    parameter. If provided, the arguments for all events associated with the
+    task will contain an entry named `filterKey`, set to the value of the
+    `filterKey` parameter provided in the constructor. This will be used by
+    tooling to allow for better filtering of timeline events.
 
 #### `dart:html`
 
-* **Breaking Change**: Changed the return type of several html native methods
-involving Futures. In return types that matched Future<List<T>>, T was changed
-to `dynamic`. These methods would have resulted in a runtime error if they were
-used (see Issue [39627][]).
+*   **Breaking Change** [#39627][]: Changed the return type of several HTML
+    native methods involving futures. In return types that matched
+    `Future<List<T>>`, `T was` changed to `dynamic`. These methods would have
+    resulted in a runtime error if they were used.
 
-[39627]: https://github.com/dart-lang/sdk/issues/39627
+*   **Breaking Change**: `Node.insertAllBefore()` erroneously had a return type
+    of `Node`, even though it was not returning anything. This has been
+    corrected to `void`.
 
-* **Breaking Change**: `Node.insertAllBefore` erroneously had a return type of
-`Node`, even though it was not returning anything. This has been corrected to
-`void`.
+[#39627]: https://github.com/dart-lang/sdk/issues/39627
 
 #### `dart:io`
 
-* Class `HttpParser` will no longer throw an exception when a HTTP response
-  status code is within [0, 999]. Customized status codes in this range are now
-  valid.
+*   Class `HttpParser` will no longer throw an exception when a HTTP response
+    status code is within [0, 999]. Customized status codes in this range are
+    now valid.
 
-* **Breaking change** [#33501](https://github.com/dart-lang/sdk/issues/33501):
-  This is breaking only for classes extending or implementing `HttpHeaders` and
-  having their own `add` or `set` methods without the `bool preserveHeaderCase`
-  named parameter. The signature of `add` and `set` has been changed to
+*   **Breaking change** [#33501][]: The signature of `HttpHeaders` methods
+    `add()` and `set` have been changed to:
 
-  ```dart
-  void add(String name, Object value, {bool preserveHeaderCase: false})
-  void set(String name, Object value, {bool preserveHeaderCase: false})
-  ```
+    ```dart
+    void add(String name, Object value, {bool preserveHeaderCase: false})
+    void set(String name, Object value, {bool preserveHeaderCase: false})
+    ```
 
-  Setting `preserveHeaderCase` to `true` will preserve the case of the `name`
-  parameter instead of converting it to lowercase. The `HttpHeader.forEach()`
-  method provides the current case of each header.
+    Setting `preserveHeaderCase` to `true` preserves the case of the `name`
+    parameter instead of converting it to lowercase. The `HttpHeader.forEach()`
+    method provides the current case of each header.
 
-* **Breaking change** [#40702](https://github.com/dart-lang/sdk/issues/40702):
-  The `Socket` class will now throw a `SocketException` if the socket has been
-  explicitly destroyed or upgraded to a secure socket upon setting or getting
-  socket options. Previously setting a socket option would be ignored and
-  getting a socket option would return `null`.
+    This is breaking only for classes extending or implementing `HttpHeaders`
+    and having their own `add` or `set` methods without the `bool
+    preserveHeaderCase` named parameter.
 
-* **Breaking change** [#40483](https://github.com/dart-lang/sdk/issues/40483):
-  The `Process` class will now throw a `StateError` if the process is detached
-  (`ProcessStartMode.detached` and `ProcessStartMode.detachedWithStdio`) upon
-  accessing the `exitCode` getter. It now also throws when not connected to the
-  child process's stdio (`ProcessStartMode.detached` and
-  `ProcessStartMode.inheritStdio`) upon accessing the `stdin`, `stdout`, and
-  `stderr` getters. Previously these getters would all return `null`.
+*   **Breaking change** [#40702][]: The `Socket` class now throws a
+    `SocketException` if the socket has been explicitly destroyed or upgraded to
+    a secure socket upon setting or getting socket options. Previously, setting
+    a socket option would be ignored and getting a socket option would return
+    `null`.
 
-* **Breaking change** [#40706](https://github.com/dart-lang/sdk/issues/40706):
-  The dummy object returned if `FileStat.stat()` and `FileStat.statSync()` fail
-  now contains Unix epoch timestamps instead of `null` for the `accessed`,
-  `changed`, and `modified` getters.
+*   **Breaking change** [#40483][]: The `Process` class now throws a
+    `StateError` if the process is detached (`ProcessStartMode.detached` and
+    `ProcessStartMode.detachedWithStdio`) upon accessing the `exitCode` getter.
+    It now also throws when not connected to the child process's stdio
+    (`ProcessStartMode.detached` and `ProcessStartMode.inheritStdio`) upon
+    accessing the `stdin`, `stdout`, and `stderr` getters. Previously, these
+    getters would all return `null`.
 
-* **Breaking change** [#40709](https://github.com/dart-lang/sdk/issues/40709):
-  The `HeaderValue` class now parses more strictly in two invalid edge cases.
-  This is the class used to parse the semicolon delimited parameters used in the
-  `Accept`, `Authorization`, `Content-Type`, and other such HTTP headers.
+*   **Breaking change** [#40706][]: The dummy object returned if
+    `FileStat.stat()` or `FileStat.statSync()` fail now contains Unix epoch
+    timestamps instead of `null` for the `accessed`, `changed`, and `modified`
+    getters.
 
-  The empty parameter value without double quotes (which is not allowed by the
-  standards) is now parsed as the empty string rather than `null`. E.g.
-  `HeaderValue.parse("v;a=").parameters` now gives `{"a": ""}` rather than
-  `{"a": null}`.
+*   **Breaking change** [#40709][]: The `HeaderValue` class now parses more
+    strictly in two invalid edge cases. This is the class used to parse the
+    semicolon delimited parameters used in the `Accept`, `Authorization`,
+    `Content-Type`, and other such HTTP headers.
 
-  Invalid inputs with unbalanced double quotes are now rejected. E.g.
-  `HeaderValue.parse('v;a="b').parameters` will now throw a `HttpException`
-  instead of giving `{"a": "b"}`.
+    The empty parameter value without double quotes (which is not allowed by the
+    standards) is now parsed as the empty string rather than `null`. E.g.
+    `HeaderValue.parse("v;a=").parameters` now gives `{"a": ""}` rather than
+    `{"a": null}`.
 
-* The `HeaderValue.toString()` method now supports parameters with `null` values
-  by omitting the value. `HeaderValue("v", {"a": null, "b": "c"}).toString()`
-  now gives `v; a; b=c`. This behavior can be used to implement some features in
-  the `Accept` and `Sec-WebSocket-Extensions` headers.
+    Invalid inputs with unbalanced double quotes are now rejected. E.g.
+    `HeaderValue.parse('v;a="b').parameters` will now throw a `HttpException`
+    instead of giving `{"a": "b"}`.
 
-  Likewise the empty value and values using characters outside of
-  [RFC 7230 tokens](https://tools.ietf.org/html/rfc7230#section-3.2.6) are now
-  correctly implemented by double quoting such values with escape sequences.
-  E.g:
+*   The `HeaderValue.toString()` method now supports parameters with `null`
+    values by omitting the value. `HeaderValue("v", {"a": null, "b":
+    "c"}).toString()` now gives `v; a; b=c`. This behavior can be used to
+    implement some features in the `Accept` and `Sec-WebSocket-Extensions`
+    headers.
 
-  ```dart
-  HeaderValue("v",
-      {"a": "A", "b": "(B)", "c": "", "d": "ø", "e": "\\\""}).toString()
-  ```
+    Likewise the empty value and values using characters outside of [RFC 7230
+    tokens][] are now correctly implemented by double quoting such values with
+    escape sequences. For example:
 
-  now gives `v;a=A;b="(B)";c="";d="ø";e="\\\""`.
+    ```dart
+    HeaderValue("v",
+        {"a": "A", "b": "(B)", "c": "", "d": "ø", "e": "\\\""}).toString()
+    ```
 
-* [Unix domain sockets](https://en.wikipedia.org/wiki/Unix_domain_socket) are
-  now supported on Linux, Android and MacOS, which can be used by passing a
-  `InternetAddress` of `InternetAddressType.Unix` into `connect`, `startConnect`
-  and `bind` methods. `port` argument in those methods will be ignored. Getter
-  of `port` will always return 0 for Unix domain sockets.
+    Gives: `v;a=A;b="(B)";c="";d="ø";e="\\\""`.
 
-* Class `InternetAddressType` gains one more option `Unix`, which represents a
-  Unix domain address.
+*   [Unix domain sockets][] are now supported on Linux, Android and MacOS, which
+    can be used by passing a `InternetAddress` of `InternetAddressType.Unix`
+    into the `connect()`, `startConnect()` and `bind()` methods. The `port`
+    argument in those methods will be ignored. The `port` getter always returns
+    0 for Unix domain sockets.
 
-* Class `InternetAddress`:
-  * `InternetAddress` constructor gains an optional `type` parameter. To create
-    a Unix domain address, `type` is set to `InternetAddressType.Unix` and
-    `address` is a file path.
-  * `InternetAddress` gains a new constructor `fromRawAddress` that takes an
-    address in byte format for Internet addresses or raw file path for Unix
-    domain addresses.
+*   Class `InternetAddressType` gains one more option `Unix`, which represents a
+    Unix domain address.
+
+*   Class `InternetAddress`:
+
+    *   `InternetAddress` constructor gains an optional `type` parameter. To
+        create a Unix domain address, `type` is set to
+        `InternetAddressType.Unix` and `address` is a file path.
+
+    *   `InternetAddress` gains a new constructor `fromRawAddress()` that takes
+        an address in byte format for Internet addresses or raw file path for
+        Unix domain addresses.
+
+*   **Breaking change** [#40681][]: The static methods `runZoned()` and
+    `runWithHttpOverrides()` on `HttpOverrides` no longer accept
+    `zoneSpecification` and `onError` parameters. Use the `runZoned()` or
+    `runZonedGuarded()` functions from `dart:async` directly if needing to
+    specify those.
+
+*   **Breaking change** [#40681][]: The static method `runZoned()` and
+    `runWithIOOverrides` on `IOOverrides` no longer accepts `zoneSpecification`
+    and `onError` parameters. Use the `runZoned()` or `runZonedGuarded()`
+    functions from `dart:async` directly if needing to specify those.
+
+[#33501]: https://github.com/dart-lang/sdk/issues/33501
+[#40702]: https://github.com/dart-lang/sdk/issues/40702
+[#40483]: https://github.com/dart-lang/sdk/issues/40483
+[#40706]: https://github.com/dart-lang/sdk/issues/40706
+[#40709]: https://github.com/dart-lang/sdk/issues/40709
+[RFC 7230 tokens]: https://tools.ietf.org/html/rfc7230#section-3.2.6
+[Unix domain sockets]: https://en.wikipedia.org/wiki/Unix_domain_socket
 
 #### `dart:mirrors`
 
-* Added `MirrorSystem.neverType`.
+*   Added `MirrorSystem.neverType`.
 
 ### Dart VM
 
-* Added `Dart_TypeDynamic`, `Dart_TypeVoid` and `Dart_TypeNever`. Type dynamic
-  can no longer by reached by `Dart_GetType(dart:core, dynamic)`.
-* Added the following methods to the VM embedding API:
-  * `Dart_GetNonNullableType`
-  * `Dart_GetNullableType`
-  * `Dart_TypeToNonNullable`
-  * `Dart_TypeToNullable`
-  * `Dart_IsLegacyType`
-  * `Dart_IsNonNullableType`
-  * `Dart_IsNullableType`
+*   Added `Dart_TypeDynamic`, `Dart_TypeVoid` and `Dart_TypeNever`. Type
+    `dynamic` can no longer by reached using `Dart_GetType(dart:core, dynamic)`.
+
+*   Added the following methods to the VM embedding API:
+
+    * `Dart_GetNonNullableType()`
+    * `Dart_GetNullableType()`
+    * `Dart_TypeToNonNullable()`
+    * `Dart_TypeToNullable()`
+    * `Dart_IsLegacyType()`
+    * `Dart_IsNonNullableType()`
+    * `Dart_IsNullableType()`
 
 ### Foreign Function Interface (`dart:ffi`)
 
-* **Breaking Change**: `Pointer.asFunction` and `DynamicLibrary.lookupFunction`
-  changed to extension methods. Invoking them dynamically previously already
-  threw an Exception, so runtime behavior stays the same. However, the
-  extension methods are only visible if `dart:ffi` is imported directly. So
-  this breaks code where `dart:ffi` is not directly imported. Fix: add an
-  import of `dart:ffi`.
+*   **Breaking Change**: Changed `Pointer.asFunction()` and
+    `DynamicLibrary.lookupFunction()` to extension methods. Invoking them
+    dynamically previously already threw an exception, so the runtime behavior
+    stays the same. However, the extension methods are only visible if
+    `dart:ffi` is imported directly. This breaks code where `dart:ffi` is not
+    directly imported. To fix, add:
+
+    ```dart
+    import 'dart:ffi';
+    ```
 
 ### Tools
 
 #### Dart Dev Compiler (DDC)
 
-* **Breaking Change**: Deleted the legacy (analyzer based) version of DDC. For
-additional details see the [announcement].
-  * The `--kernel` option is now ignored and defaults to true. There is no
-    longer any way to invoke the legacy (analyzer based) version of DDC.
-  * Command line arguments that were only used for the legacy DDC have been
-    removed.
-  * The pre-compiled ddc_sdk.js artifacts generated by legacy DDC have
-    been deleted from `dart-sdk/lib/dev_compiler` in favor of the versions
-    located at `dart-sdk/lib/dev_compiler/kernel`.
-* **Breaking Change**: Functions passed to JavaScript using the recommended
-  `package:js` interop specification must now be wrapped with a call to
-  `allowInterop`. This behavior was always enforced by `dart2js`, but was not
-  enforced consistently in `ddc`. It will now be enforced in both.
-* **Breaking Change**: Constructors in `@JS()` classes must be marked with
-  `external`. Previously the external could be omitted in some cases with DDC
-  but doing so would cause incorrect behavior with `dart2js`.
-* JS interop classes with an index operator are now static errors.
-* All remaining support from the `dart:mirrors` library has been removed.
-  Use of this library on the web has been unsupported and prevented by the Dart
-  build systems since Dart v2.0.0. All known exception cases have been cleaned
-  up. This change makes DDC and dart2js now behave consistently.
-  
-  The library can still be imported on web apps, but all APIs throw. In a future
-  breaking change release, imports to this library will likely become a
-  compile-time error.
+We fixed several inconsistencies between DDC and Dart2JS so that users less
+frequently encounter code that is accepted by one compiler but then fails in the
+other.
 
- [announcement]: https://github.com/dart-lang/sdk/issues/38994
+*   **Breaking Change**: Deleted the legacy (analyzer based) version of DDC. For
+    additional details see the [announcement][ddc].
+
+    *   The `--kernel` option is now ignored and defaults to true. There is no
+        longer any way to invoke the legacy (analyzer based) version of DDC.
+
+    *   Command line arguments that were only used for the legacy DDC have been
+        removed.
+
+    *   The pre-compiled `dart_sdk.js` artifacts generated by legacy DDC have
+        been deleted from `dart-sdk/lib/dev_compiler` in favor of the versions
+        located at `dart-sdk/lib/dev_compiler/kernel`.
+
+*   **Breaking Change**: Functions passed to JavaScript using the recommended
+    `package:js` interop specification must now be wrapped with a call to
+    `allowInterop`. This behavior was always enforced by Dart2JS, but was not
+    enforced consistently by DDC. It is now enforced by both.
+
+*   **Breaking Change**: Constructors in `@JS()` classes must be marked with
+    `external`. Previously the `external` could be omitted in some cases with
+    DDC but doing so would cause incorrect behavior with Dart2JS.
+
+*   JS interop classes with an index operator are now static errors.
+
+*   All remaining support from the `dart:mirrors` library has been removed. Use
+    of this library on the web has been unsupported and prevented by the Dart
+    build systems since Dart v2.0.0. All known exception cases have been cleaned
+    up. This change makes DDC and Dart2JS now behave consistently.
+
+    The library can still be imported on web apps, but all APIs throw. In a
+    future breaking change release, imports to this library will likely become a
+    compile-time error.
+
+[ddc]: https://github.com/dart-lang/sdk/issues/38994
 
 #### Dart2JS
 
-* JS interop classes with an index operator are now static errors instead of
-  causing invalid code in dart2js.
-* **Breaking Change**: The subtyping rule for generic functions is now more
-  forgiving. Corresponding type parameter bounds now only need to be mutual
-  subtypes rather than structurally equal up to renaming of bound type variables
-  and equating all top types.
-* **Breaking Change**: Types are now normalized. See [normalization] for the
-  full specification. Types will now be printed in their normal form, and
-  mutual subtypes with the same normal form will now be considered equal.
-* **Breaking Change**: Constructors in `@JS()` classes must be marked with
-  `external`. Previously the external could be omitted for unused constructors.
-  Omitting `external` for a constructor which is used would cause incorrect
-  behavior at runtime, now omitting it on any constructor is a static error.
-
- [normalization]: https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
-
-#### Linter
-
-The Linter was updated to `0.1.113`, which includes:
-
-* updated documentation links
-* `one_member_abstracts` updated to not lint classes with mixins or implementing interfaces
-* `unnecessary_getters_setters` fixed to ignore cases where a getter/setter is deprecated
-* new lint: `leading_newlines_in_multiline_strings`
-* improved highlight ranges for `avoid_private_typedef_functions` and `avoid_returning_null_for_future`
-
-#### Analyzer
-
- * Removed support for the deprecated analysis options file name `.analysis_options`.
-
-#### Pub
-
-* Added `pub outdated` command which lists outdated package dependencies, and
-  gives advice on how to upgrade.
-
-* `pub get` and `pub upgrade` now fetches version information about hosted
-  dependencies in parallel, improving the time package resolution performance.
-
-* `pub get` and `pub upgrade` no longer precompiles executables from
-  dependencies by default. Instead they are precompiled on first `pub run`.
-  Use `pub get --precompile` to get the previous behavior.
-
-* Fixed missing retries of DNS failures during `pub get`.
-
-* Importing packages not in `pubspec.yaml` now causes `pub publish` to reject
-  the package.
-
-* `pub publish` no longer requires the presence of a `homepage` field, if the
-  `repository` field is provided.
-
-* `pub publish` will now warn if non-pre-release packages depends on pre-release
-  packages or pre-release Dart SDKs.
-
-* Relative paths in `pubspec.lock` are now using `/` also on Windows to make
-  the file sharable between machines.
-
-* Fixed language version in [`.dart_tool/package_config.json`](https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md)
-  for packages without an explicit sdk constraint.
-
-  Now writes an empty language-version while before the language version of the
-  current sdk would be used.
-
-* `%LOCALAPPDATA%` is now preferred over `%APPDATA%` when creating a pub cache
-  directory on Windows. `%LOCALAPPDATA%` is not copied when users roam between
-  devices.
-
-#### dart2js
-
-A new representation of runtime types was enabled by default.
+A new representation of runtime types is enabled by default.
 
 This change is part of a long term goal of making runtime checks cheaper and
 more flexible for upcoming changes in the language. The new representation
 disentangles how types and classes are represented and makes types first-class
-to the compiler.  This makes it possible to do certain kind of optimizations on
+to the compiler. This makes it possible to do certain kind of optimizations on
 type checks that were not possible before and will enable us to model
 non-nullable types in the near future.
 
 This change should not affect the semantics of your application, but it has some
 relatively small visible effects that we want to highlight:
 
-* Types are now canonicalized, this fixes a long standing bug that Types could
-  not be used in switch cases (issue [17207][]).
+*   Types are now canonicalized, this fixes a long standing bug that Types could
+    not be used in switch cases (issue [17207][]).
 
-* Code-size changes may be visible, but the difference is small overall. It is
-  more visible on smaller apps because the new implementation includes more
-  helper methods. On large apps we have even seen an overall code-size
-  reduction.
+*   Code-size changes may be visible, but the difference is small overall. It is
+    more visible on smaller apps because the new implementation includes more
+    helper methods. On large apps we have even seen an overall code-size
+    reduction.
 
-* Certain checks are a lot faster.  This is less noticeable if you are compiling
-  apps with `-O3` where checks are omitted altogether. Even with `-O3`, the
-  performance of some `is` checks used by your app may improve.
+*   Certain checks are a lot faster.  This is less noticeable if you are
+    compiling apps with `-O3` where checks are omitted altogether. Even with
+    `-O3`, the performance of some `is` checks used by your app may improve.
 
-* When using `-O3` and `-O4` incorrect type annotations could surface as errors.
-  The old type representation was accidentally lenient on some invalid type
-  annotations. We have only encountered this issue on programs that were not
-  tested properly at the js-interop program boundary.
+*   When using `-O3` and `-O4` incorrect type annotations could surface as
+    errors. The old type representation was accidentally lenient on some invalid
+    type annotations. We have only encountered this issue on programs that were
+    not tested properly at the js-interop program boundary.
 
-* `Type.toString` has a small change that is rarely visible. For a long time
-  dart2js has had support to erase unused type variables. Today, when dart2js is
-  given `--lax-runtime-type-to-string` (currently included in `-O2`, `-O3`, and
-  `-O4`) and it decides to erase the type variable of a class `Foo<T>`, then it
-  compiles expressions like `foo.runtimeType.toString()` to print `Foo`. With
-  the new representation, this will show `Foo<erased>` instead. This change may
-  be visible in error messages produced by type checks involving erased types.
+*   `Type.toString()` has a small change that is rarely visible. For a long
+    time, Dart2JS has had support to erase unused type variables. Today, when
+    Dart2JS is given `--lax-runtime-type-to-string` (currently included in
+    `-O2`, `-O3`, and `-O4`) and it decides to erase the type variable of a
+    class `Foo<T>`, then it compiles expressions like
+    `foo.runtimeType.toString()` to print `Foo`. With the new representation,
+    this will show `Foo<erased>` instead. This change may be visible in error
+    messages produced by type checks involving erased types.
 
 Because types and classes are represented separately, we will likely reevaluate
 restrictions of deferred libraries in the near future. For example, we could
@@ -309,22 +306,100 @@
 
 In the unlikely case you run into any issues, please file a bug so we can
 investigate. You can temporarily force the old type representation by passing
-`--use-old-rti` to dart2js if necessary, but our goal is to delete the old type
+`--use-old-rti` to Dart2JS if necessary, but our goal is to delete the old type
 representation soon.
 
+In addition, we fixed some inconsistencies between Dart2JS and DDC:
+
+*   JS interop classes with an index operator are now static errors instead of
+    causing invalid code in Dart2JS.
+
+*   **Breaking Change**: The subtyping rule for generic functions is now more
+    forgiving. Corresponding type parameter bounds now only need to be mutual
+    subtypes rather than structurally equal up to renaming of bound type
+    variables and equating all top types.
+
+*   **Breaking Change**: Types are now normalized. See [normalization] for the
+    full specification. Types will now be printed in their normal form, and
+    mutual subtypes with the same normal form will now be considered equal.
+
+*   **Breaking Change**: Constructors in `@JS()` classes must be marked with
+    `external`. Previously, the external could be omitted for unused
+    constructors. Omitting `external` for a constructor which is used would
+    cause incorrect behavior at runtime, now omitting it on any constructor is a
+    static error.
 
 [17207]: https://github.com/dart-lang/sdk/issues/17207
 
+[normalization]: https://github.com/dart-lang/language/blob/master/resources/type-system/normalization.md
+
+#### Linter
+
+Updated the Linter to `0.1.114`, which includes:
+
+* Fixed `avoid_shadowing_type_parameters` to support extensions and mixins.
+* Updated `non_constant_identifier_names` to allow named constructors made up of only underscores (`_`).
+* Updated `avoid_unused_constructor_parameters` to ignore unused params named in all underscores (`_`).
+
+#### Analyzer
+
+*   Removed support for the deprecated analysis options file name
+    `.analysis_options`.
+
+#### Pub
+
+*   Added `pub outdated` command which lists outdated package dependencies, and
+    gives advice on how to upgrade.
+
+*   `pub get` and `pub upgrade` now fetch version information about hosted
+    dependencies in parallel, improving the time package resolution performance.
+
+*   `pub get` and `pub upgrade` no longer precompile executables from
+    dependencies by default. Instead they are precompiled on first `pub run`.
+    Use `pub get --precompile` to get the previous behavior.
+
+*   Fixed missing retries of DNS failures during `pub get`.
+
+*   If code contains imports for packages not listed in the package's
+    `pubspec.yaml` then `pub publish` will reject the package.
+
+*   `pub publish` no longer requires the presence of a `homepage` field, if the
+    `repository` field is provided.
+
+*   `pub publish` warns if non-pre-release packages depends on pre-release
+    packages or pre-release Dart SDKs.
+
+*   Relative paths in `pubspec.lock` now use `/` also on Windows to make the
+    file sharable between machines.
+
+*   Fixed language version in [`.dart_tool/package_config.json`][package config]
+    for packages without an explicit SDK constraint. Pub now writes an empty
+    language version where before the language version of the current SDK would
+    be used.
+
+*   `%LOCALAPPDATA%` is now preferred over `%APPDATA%` when creating a pub cache
+    directory on Windows. `%LOCALAPPDATA%` is not copied when users roam between
+    devices.
+
+*   `pub publish` warns if LICENSE and README.md files are not called those
+    exact names.
+
+*   `pub repair cache` downloads hosted packages in parallel.
+
+[package config]: https://github.com/dart-lang/language/blob/master/accepted/future-releases/language-versioning/package-config-file-v2.md
+
 ## 2.7.2 - 2020-03-23
 
-This is a patch release that addresses a vulnerability dart:html
-[NodeValidator](https://api.dart.dev/stable/dart-html/NodeValidator-class.html)
-related to DOM clobbering of `previousSibling`. Thanks to **Vincenzo di Cicco**
-for finding and reporting this issue.
+This is a patch release that addresses a vulnerability in `dart:html`
+[NodeValidator][] related to DOM clobbering of `previousSibling`. See the
+[vulnerability advisory][CVE-2020-8923] for more details. Thanks to **Vincenzo
+di Cicco** for finding and reporting this issue.
 
-This release also improves compatibility with ARMv8 processors
-(issue [40001][]) and dart:io stability (issue [40589][]).
+This release also improves compatibility with ARMv8 processors (issue [40001][])
+and dart:io stability (issue [40589][]).
 
+[NodeValidator]: https://api.dart.dev/stable/dart-html/NodeValidator-class.html
+[CVE-2020-8923]: https://github.com/dart-lang/sdk/security/advisories/GHSA-hfq3-v9pv-p627
 [40001]: https://github.com/dart-lang/sdk/issues/40001
 [40589]: https://github.com/dart-lang/sdk/issues/40589
 
diff --git a/DEPS b/DEPS
index 9a6d8c6..bf0cb23 100644
--- a/DEPS
+++ b/DEPS
@@ -39,7 +39,7 @@
   # co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
   # hashes. It requires access to the dart-build-access group, which EngProd
   # has.
-  "co19_rev": "51ee35d0459ad329287254b79ed3918d78b5bbf3",
+  "co19_rev": "b9efaddfe0553b6937bf625157f6a13498951346",
   "co19_2_rev": "368bfa9e877a2df003547f64bb17e30596af10c7",
 
   # As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
@@ -102,7 +102,7 @@
   "intl_tag": "0.16.1",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "2.0.9",
-  "linter_tag": "0.1.113",
+  "linter_tag": "0.1.114",
   "logging_tag": "0.11.3+2",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
   "markdown_tag": "2.1.1",
@@ -112,14 +112,14 @@
   "mustache_tag" : "5e81b12215566dbe2473b2afd01a8a8aedd56ad9",
   "oauth2_tag": "1.2.1",
   "observatory_pub_packages_rev": "0894122173b0f98eb08863a7712e78407d4477bc",
-  "package_config_tag": "87a8b5184020ebcc13b34ee95dde58f851b68ca3", # should be 1.9.0
+  "package_config_tag": "v1.9.2",
   "package_resolver_tag": "1.0.10",
   "path_tag": "1.6.2",
   "pedantic_tag": "v1.8.0",
   "ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_tag": "1.3.6",
   "protobuf_rev": "3746c8fd3f2b0147623a8e3db89c3ff4330de760",
-  "pub_rev": "11afdac99fe67373829f37acc75b625011d360ad",
+  "pub_rev": "ab109723d9eb782c2ea4cce68c044da40403a652",
   "pub_semver_tag": "v1.4.4",
   "quiver-dart_tag": "2.0.0+1",
   "resource_rev": "f8e37558a1c4f54550aa463b88a6a831e3e33cd6",
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index b4145ba..6d61428 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -435,6 +435,61 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+    templateCannotAssignToConstVariable =
+    const Template<Message Function(String name)>(
+        messageTemplate: r"""Can't assign to the const variable '#name'.""",
+        withArguments: _withArgumentsCannotAssignToConstVariable);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeCannotAssignToConstVariable =
+    const Code<Message Function(String name)>(
+  "CannotAssignToConstVariable",
+  templateCannotAssignToConstVariable,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsCannotAssignToConstVariable(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeCannotAssignToConstVariable,
+      message: """Can't assign to the const variable '${name}'.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeCannotAssignToExtensionThis =
+    messageCannotAssignToExtensionThis;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageCannotAssignToExtensionThis = const MessageCode(
+    "CannotAssignToExtensionThis",
+    message: r"""Can't assign to 'this'.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+    templateCannotAssignToFinalVariable =
+    const Template<Message Function(String name)>(
+        messageTemplate: r"""Can't assign to the final variable '#name'.""",
+        withArguments: _withArgumentsCannotAssignToFinalVariable);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeCannotAssignToFinalVariable =
+    const Code<Message Function(String name)>(
+  "CannotAssignToFinalVariable",
+  templateCannotAssignToFinalVariable,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsCannotAssignToFinalVariable(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeCannotAssignToFinalVariable,
+      message: """Can't assign to the final variable '${name}'.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeCannotAssignToParenthesizedExpression =
     messageCannotAssignToParenthesizedExpression;
 
@@ -454,6 +509,15 @@
     message: r"""Can't assign to super.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeCannotAssignToTypeLiteral =
+    messageCannotAssignToTypeLiteral;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageCannotAssignToTypeLiteral = const MessageCode(
+    "CannotAssignToTypeLiteral",
+    message: r"""Can't assign to a type literal.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String string)>
     templateCannotReadSdkSpecification =
     const Template<Message Function(String string)>(
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
index 9a2abc6..0ab3ed5 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
@@ -461,6 +461,29 @@
 }
 
 /**
+ * A specialized comment token representing a language version
+ * (e.g. '// @dart = 2.1').
+ */
+class LanguageVersionToken extends CommentToken {
+  /**
+   * The major language version.
+   */
+  final int major;
+
+  /**
+   * The minor language version.
+   */
+  final int minor;
+
+  LanguageVersionToken.from(String text, int offset, this.major, this.minor)
+      : super(TokenType.SINGLE_LINE_COMMENT, text, offset);
+
+  @override
+  LanguageVersionToken copy() =>
+      new LanguageVersionToken.from(lexeme, offset, major, minor);
+}
+
+/**
  * A token that was scanned from the input. Each token knows which tokens
  * precede and follow it, acting as a link in a doubly linked list of tokens.
  */
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/token_impl.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/token_impl.dart
index 11187f7..12cdd53 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/token_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/token_impl.dart
@@ -187,19 +187,12 @@
   }
 }
 
-/**
- * A specialized comment token representing a language version
- * (e.g. '// @dart = 2.1').
- */
-class LanguageVersionToken extends CommentToken {
-  /**
-   * The major language version.
-   */
+class LanguageVersionToken extends CommentToken
+    implements analyzer.LanguageVersionToken {
+  @override
   int major;
 
-  /**
-   * The minor language version.
-   */
+  @override
   int minor;
 
   LanguageVersionToken.from(String text, int offset, this.major, this.minor)
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index a86a695..a2dd3bf 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -44,6 +44,7 @@
 import 'package:analysis_server/src/server/diagnostic_server.dart';
 import 'package:analysis_server/src/server/error_notifier.dart';
 import 'package:analysis_server/src/server/features.dart';
+import 'package:analysis_server/src/server/sdk_configuration.dart';
 import 'package:analysis_server/src/services/flutter/widget_descriptions.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
@@ -311,7 +312,7 @@
   /// Handle a [request] that was read from the communication channel.
   void handleRequest(Request request) {
     performance.logRequestTiming(request.clientRequestTime);
-    runZoned(() {
+    runZonedGuarded(() {
       ServerPerformanceStatistics.serverRequests.makeCurrentWhile(() {
         int count = handlers.length;
         for (int i = 0; i < count; i++) {
@@ -340,7 +341,7 @@
         }
         channel.sendResponse(Response.unknownRequest(request));
       });
-    }, onError: (exception, stackTrace) {
+    }, (exception, stackTrace) {
       AnalysisEngine.instance.instrumentationService.logException(
           FatalException('Failed to handle request: ${request.method}',
               exception, stackTrace));
@@ -723,6 +724,12 @@
   /// should be accessed via a null-aware operator.
   CrashReportSender crashReportSender;
 
+  /// An optional set of configuration overrides specified by the SDK.
+  ///
+  /// These overrides can provide new values for configuration settings, and are
+  /// generally used in specific SDKs (like the internal google3 one).
+  SdkConfiguration configurationOverrides;
+
   /// The list of the names of the experiments that should be enabled by
   /// default, unless the analysis options file of a context overrides it.
   List<String> enabledExperiments = const <String>[];
diff --git a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
index 343f98a..57bf820 100644
--- a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
+++ b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
@@ -144,9 +144,9 @@
 
   /// Send the string [s] to [_output] followed by a newline.
   void _outputLine(String s) {
-    runZoned(() {
+    runZonedGuarded(() {
       _output.writeln(s);
-    }, onError: (e) {
+    }, (e, s) {
       close();
     });
   }
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index dd193c4..d4f6632 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -217,7 +217,7 @@
       );
     }
 
-    return runZoned(() {
+    return runZonedGuarded(() {
       String requestName = request.method;
 
       if (requestName == COMPLETION_REQUEST_GET_SUGGESTION_DETAILS) {
@@ -233,7 +233,7 @@
         return setSubscriptions(request);
       }
       return null;
-    }, onError: (exception, stackTrace) {
+    }, (exception, stackTrace) {
       AnalysisEngine.instance.instrumentationService.logException(
           CaughtException.withMessage(
               'Failed to handle completion domain request: ${request.method}',
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 9a8a5ae..fb240a1 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -942,7 +942,7 @@
           ?.sendEvent('refactor', params.kind.name.toLowerCase());
     }
 
-    runZoned(() async {
+    runZonedGuarded(() async {
       // TODO(brianwilkerson) Determine whether this await is necessary.
       await null;
       await _init(params.kind, file, params.offset, params.length);
@@ -990,7 +990,7 @@
       _checkForReset_afterCreateChange();
       result.potentialEdits = nullIfEmpty(refactoring.potentialEditIds);
       _sendResultResponse();
-    }, onError: (exception, stackTrace) {
+    }, (exception, stackTrace) {
       if (exception is _ResetError ||
           exception is InconsistentAnalysisException) {
         cancel();
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
index f006600..bd289f3 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
@@ -468,6 +468,7 @@
       case NullabilityFixKind.discardThen:
       case NullabilityFixKind.removeAs:
       case NullabilityFixKind.removeNullAwareness:
+      case NullabilityFixKind.removeLanguageVersionComment:
         // There's no need for hints around code that is being removed.
         break;
       case NullabilityFixKind.makeTypeNullable:
@@ -516,11 +517,6 @@
     }
     assert(identical(step.node, node));
     while (step != null) {
-      if (step.node == info.never) {
-        // Assert that we are only ever trimming off the last step.
-        assert(step.principalCause == null);
-        break;
-      }
       entries.add(_nodeToTraceEntry(step.node));
       if (step.codeReference != null) {
         entries.add(_stepToTraceEntry(step));
@@ -541,12 +537,6 @@
     assert(identical(step.targetNode, node));
     while (step != null) {
       entries.add(_nodeToTraceEntry(step.targetNode));
-      if (step.targetNode.upstreamEdges.isNotEmpty &&
-          step.targetNode.upstreamEdges.first.sourceNode == info.always) {
-        // Assert that we are only ever trimming off the last step.
-        assert(step.principalCause == null);
-        break;
-      }
       if (step.codeReference != null) {
         entries.add(_stepToTraceEntry(step));
       }
@@ -743,7 +733,8 @@
   }
 
   TraceEntryInfo _stepToTraceEntry(PropagationStepInfo step) {
-    var description = step.toString(); // TODO(paulberry): improve this message.
+    String description = step.edge?.description;
+    description ??= step.toString(); // TODO(paulberry): improve this message.
     return _makeTraceEntry(description, step.codeReference);
   }
 
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart
index 1a941df..a974261 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/resources/resources.g.dart
@@ -434,7 +434,7 @@
 ''';
 
 String _migration_js;
-// migration_dart md5 is '6520368a5d56a6a3d8049dbc6ac1b17f'
+// migration_dart md5 is '847799fe43f4af04fec9d5e63d69e6da'
 String _migration_js_base64 = '''
 KGZ1bmN0aW9uIGRhcnRQcm9ncmFtKCl7ZnVuY3Rpb24gY29weVByb3BlcnRpZXMoYSxiKXt2YXIgdD1P
 YmplY3Qua2V5cyhhKQpmb3IodmFyIHM9MDtzPHQubGVuZ3RoO3MrKyl7dmFyIHI9dFtzXQpiW3JdPWFb
@@ -1828,2119 +1828,2119 @@
 dWxsKUouZFIocy5wYXJlbnRFbGVtZW50KS5SKDAsImhpZ2hsaWdodCIpfWlmKGE9PXdpbmRvdy5sb2Nh
 dGlvbi5wYXRobmFtZSl7TC5mRyhiLGMpCmUuJDAoKX1lbHNlIEwuRzcoYSxiLGMsZCxlKX0sCkx4OmZ1
 bmN0aW9uKGEsYil7dmFyIHQKaWYoYT09PTEpdD1iCmVsc2UgdD1iKyJzIgpyZXR1cm4gdH0sClQxOmZ1
-bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG09JC5oTCgpCkoubDUobSwiIikKaWYoYT09bnVsbCl7
-dD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJwIikKdC50ZXh0Q29udGVudD0iU2VlIGRldGFpbHMgYWJv
-dXQgYSBwcm9wb3NlZCBlZGl0LiIKQy5MdC5zRCh0LEguVk0oWyJwbGFjZWhvbGRlciJdLHUucykpCm0u
-YXBwZW5kQ2hpbGQodCkKcmV0dXJufXM9YS5lCnQ9JC5uVSgpCnI9dC50TShzKQpxPWEuYwpwPWRvY3Vt
-ZW50Cm89dC5IUChzLEouVDAocC5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50KSkKbj1h
-LmQKdD1wLmNyZWF0ZUVsZW1lbnQoInAiKQp1LmguYihtLmFwcGVuZENoaWxkKHQpKS5hcHBlbmRDaGls
-ZChwLmNyZWF0ZVRleHROb2RlKEguZChxKSsiIGF0ICIrSC5kKG8pKyI6IitILmQobikrIi4iKSkKTC5D
-QyhhLG0scikKTC5GeihhLG0pCkwuTkcoYSxtLHIpfSwKTEg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMs
-cixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQ9JC5tUSgpCkoubDUoZCwiIikKdD1kb2N1bWVudApz
-PXQuY3JlYXRlRWxlbWVudCgicCIpCnI9dS5oCnE9ci5iKGQuYXBwZW5kQ2hpbGQocykpCnA9Yi5sZW5n
-dGgKaWYocD09PTApcS5hcHBlbmRDaGlsZCh0LmNyZWF0ZVRleHROb2RlKCJObyBwcm9wb3NlZCBlZGl0
-cyIpKQplbHNlIHEuYXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9kZSgiIitwKyIgcHJvcG9zZWQgIitM
-Lkx4KHAsImVkaXQiKSsiOiIpKQpzPXQuY3JlYXRlRWxlbWVudCgidWwiKQpvPXIuYihkLmFwcGVuZENo
-aWxkKHMpKQpmb3IoZD1iLmxlbmd0aCxzPXUuaSxuPXUuUSxtPW4uQygifigxKSIpLGw9dS5NLG49bi5k
-LGs9MDtrPGIubGVuZ3RoO2IubGVuZ3RoPT09ZHx8KDAsSC5saykoYiksKytrKXtqPWJba10KaT10LmNy
-ZWF0ZUVsZW1lbnQoImxpIikKaD1yLmIoby5hcHBlbmRDaGlsZChpKSkKSi5kUihoKS5pKDAsImVkaXQi
-KQppPXQuY3JlYXRlRWxlbWVudCgiYSIpCmc9cy5iKGguYXBwZW5kQ2hpbGQoaSkpCmcuY2xhc3NMaXN0
-LmFkZCgiZWRpdC1saW5rIikKZj1qLmMKaT1ILmQoZikKZy5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcg
-Vy5TeShuZXcgVy5pNyhnKSkuTygib2Zmc2V0IiksaSkKZT1qLmEKaT1ILmQoZSkKZy5zZXRBdHRyaWJ1
-dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhnKSkuTygibGluZSIpLGkpCmcuYXBwZW5kQ2hpbGQo
-dC5jcmVhdGVUZXh0Tm9kZSgibGluZSAiK0guZChlKSkpCmk9bS5iKG5ldyBMLkVFKGYsZSxhKSkKbC5i
-KG51bGwpClcuSkUoZywiY2xpY2siLGksITEsbikKaC5hcHBlbmRDaGlsZCh0LmNyZWF0ZVRleHROb2Rl
-KCI6ICIrSC5kKGouYikpKX1pZihjKUwuVDEobnVsbCl9LApGcjpmdW5jdGlvbihhLGIsYyl7dmFyIHQs
-cyxyLHE9d2luZG93LmxvY2F0aW9uLHA9UC5oSygocSYmQy5FeCkuZ0RyKHEpK0guZChhKSkKcT11LnoK
-dD1QLkZsKHUuTixxKQppZihiIT1udWxsKXQuWSgwLCJvZmZzZXQiLEguZChiKSkKaWYoYyE9bnVsbCl0
-LlkoMCwibGluZSIsSC5kKGMpKQpwPXAubm0oMCx0LmE9PT0wP251bGw6dCkKcz13aW5kb3cuaGlzdG9y
-eQpyPXAudygwKQpzLnRvU3RyaW5nCnMucHVzaFN0YXRlKG5ldyBQLkJmKFtdLFtdKS5QdihQLkZsKHEs
-cSkpLCIiLHIpfSwKRW46ZnVuY3Rpb24oYSl7dmFyIHQ9Si5iYihkb2N1bWVudC5xdWVyeVNlbGVjdG9y
-KCIucm9vdCIpLnRleHRDb250ZW50LCIvIikKaWYoQy54Qi5uKGEsdCkpcmV0dXJuIEMueEIuRyhhLHQu
-bGVuZ3RoKQplbHNlIHJldHVybiBhfSwKQlg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9e30Kci5hPWEK
-YT1MLkVuKGEpCnIuYT1hCiQuRDkoKS50ZXh0Q29udGVudD1hCnQ9ZG9jdW1lbnQKcz11LmgKSC5EaChz
-LHMsIlQiLCJxdWVyeVNlbGVjdG9yQWxsIikKdD1uZXcgVy53eih0LnF1ZXJ5U2VsZWN0b3JBbGwoIi5u
-YXYtcGFuZWwgLm5hdi1saW5rIiksdS5TKQp0LksodCxuZXcgTC5WUyhyKSl9LApCRTpmdW5jdGlvbihh
-LGIsYyl7dmFyIHQ9Ii5yZWdpb25zIixzPWRvY3VtZW50LHI9cy5xdWVyeVNlbGVjdG9yKHQpLHE9cy5x
-dWVyeVNlbGVjdG9yKCIuY29kZSIpCkoudEgocixiLmEsJC5LRygpKQpKLnRIKHEsYi5iLCQuS0coKSkK
-TC5MSChhLGIuZCxjKQpMLnZVKCkKTC55WCgiLmNvZGUiLCEwKQpMLnlYKHQsITApfSwKdFg6ZnVuY3Rp
-b24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGk9ZG9jdW1lbnQsaD1pLmNyZWF0ZUVsZW1l
-bnQoInVsIiksZz11LmgsZj1nLmIoYS5hcHBlbmRDaGlsZChoKSkKZm9yKGg9Yi5sZW5ndGgsdD11Lk0s
-cz0wO3M8Yi5sZW5ndGg7Yi5sZW5ndGg9PT1ofHwoMCxILmxrKShiKSwrK3Mpe3I9YltzXQpxPWkuY3Jl
-YXRlRWxlbWVudCgibGkiKQpwPWcuYihmLmFwcGVuZENoaWxkKHEpKQpxPUouUkUocCkKaWYoci5hPT09
-Qy5ZMil7cS5nRChwKS5pKDAsImRpciIpCnE9aS5jcmVhdGVFbGVtZW50KCJzcGFuIikKbz1nLmIocC5h
-cHBlbmRDaGlsZChxKSkKcT1KLlJFKG8pCnEuZ0QobykuaSgwLCJhcnJvdyIpCnEuc2hmKG8sIiYjeDI1
-QkM7IikKcT1pLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpKLmw1KGcuYihwLmFwcGVuZENoaWxkKHEpKSwi
-JiN4MUY0QzE7IikKcC5hcHBlbmRDaGlsZChpLmNyZWF0ZVRleHROb2RlKHIuYikpCkwudFgocCxyLmMp
-Ckwua3oobyl9ZWxzZXtxLnNoZihwLCImI3gxRjRDNDsiKQpxPWkuY3JlYXRlRWxlbWVudCgiYSIpCm49
-Zy5iKHAuYXBwZW5kQ2hpbGQocSkpCnE9Si5SRShuKQpxLmdEKG4pLmkoMCwibmF2LWxpbmsiKQpuLnNl
-dEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KG4pKS5PKCJuYW1lIiksci5kKQpuLnNl
-dEF0dHJpYnV0ZSgiaHJlZiIsci5lKQpuLmFwcGVuZENoaWxkKGkuY3JlYXRlVGV4dE5vZGUoci5iKSkK
-cT1xLmdWbChuKQptPXEuJHRpCmw9bS5DKCJ+KDEpIikuYihuZXcgTC5URCgpKQp0LmIobnVsbCkKVy5K
-RShxLmEscS5iLGwsITEsbS5kKQprPXIuZgppZih0eXBlb2YgayE9PSJudW1iZXIiKXJldHVybiBrLm9z
-KCkKaWYoaz4wKXtxPWkuY3JlYXRlRWxlbWVudCgic3BhbiIpCmo9Zy5iKHAuYXBwZW5kQ2hpbGQocSkp
-CkouZFIoaikuaSgwLCJlZGl0LWNvdW50IikKcT0iIitrKyIgIgppZihrPT09MSltPSJlZGl0IgplbHNl
-IG09ImVkaXRzIgpqLnNldEF0dHJpYnV0ZSgidGl0bGUiLHErbSkKai5hcHBlbmRDaGlsZChpLmNyZWF0
-ZVRleHROb2RlKEMuam4udyhrKSkpfX19fSwKYzQ6ZnVuY3Rpb24oYSxiKXt2YXIgdD1kb2N1bWVudCxz
-PXQuY3JlYXRlRWxlbWVudCgiYSIpCnUuaS5iKHMpCnMuYXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9k
-ZShILmQoYS5jKSsiOiIrSC5kKGEuYikpKQp0PUQubnIoYixhLmEpCnMuc2V0QXR0cmlidXRlKCJocmVm
-IiwkLm5VKCkubzUodCkpCnMuY2xhc3NMaXN0LmFkZCgibmF2LWxpbmsiKQpyZXR1cm4gc30sCkZ6OmZ1
-bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpPWEuYgppZihpIT1udWxsKWZvcih0
-PWkubGVuZ3RoLHM9dS5oLHI9dS5zLHE9dS5YLHA9MDtwPGkubGVuZ3RoO2kubGVuZ3RoPT09dHx8KDAs
-SC5saykoaSksKytwKXtvPWlbcF0Kbj1kb2N1bWVudAptPW4uY3JlYXRlRWxlbWVudCgicCIpCmw9cy5i
-KGIuYXBwZW5kQ2hpbGQobSkpCm09bi5jcmVhdGVFbGVtZW50KCJhIikKaz1zLmIobC5hcHBlbmRDaGls
-ZChtKSkKay5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKG8uYSkpCmsuc2V0QXR0cmlidXRlKCJo
-cmVmIixvLmIpCm49cS5iKEguVk0oWyJwb3N0LWxpbmsiLCJiZWZvcmUtYXBwbHkiXSxyKSkKaj1KLmRS
-KGspCmouVjEoMCkKai5GVigwLG4pfX0sCk5HOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8s
-bixtLGw9YS5hCmlmKGwubGVuZ3RoIT09MCl7dD1kb2N1bWVudApzPXQuY3JlYXRlRWxlbWVudCgicCIp
-CnMudGV4dENvbnRlbnQ9IkVkaXQgcmF0aW9uYWxlIChleHBlcmltZW50YWwpOiIKYi5hcHBlbmRDaGls
-ZChzKQpzPXQuY3JlYXRlRWxlbWVudCgidWwiKQpyPXUuaC5iKGIuYXBwZW5kQ2hpbGQocykpCmZvcihz
-PWwubGVuZ3RoLHE9MDtxPGwubGVuZ3RoO2wubGVuZ3RoPT09c3x8KDAsSC5saykobCksKytxKXtwPWxb
-cV0Kbz10LmNyZWF0ZUVsZW1lbnQoImxpIikKbj1yLmFwcGVuZENoaWxkKG8pCm4uYXBwZW5kQ2hpbGQo
-dC5jcmVhdGVUZXh0Tm9kZShwLmEpKQptPXAuYgppZihtIT1udWxsKXtuLmFwcGVuZENoaWxkKHQuY3Jl
-YXRlVGV4dE5vZGUoIiAoIikpCm4uYXBwZW5kQ2hpbGQoTC5jNChtLGMpKQpuLmFwcGVuZENoaWxkKHQu
-Y3JlYXRlVGV4dE5vZGUoIikiKSl9fX19LApDQzpmdW5jdGlvbihhLGIsYTApe3ZhciB0LHMscixxLHAs
-byxuLG0sbCxrLGosaSxoLGcsZixlLGQsYwpmb3IodD1hLmYscz10Lmxlbmd0aCxyPXUucyxxPXUuWCxw
-PTA7cDx0Lmxlbmd0aDt0Lmxlbmd0aD09PXN8fCgwLEgubGspKHQpLCsrcCl7bz10W3BdCm49ZG9jdW1l
-bnQKbT1uLmNyZWF0ZUVsZW1lbnQoInAiKQpsPXEuYihILlZNKFsidHJhY2UiXSxyKSkKaz1KLmRSKG0p
-CmsuVjEoMCkKay5GVigwLGwpCmo9Yi5hcHBlbmRDaGlsZChtKQptPW4uY3JlYXRlRWxlbWVudCgic3Bh
-biIpCmw9cS5iKEguVk0oWyJ0eXBlLWRlc2NyaXB0aW9uIl0scikpCms9Si5kUihtKQprLlYxKDApCmsu
-RlYoMCxsKQptLmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoby5hKSkKai5hcHBlbmRDaGlsZCht
-KQpqLmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoIjoiKSkKbT1uLmNyZWF0ZUVsZW1lbnQoInVs
-IikKbD1xLmIoSC5WTShbInRyYWNlIl0scikpCms9Si5kUihtKQprLlYxKDApCmsuRlYoMCxsKQppPWou
-YXBwZW5kQ2hpbGQobSkKZm9yKG09by5iLGw9bS5sZW5ndGgsaD0wO2g8bS5sZW5ndGg7bS5sZW5ndGg9
-PT1sfHwoMCxILmxrKShtKSwrK2gpe2c9bVtoXQpmPW4uY3JlYXRlRWxlbWVudCgibGkiKQpKLmw1KGYs
-IiYjeDI3NEY7ICIpCmU9aS5hcHBlbmRDaGlsZChmKQpmPW4uY3JlYXRlRWxlbWVudCgic3BhbiIpCmQ9
-cS5iKEguVk0oWyJmdW5jdGlvbiJdLHIpKQprPUouZFIoZikKay5WMSgwKQprLkZWKDAsZCkKZD1nLmIK
-aWYoZD09bnVsbClkPSJ1bmtub3duIgpmLmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoZCkpCmUu
-YXBwZW5kQ2hpbGQoZikKYz1nLmMKaWYoYyE9bnVsbCl7ZS5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHRO
-b2RlKCIgKCIpKQplLmFwcGVuZENoaWxkKEwuYzQoYyxhMCkpCmUuYXBwZW5kQ2hpbGQobi5jcmVhdGVU
-ZXh0Tm9kZSgiKSIpKX1lLmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUoIjogIikpCmUuYXBwZW5k
-Q2hpbGQobi5jcmVhdGVUZXh0Tm9kZShnLmEpKX19fSwKZTpmdW5jdGlvbiBlKCl7fSwKVlc6ZnVuY3Rp
-b24gVlcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKb1o6ZnVuY3Rpb24gb1ooKXt9
-LApqcjpmdW5jdGlvbiBqcigpe30sCnFsOmZ1bmN0aW9uIHFsKCl7fSwKTDpmdW5jdGlvbiBMKCl7fSwK
-V3g6ZnVuY3Rpb24gV3goYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkFPOmZ1bmN0aW9uIEFPKGEpe3Ro
-aXMuYT1hfSwKZE46ZnVuY3Rpb24gZE4oYSl7dGhpcy5hPWF9LApIbzpmdW5jdGlvbiBIbyhhKXt0aGlz
-LmE9YX0sCnh6OmZ1bmN0aW9uIHh6KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApJQzpmdW5jdGlvbiBJ
-Qygpe30sCkwxOmZ1bmN0aW9uIEwxKCl7fSwKblQ6ZnVuY3Rpb24gblQoYSxiLGMpe3RoaXMuYT1hCnRo
-aXMuYj1iCnRoaXMuYz1jfSwKQlo6ZnVuY3Rpb24gQlooYSl7dGhpcy5hPWF9LApHSDpmdW5jdGlvbiBH
-SCgpe30sCkRUOmZ1bmN0aW9uIERUKCl7fSwKZUg6ZnVuY3Rpb24gZUgoYSl7dGhpcy5hPWF9LAp6RDpm
-dW5jdGlvbiB6RChhLGIsYyxkLGUpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5l
-PWV9LApPRTpmdW5jdGlvbiBPRShhKXt0aGlzLmE9YX0sClRXOmZ1bmN0aW9uIFRXKCl7fSwKeHI6ZnVu
-Y3Rpb24geHIoYSl7dGhpcy5hPWF9LApFRTpmdW5jdGlvbiBFRShhLGIsYyl7dGhpcy5hPWEKdGhpcy5i
-PWIKdGhpcy5jPWN9LApRTDpmdW5jdGlvbiBRTChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKVlM6ZnVu
-Y3Rpb24gVlMoYSl7dGhpcy5hPWF9LApURDpmdW5jdGlvbiBURCgpe30sClhBOmZ1bmN0aW9uIFhBKCl7
-fSwKbUs6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG49SC5WTShbXSx1LmZoKQpmb3IodD1KLklU
-KHUuUi5iKGEpKTt0LkYoKTspe3M9dC5nbCgpCnI9Si5VNihzKQpxPUwucDIoSC55KHIucShzLCJ0eXBl
-IikpKQpwPUgueShyLnEocywibmFtZSIpKQpvPXIucShzLCJzdWJ0cmVlIikKbz1vPT1udWxsP251bGw6
-TC5tSyhvKQpDLk5tLmkobixuZXcgTC5aWihxLHAsbyxILnkoci5xKHMsInBhdGgiKSksSC55KHIucShz
-LCJocmVmIikpLEguU2Moci5xKHMsImVkaXRDb3VudCIpKSkpfXJldHVybiBufSwKcDI6ZnVuY3Rpb24o
-YSl7c3dpdGNoKGEpe2Nhc2UiZGlyZWN0b3J5IjpyZXR1cm4gQy5ZMgpjYXNlImZpbGUiOnJldHVybiBD
-LnJmCmRlZmF1bHQ6dGhyb3cgSC5iKFAuUFYoIlVucmVjb2duaXplZCBuYXZpZ2F0aW9uIHRyZWUgbm9k
-ZSB0eXBlOiAiK0guZChhKSkpfX0sClpaOmZ1bmN0aW9uIFpaKGEsYixjLGQsZSxmKXt2YXIgXz10aGlz
-Cl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mfSwKeTg6ZnVuY3Rpb24geTgoYSl7dGhp
-cy5iPWF9LApJVjpmdW5jdGlvbiBJVihhLGIsYyxkKXt2YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1j
-Cl8ucj1kfX0sTT17CllGOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4KZm9yKHQ9Yi5sZW5n
-dGgscz0xO3M8dDsrK3Mpe2lmKGJbc109PW51bGx8fGJbcy0xXSE9bnVsbCljb250aW51ZQpmb3IoO3Q+
-PTE7dD1yKXtyPXQtMQppZihiW3JdIT1udWxsKWJyZWFrfXE9bmV3IFAuUm4oIiIpCnA9YSsiKCIKcS5h
-PXAKbz1ILnFDKGIsMCx0LEgudDYoYikuZCkKbj1vLiR0aQpuPXArbmV3IEguQTgobyxuLkMoInFVKGFM
-LkUpIikuYihuZXcgTS5ObygpKSxuLkMoIkE4PGFMLkUscVU+IikpLkgoMCwiLCAiKQpxLmE9bgpxLmE9
-bisoIik6IHBhcnQgIisocy0xKSsiIHdhcyBudWxsLCBidXQgcGFydCAiK3MrIiB3YXMgbm90LiIpCnRo
-cm93IEguYihQLnhZKHEudygwKSkpfX0sCmxJOmZ1bmN0aW9uIGxJKGEpe3RoaXMuYT1hfSwKTWk6ZnVu
-Y3Rpb24gTWkoKXt9LApxNzpmdW5jdGlvbiBxNygpe30sCk5vOmZ1bmN0aW9uIE5vKCl7fX0sWD17CkNM
-OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPWIueFooYSkKYi5oSyhhKQppZihvIT1udWxsKWE9
-Si5LVihhLG8ubGVuZ3RoKQp0PXUucwpzPUguVk0oW10sdCkKcj1ILlZNKFtdLHQpCnQ9YS5sZW5ndGgK
-aWYodCE9PTAmJmIucjQoQy54Qi5XKGEsMCkpKXtpZigwPj10KXJldHVybiBILk9IKGEsMCkKQy5ObS5p
-KHIsYVswXSkKcT0xfWVsc2V7Qy5ObS5pKHIsIiIpCnE9MH1mb3IocD1xO3A8dDsrK3ApaWYoYi5yNChD
-LnhCLlcoYSxwKSkpe0MuTm0uaShzLEMueEIuTmooYSxxLHApKQpDLk5tLmkocixhW3BdKQpxPXArMX1p
-ZihxPHQpe0MuTm0uaShzLEMueEIuRyhhLHEpKQpDLk5tLmkociwiIil9cmV0dXJuIG5ldyBYLldEKGIs
-byxzLHIpfSwKV0Q6ZnVuY3Rpb24gV0QoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9
-YwpfLmU9ZH0sCnFSOmZ1bmN0aW9uIHFSKGEpe3RoaXMuYT1hfSwKSlQ6ZnVuY3Rpb24oYSl7cmV0dXJu
-IG5ldyBYLmR2KGEpfSwKZHY6ZnVuY3Rpb24gZHYoYSl7dGhpcy5hPWF9fSxPPXsKUmg6ZnVuY3Rpb24o
-KXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGk9bnVsbAppZihQLnVvKCkuZ0ZpKCkhPT0iZmlsZSIp
-cmV0dXJuICQuRWIoKQp0PVAudW8oKQppZighQy54Qi5UYyh0LmdJaSh0KSwiLyIpKXJldHVybiAkLkVi
-KCkKcz1QLlBpKGksMCwwKQpyPVAuelIoaSwwLDApCnE9UC5PZShpLDAsMCwhMSkKcD1QLmxlKGksMCww
-LGkpCm89UC50RyhpLDAsMCkKbj1QLndCKGkscykKbT1zPT09ImZpbGUiCmlmKHE9PW51bGwpdD1yLmxl
-bmd0aCE9PTB8fG4hPW51bGx8fG0KZWxzZSB0PSExCmlmKHQpcT0iIgp0PXE9PW51bGwKbD0hdAprPVAu
-a2EoImEvYiIsMCwzLGkscyxsKQpqPXMubGVuZ3RoPT09MAppZihqJiZ0JiYhQy54Qi5uKGssIi8iKSlr
-PVAud0Yoaywhanx8bCkKZWxzZSBrPVAueGUoaykKaWYobmV3IFAuRG4ocyxyLHQmJkMueEIubihrLCIv
-LyIpPyIiOnEsbixrLHAsbykudDQoKT09PSJhXFxiIilyZXR1cm4gJC5LaygpCnJldHVybiAkLmJEKCl9
-LAp6TDpmdW5jdGlvbiB6TCgpe319LEU9e09GOmZ1bmN0aW9uIE9GKGEsYixjKXt0aGlzLmQ9YQp0aGlz
-LmU9Ygp0aGlzLmY9Y319LEY9e3J1OmZ1bmN0aW9uIHJ1KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5kPWEK
-Xy5lPWIKXy5mPWMKXy5yPWR9fSxEPXsKUlg6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9UC51bygpCmlmKEou
-Uk0ociwkLkk2KSlyZXR1cm4gJC5GZgokLkk2PXIKaWYoJC5IaygpPT0kLkViKCkpcmV0dXJuICQuRmY9
-ci5aSSgiLiIpLncoMCkKZWxzZXt0PXIudDQoKQpzPXQubGVuZ3RoLTEKcmV0dXJuICQuRmY9cz09PTA/
-dDpDLnhCLk5qKHQsMCxzKX19LApucjpmdW5jdGlvbihhLGIpe3ZhciB0PW51bGwKcmV0dXJuICQublUo
-KS5xNygwLGEsYix0LHQsdCx0LHQsdCl9fQp2YXIgdz1bQyxILEosUCxXLFUsQixULEwsTSxYLE8sRSxG
-LERdCmh1bmtIZWxwZXJzLnNldEZ1bmN0aW9uTmFtZXNJZk5lY2Vzc2FyeSh3KQp2YXIgJD17fQpILmVv
-LnByb3RvdHlwZT17fQpKLnZCLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PT1i
-fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5z
-dGFuY2Ugb2YgJyIrSC5kKEguTShhKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt1Lm8uYihiKQp0aHJv
-dyBILmIoUC5scihhLGIuZ1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9fQpKLnlFLnByb3RvdHlwZT17Cnc6
-ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gYT81MTkw
-MTg6MjE4MTU5fSwKJGlhMjoxfQpKLllFLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJu
-IG51bGw9PWJ9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiJudWxsIn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1
-cm4gMH0sCmU3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuU2ooYSx1Lm8uYihiKSl9LAokaWM4OjF9
-CkouTUYucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiAwfSwKdzpmdW5jdGlvbihhKXty
-ZXR1cm4gU3RyaW5nKGEpfSwKJGl2bToxfQpKLmlDLnByb3RvdHlwZT17fQpKLmtkLnByb3RvdHlwZT17
-fQpKLmM1LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9YVskLncoKV0KaWYodD09bnVsbCly
-ZXR1cm4gdGhpcy50KGEpCnJldHVybiJKYXZhU2NyaXB0IGZ1bmN0aW9uIGZvciAiK0guZChKLmoodCkp
-fSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm57ZnVuYzoxLG9wdDpbLCwsLCwsLCwsLCwsLCwsLF19fSwKJGlF
-SDoxfQpKLmpkLnByb3RvdHlwZT17Cmk6ZnVuY3Rpb24oYSxiKXtILnQ2KGEpLmQuYihiKQppZighIWEu
-Zml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiYWRkIikpCmEucHVzaChiKX0sClc0OmZ1bmN0aW9uKGEsYil7
-dmFyIHQKaWYoISFhLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoInJlbW92ZUF0IikpCnQ9YS5sZW5ndGgK
-aWYoYj49dCl0aHJvdyBILmIoUC54KGIsbnVsbCkpCnJldHVybiBhLnNwbGljZShiLDEpWzBdfSwKVUc6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscgpILnQ2KGEpLkMoImNYPDE+IikuYihjKQppZighIWEuZml4
-ZWQkbGVuZ3RoKUgudmgoUC5MNCgiaW5zZXJ0QWxsIikpCnQ9YS5sZW5ndGgKUC53QShiLDAsdCwiaW5k
-ZXgiKQpzPWMubGVuZ3RoCnRoaXMuc0EoYSx0K3MpCnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEs
-YikKdGhpcy52ZyhhLGIscixjKX0sCm12OmZ1bmN0aW9uKGEpe2lmKCEhYS5maXhlZCRsZW5ndGgpSC52
-aChQLkw0KCJyZW1vdmVMYXN0IikpCmlmKGEubGVuZ3RoPT09MCl0aHJvdyBILmIoSC5IWShhLC0xKSkK
-cmV0dXJuIGEucG9wKCl9LApGVjpmdW5jdGlvbihhLGIpe3ZhciB0CkgudDYoYSkuQygiY1g8MT4iKS5i
-KGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJhZGRBbGwiKSkKZm9yKHQ9Si5JVChiKTt0
-LkYoKTspYS5wdXNoKHQuZ2woKSl9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnQ2KGEpLkMoIn4o
-MSkiKS5iKGIpCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKXtiLiQxKGFbc10pCmlmKGEubGVuZ3Ro
-IT09dCl0aHJvdyBILmIoUC5hNChhKSl9fSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUgudDYoYSkK
-cmV0dXJuIG5ldyBILkE4KGEsdC5LcShjKS5DKCIxKDIpIikuYihiKSx0LkMoIkA8MT4iKS5LcShjKS5D
-KCJBODwxLDI+IikpfSwKSDpmdW5jdGlvbihhLGIpe3ZhciB0LHM9bmV3IEFycmF5KGEubGVuZ3RoKQpz
-LmZpeGVkJGxlbmd0aD1BcnJheQpmb3IodD0wO3Q8YS5sZW5ndGg7Kyt0KXRoaXMuWShzLHQsSC5kKGFb
-dF0pKQpyZXR1cm4gcy5qb2luKGIpfSwKTjA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCmQuYihi
-KQpILnQ2KGEpLktxKGQpLkMoIjEoMSwyKSIpLmIoYykKdD1hLmxlbmd0aApmb3Iocz1iLHI9MDtyPHQ7
-KytyKXtzPWMuJDIocyxhW3JdKQppZihhLmxlbmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVy
-biBzfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpy
-ZXR1cm4gYVtiXX0sCkQ2OmZ1bmN0aW9uKGEsYixjKXtpZihiPDB8fGI+YS5sZW5ndGgpdGhyb3cgSC5i
-KFAuVEUoYiwwLGEubGVuZ3RoLCJzdGFydCIsbnVsbCkpCmlmKGM8Ynx8Yz5hLmxlbmd0aCl0aHJvdyBI
-LmIoUC5URShjLGIsYS5sZW5ndGgsImVuZCIsbnVsbCkpCmlmKGI9PT1jKXJldHVybiBILlZNKFtdLEgu
-dDYoYSkpCnJldHVybiBILlZNKGEuc2xpY2UoYixjKSxILnQ2KGEpKX0sCmdyWjpmdW5jdGlvbihhKXt2
-YXIgdD1hLmxlbmd0aAppZih0PjApcmV0dXJuIGFbdC0xXQp0aHJvdyBILmIoSC5XcCgpKX0sCllXOmZ1
-bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyPUgudDYoYSkKci5DKCJjWDwxPiIpLmIoZCkKaWYoISFh
-LmltbXV0YWJsZSRsaXN0KUgudmgoUC5MNCgic2V0UmFuZ2UiKSkKUC5qQihiLGMsYS5sZW5ndGgpCnQ9
-Yy1iCmlmKHQ9PT0wKXJldHVybgpQLmsxKGUsInNraXBDb3VudCIpCnIuQygiek08MT4iKS5iKGQpCnI9
-Si5VNihkKQppZihlK3Q+ci5nQShkKSl0aHJvdyBILmIoSC5hcigpKQppZihlPGIpZm9yKHM9dC0xO3M+
-PTA7LS1zKWFbYitzXT1yLnEoZCxlK3MpCmVsc2UgZm9yKHM9MDtzPHQ7KytzKWFbYitzXT1yLnEoZCxl
-K3MpfSwKdmc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIHRoaXMuWVcoYSxiLGMsZCwwKX0sClZyOmZ1
-bmN0aW9uKGEsYil7dmFyIHQscwpILnQ2KGEpLkMoImEyKDEpIikuYihiKQp0PWEubGVuZ3RoCmZvcihz
-PTA7czx0Oysrcyl7aWYoSC5vVChiLiQxKGFbc10pKSlyZXR1cm4hMAppZihhLmxlbmd0aCE9PXQpdGhy
-b3cgSC5iKFAuYTQoYSkpfXJldHVybiExfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdApmb3IodD0wO3Q8
-YS5sZW5ndGg7Kyt0KWlmKEouUk0oYVt0XSxiKSlyZXR1cm4hMApyZXR1cm4hMX0sCnc6ZnVuY3Rpb24o
-YSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX0sCmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEoubTEo
-YSxhLmxlbmd0aCxILnQ2KGEpLkMoIm0xPDE+IikpfSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVR
-KGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKc0E6ZnVuY3Rpb24oYSxiKXtpZigh
-IWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgic2V0IGxlbmd0aCIpKQppZihiPDApdGhyb3cgSC5iKFAu
-VEUoYiwwLG51bGwsIm5ld0xlbmd0aCIsbnVsbCkpCmEubGVuZ3RoPWJ9LApxOmZ1bmN0aW9uKGEsYil7
-SC5TYyhiKQppZihiPj1hLmxlbmd0aHx8YjwwKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2Jd
-fSwKWTpmdW5jdGlvbihhLGIsYyl7SC50NihhKS5kLmIoYykKaWYoISFhLmltbXV0YWJsZSRsaXN0KUgu
-dmgoUC5MNCgiaW5kZXhlZCBzZXQiKSkKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5IWShh
-LGIpKQphW2JdPWN9LAokaWNYOjEsCiRpek06MX0KSi5Qby5wcm90b3R5cGU9e30KSi5tMS5wcm90b3R5
-cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlz
-LHI9cy5hLHE9ci5sZW5ndGgKaWYocy5iIT09cSl0aHJvdyBILmIoSC5sayhyKSkKdD1zLmMKaWYodD49
-cSl7cy5zTShudWxsKQpyZXR1cm4hMX1zLnNNKHJbdF0pOysrcy5jCnJldHVybiEwfSwKc006ZnVuY3Rp
-b24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KSi5xSS5wcm90b3R5cGU9ewp5dTpm
-dW5jdGlvbihhKXt2YXIgdAppZihhPj0tMjE0NzQ4MzY0OCYmYTw9MjE0NzQ4MzY0NylyZXR1cm4gYXww
-CmlmKGlzRmluaXRlKGEpKXt0PWE8MD9NYXRoLmNlaWwoYSk6TWF0aC5mbG9vcihhKQpyZXR1cm4gdCsw
-fXRocm93IEguYihQLkw0KCIiK2ErIi50b0ludCgpIikpfSwKelE6ZnVuY3Rpb24oYSl7aWYoYT4wKXtp
-ZihhIT09MS8wKXJldHVybiBNYXRoLnJvdW5kKGEpfWVsc2UgaWYoYT4tMS8wKXJldHVybiAwLU1hdGgu
-cm91bmQoMC1hKQp0aHJvdyBILmIoUC5MNCgiIithKyIucm91bmQoKSIpKX0sCldaOmZ1bmN0aW9uKGEs
-Yil7dmFyIHQscyxyLHEKaWYoYjwyfHxiPjM2KXRocm93IEguYihQLlRFKGIsMiwzNiwicmFkaXgiLG51
-bGwpKQp0PWEudG9TdHJpbmcoYikKaWYoQy54Qi5tKHQsdC5sZW5ndGgtMSkhPT00MSlyZXR1cm4gdApz
-PS9eKFtcZGEtel0rKSg/OlwuKFtcZGEtel0rKSk/XChlXCsoXGQrKVwpJC8uZXhlYyh0KQppZihzPT1u
-dWxsKUgudmgoUC5MNCgiVW5leHBlY3RlZCB0b1N0cmluZyByZXN1bHQ6ICIrdCkpCnI9cy5sZW5ndGgK
-aWYoMT49cilyZXR1cm4gSC5PSChzLDEpCnQ9c1sxXQppZigzPj1yKXJldHVybiBILk9IKHMsMykKcT0r
-c1szXQpyPXNbMl0KaWYociE9bnVsbCl7dCs9cgpxLT1yLmxlbmd0aH1yZXR1cm4gdCtDLnhCLkl4KCIw
-IixxKX0sCnc6ZnVuY3Rpb24oYSl7aWYoYT09PTAmJjEvYTwwKXJldHVybiItMC4wIgplbHNlIHJldHVy
-biIiK2F9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscD1hfDAKaWYoYT09PXApcmV0dXJuIDUz
-Njg3MDkxMSZwCnQ9TWF0aC5hYnMoYSkKcz1NYXRoLmxvZyh0KS8wLjY5MzE0NzE4MDU1OTk0NTN8MApy
-PU1hdGgucG93KDIscykKcT10PDE/dC9yOnIvdApyZXR1cm4gNTM2ODcwOTExJigocSo5MDA3MTk5MjU0
-NzQwOTkyfDApKyhxKjM1NDIyNDMxODExNzY1MjF8MCkpKjU5OTE5NytzKjEyNTl9LAp6WTpmdW5jdGlv
-bihhLGIpe3ZhciB0PWElYgppZih0PT09MClyZXR1cm4gMAppZih0PjApcmV0dXJuIHQKaWYoYjwwKXJl
-dHVybiB0LWIKZWxzZSByZXR1cm4gdCtifSwKd0c6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPjApdD10
-aGlzLnAzKGEsYikKZWxzZXt0PWI+MzE/MzE6Ygp0PWE+PnQ+Pj4wfXJldHVybiB0fSwKYmY6ZnVuY3Rp
-b24oYSxiKXtpZihiPDApdGhyb3cgSC5iKEgudEwoYikpCnJldHVybiB0aGlzLnAzKGEsYil9LApwMzpm
-dW5jdGlvbihhLGIpe3JldHVybiBiPjMxPzA6YT4+PmJ9LAokaUNQOjEsCiRpRks6MX0KSi51ci5wcm90
-b3R5cGU9eyRpS046MX0KSi5WQS5wcm90b3R5cGU9e30KSi5Eci5wcm90b3R5cGU9ewptOmZ1bmN0aW9u
-KGEsYil7aWYoYjwwKXRocm93IEguYihILkhZKGEsYikpCmlmKGI+PWEubGVuZ3RoKUgudmgoSC5IWShh
-LGIpKQpyZXR1cm4gYS5jaGFyQ29kZUF0KGIpfSwKVzpmdW5jdGlvbihhLGIpe2lmKGI+PWEubGVuZ3Ro
-KXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhLmNoYXJDb2RlQXQoYil9LApkZDpmdW5jdGlvbihh
-LGIpe3JldHVybiBuZXcgSC51bihiLGEsMCl9LApoOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJz
-dHJpbmciKXRocm93IEguYihQLkwzKGIsbnVsbCxudWxsKSkKcmV0dXJuIGErYn0sClRjOmZ1bmN0aW9u
-KGEsYil7dmFyIHQ9Yi5sZW5ndGgscz1hLmxlbmd0aAppZih0PnMpcmV0dXJuITEKcmV0dXJuIGI9PT10
-aGlzLkcoYSxzLXQpfSwKaTc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwpjPVAuakIoYixjLGEubGVu
-Z3RoKQp0PWEuc3Vic3RyaW5nKDAsYikKcz1hLnN1YnN0cmluZyhjKQpyZXR1cm4gdCtkK3N9LApRaTpm
-dW5jdGlvbihhLGIsYyl7dmFyIHQKaWYoIUgub2soYykpSC52aChILnRMKGMpKQppZih0eXBlb2YgYyE9
-PSJudW1iZXIiKXJldHVybiBjLkooKQppZihjPDB8fGM+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYyww
-LGEubGVuZ3RoLG51bGwsbnVsbCkpCnQ9YytiLmxlbmd0aAppZih0PmEubGVuZ3RoKXJldHVybiExCnJl
-dHVybiBiPT09YS5zdWJzdHJpbmcoYyx0KX0sCm46ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5RaShh
-LGIsMCl9LApOajpmdW5jdGlvbihhLGIsYyl7aWYoIUgub2soYikpSC52aChILnRMKGIpKQppZihjPT1u
-dWxsKWM9YS5sZW5ndGgKaWYodHlwZW9mIGIhPT0ibnVtYmVyIilyZXR1cm4gYi5KKCkKaWYoYjwwKXRo
-cm93IEguYihQLngoYixudWxsKSkKaWYoYj5jKXRocm93IEguYihQLngoYixudWxsKSkKaWYoYz5hLmxl
-bmd0aCl0aHJvdyBILmIoUC54KGMsbnVsbCkpCnJldHVybiBhLnN1YnN0cmluZyhiLGMpfSwKRzpmdW5j
-dGlvbihhLGIpe3JldHVybiB0aGlzLk5qKGEsYixudWxsKX0sCmhjOmZ1bmN0aW9uKGEpe3JldHVybiBh
-LnRvTG93ZXJDYXNlKCl9LApiUzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT1hLnRyaW0oKSxwPXEubGVu
-Z3RoCmlmKHA9PT0wKXJldHVybiBxCmlmKHRoaXMuVyhxLDApPT09MTMzKXt0PUoubW0ocSwxKQppZih0
-PT09cClyZXR1cm4iIn1lbHNlIHQ9MApzPXAtMQpyPXRoaXMubShxLHMpPT09MTMzP0ouYzEocSxzKTpw
-CmlmKHQ9PT0wJiZyPT09cClyZXR1cm4gcQpyZXR1cm4gcS5zdWJzdHJpbmcodCxyKX0sCkl4OmZ1bmN0
-aW9uKGEsYil7dmFyIHQscwppZigwPj1iKXJldHVybiIiCmlmKGI9PT0xfHxhLmxlbmd0aD09PTApcmV0
-dXJuIGEKaWYoYiE9PWI+Pj4wKXRocm93IEguYihDLkVxKQpmb3IodD1hLHM9IiI7ITA7KXtpZigoYiYx
-KT09PTEpcz10K3MKYj1iPj4+MQppZihiPT09MClicmVhawp0Kz10fXJldHVybiBzfSwKWFU6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciB0CmlmKGM8MHx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5n
-dGgsbnVsbCxudWxsKSkKdD1hLmluZGV4T2YoYixjKQpyZXR1cm4gdH0sCk9ZOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIHRoaXMuWFUoYSxiLDApfSwKUGs6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoYz09bnVs
-bCljPWEubGVuZ3RoCmVsc2UgaWYoYzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxl
-bmd0aCxudWxsLG51bGwpKQp0PWIubGVuZ3RoCnM9YS5sZW5ndGgKaWYoYyt0PnMpYz1zLXQKcmV0dXJu
-IGEubGFzdEluZGV4T2YoYixjKX0sCmNuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUGsoYSxiLG51
-bGwpfSwKSXM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PWEubGVuZ3RoCmlmKGM+dCl0aHJvdyBILmIoUC5U
-RShjLDAsdCxudWxsLG51bGwpKQpyZXR1cm4gSC5tMihhLGIsYyl9LAp0ZzpmdW5jdGlvbihhLGIpe3Jl
-dHVybiB0aGlzLklzKGEsYiwwKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApnaU86ZnVuY3Rpb24o
-YSl7dmFyIHQscyxyCmZvcih0PWEubGVuZ3RoLHM9MCxyPTA7cjx0Oysrcil7cz01MzY4NzA5MTEmcyth
-LmNoYXJDb2RlQXQocikKcz01MzY4NzA5MTEmcysoKDUyNDI4NyZzKTw8MTApCnNePXM+PjZ9cz01MzY4
-NzA5MTEmcysoKDY3MTA4ODYzJnMpPDwzKQpzXj1zPj4xMQpyZXR1cm4gNTM2ODcwOTExJnMrKCgxNjM4
-MyZzKTw8MTUpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIp
-e0guU2MoYikKaWYoYj49YS5sZW5ndGh8fCExKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2Jd
-fSwKJGl2WDoxLAokaXFVOjF9CkgucWoucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
-aXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEMueEIubSh0aGlzLmEsSC5TYyhiKSl9
-fQpILmJRLnByb3RvdHlwZT17fQpILmFMLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD10
-aGlzCnJldHVybiBuZXcgSC5hNyh0LHQuZ0EodCksSC5MaCh0KS5DKCJhNzxhTC5FPiIpKX0sCkg6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdCxzLHIscT10aGlzLHA9cS5nQShxKQppZihiLmxlbmd0aCE9PTApe2lmKHA9
-PT0wKXJldHVybiIiCnQ9SC5kKHEuRSgwLDApKQppZihwIT09cS5nQShxKSl0aHJvdyBILmIoUC5hNChx
-KSkKZm9yKHM9dCxyPTE7cjxwOysrcil7cz1zK2IrSC5kKHEuRSgwLHIpKQppZihwIT09cS5nQShxKSl0
-aHJvdyBILmIoUC5hNChxKSl9cmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9ZWxzZXtmb3Iocj0w
-LHM9IiI7cjxwOysrcil7cys9SC5kKHEuRSgwLHIpKQppZihwIT09cS5nQShxKSl0aHJvdyBILmIoUC5h
-NChxKSl9cmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9fSwKZXY6ZnVuY3Rpb24oYSxiKXtyZXR1
-cm4gdGhpcy5HRygwLEguTGgodGhpcykuQygiYTIoYUwuRSkiKS5iKGIpKX19CkgubkgucHJvdG90eXBl
-PXsKZ1VEOmZ1bmN0aW9uKCl7dmFyIHQ9Si5IbSh0aGlzLmEpLHM9dGhpcy5jCmlmKHM9PW51bGx8fHM+
-dClyZXR1cm4gdApyZXR1cm4gc30sCmdBczpmdW5jdGlvbigpe3ZhciB0PUouSG0odGhpcy5hKSxzPXRo
-aXMuYgppZihzPnQpcmV0dXJuIHQKcmV0dXJuIHN9LApnQTpmdW5jdGlvbihhKXt2YXIgdCxzPUouSG0o
-dGhpcy5hKSxyPXRoaXMuYgppZihyPj1zKXJldHVybiAwCnQ9dGhpcy5jCmlmKHQ9PW51bGx8fHQ+PXMp
-cmV0dXJuIHMtcgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkhOKCkKcmV0dXJuIHQtcn0s
-CkU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMscj1zLmdBcygpK2IKaWYoYj49MCl7dD1zLmdVRCgp
-CmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIEgucFkodCkKdD1yPj10fWVsc2UgdD0hMAppZih0
-KXRocm93IEguYihQLkNmKGIscywiaW5kZXgiLG51bGwsbnVsbCkpCnJldHVybiBKLkdBKHMuYSxyKX19
-CkguYTcucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigp
-e3ZhciB0LHM9dGhpcyxyPXMuYSxxPUouVTYocikscD1xLmdBKHIpCmlmKHMuYiE9PXApdGhyb3cgSC5i
-KFAuYTQocikpCnQ9cy5jCmlmKHQ+PXApe3Muc0kobnVsbCkKcmV0dXJuITF9cy5zSShxLkUocix0KSk7
-KytzLmMKcmV0dXJuITB9LApzSTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuZC5iKGEpfSwKJGlB
-bjoxfQpILkE4LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkhtKHRoaXMuYSl9LApF
-OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYi4kMShKLkdBKHRoaXMuYSxiKSl9fQpILlU1LnByb3Rv
-dHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguU08oSi5JVCh0aGlzLmEpLHRoaXMuYix0
-aGlzLiR0aS5DKCJTTzwxPiIpKX19CkguU08ucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciB0LHMK
-Zm9yKHQ9dGhpcy5hLHM9dGhpcy5iO3QuRigpOylpZihILm9UKHMuJDEodC5nbCgpKSkpcmV0dXJuITAK
-cmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuZ2woKX19CkguU1UucHJvdG90eXBl
-PXt9CkguUmUucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7SC5MaCh0aGlzKS5DKCJSZS5FIiku
-YihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSBhbiB1bm1vZGlmaWFibGUgbGlzdCIpKX19
-CkguWEMucHJvdG90eXBlPXt9Ckgud3YucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
-aXMuX2hhc2hDb2RlCmlmKHQhPW51bGwpcmV0dXJuIHQKdD01MzY4NzA5MTEmNjY0NTk3KkouaGYodGhp
-cy5hKQp0aGlzLl9oYXNoQ29kZT10CnJldHVybiB0fSwKdzpmdW5jdGlvbihhKXtyZXR1cm4nU3ltYm9s
-KCInK0guZCh0aGlzLmEpKyciKSd9LApETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJuITEK
-cmV0dXJuIGIgaW5zdGFuY2VvZiBILnd2JiZ0aGlzLmE9PWIuYX0sCiRpR0Q6MX0KSC5QRC5wcm90b3R5
-cGU9e30KSC5XVS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKWTpm
-dW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0LmQuYihiKQp0LmNoWzFdLmIoYykKcmV0dXJu
-IEguZGMoKX0sCiRpWjA6MX0KSC5MUC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhp
-cy5hfSwKeDQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGEhPSJzdHJpbmciKXJldHVybiExCmlmKCJfX3By
-b3RvX18iPT09YSlyZXR1cm4hMQpyZXR1cm4gdGhpcy5iLmhhc093blByb3BlcnR5KGEpfSwKcTpmdW5j
-dGlvbihhLGIpe2lmKCF0aGlzLng0KGIpKXJldHVybiBudWxsCnJldHVybiB0aGlzLnFQKGIpfSwKcVA6
-ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYltILnkoYSldfSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
-cixxLHA9SC5MaCh0aGlzKQpwLkMoIn4oMSwyKSIpLmIoYikKdD10aGlzLmMKZm9yKHM9dC5sZW5ndGgs
-cD1wLmNoWzFdLHI9MDtyPHM7KytyKXtxPXRbcl0KYi4kMihxLHAuYih0aGlzLnFQKHEpKSl9fX0KSC5M
-SS5wcm90b3R5cGU9ewpnV2E6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmEKcmV0dXJuIHR9LApnbmQ6ZnVu
-Y3Rpb24oKXt2YXIgdCxzLHIscSxwPXRoaXMKaWYocC5jPT09MSlyZXR1cm4gQy5oVQp0PXAuZApzPXQu
-bGVuZ3RoLXAuZS5sZW5ndGgtcC5mCmlmKHM9PT0wKXJldHVybiBDLmhVCnI9W10KZm9yKHE9MDtxPHM7
-KytxKXtpZihxPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LHEpCnIucHVzaCh0W3FdKX1yZXR1cm4gSi56
-QyhyKX0sCmdWbTpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10aGlzCmlmKGwuYyE9PTAp
-cmV0dXJuIEMuQ00KdD1sLmUKcz10Lmxlbmd0aApyPWwuZApxPXIubGVuZ3RoLXMtbC5mCmlmKHM9PT0w
-KXJldHVybiBDLkNNCnA9bmV3IEguTjUodS5lbykKZm9yKG89MDtvPHM7KytvKXtpZihvPj10Lmxlbmd0
-aClyZXR1cm4gSC5PSCh0LG8pCm49dFtvXQptPXErbwppZihtPDB8fG0+PXIubGVuZ3RoKXJldHVybiBI
-Lk9IKHIsbSkKcC5ZKDAsbmV3IEgud3YobiksclttXSl9cmV0dXJuIG5ldyBILlBEKHAsdS5nRil9LAok
-aXZROjF9CkguQ2oucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdApILnkoYSkKdD10aGlz
-LmEKdC5iPXQuYisiJCIrSC5kKGEpCkMuTm0uaSh0aGlzLmIsYSkKQy5ObS5pKHRoaXMuYyxiKTsrK3Qu
-YX0sCiRTOjEyfQpILmY5LnByb3RvdHlwZT17CnFTOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9
-bmV3IFJlZ0V4cChyLmEpLmV4ZWMoYSkKaWYocT09bnVsbClyZXR1cm4gbnVsbAp0PU9iamVjdC5jcmVh
-dGUobnVsbCkKcz1yLmIKaWYocyE9PS0xKXQuYXJndW1lbnRzPXFbcysxXQpzPXIuYwppZihzIT09LTEp
-dC5hcmd1bWVudHNFeHByPXFbcysxXQpzPXIuZAppZihzIT09LTEpdC5leHByPXFbcysxXQpzPXIuZQpp
-ZihzIT09LTEpdC5tZXRob2Q9cVtzKzFdCnM9ci5mCmlmKHMhPT0tMSl0LnJlY2VpdmVyPXFbcysxXQpy
-ZXR1cm4gdH19CkguVzAucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmIKaWYodD09
-bnVsbClyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5kKHRoaXMuYSkKcmV0dXJuIk5vU3VjaE1l
-dGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIit0KyInIG9uIG51bGwifX0KSC5hei5wcm90b3R5
-cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxyPSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9k
-IG5vdCBmb3VuZDogJyIscT1zLmIKaWYocT09bnVsbClyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIr
-SC5kKHMuYSkKdD1zLmMKaWYodD09bnVsbClyZXR1cm4gcitxKyInICgiK0guZChzLmEpKyIpIgpyZXR1
-cm4gcitxKyInIG9uICciK3QrIicgKCIrSC5kKHMuYSkrIikifX0KSC52Vi5wcm90b3R5cGU9ewp3OmZ1
-bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5sZW5ndGg9PT0wPyJFcnJvciI6IkVycm9yOiAi
-K3R9fQpILmJxLnByb3RvdHlwZT17fQpILkFtLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe2lmKHUu
-YlUuYyhhKSlpZihhLiR0aHJvd25Kc0Vycm9yPT1udWxsKWEuJHRocm93bkpzRXJyb3I9dGhpcy5hCnJl
-dHVybiBhfSwKJFM6NH0KSC5YTy5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5i
-CmlmKHMhPW51bGwpcmV0dXJuIHMKcz10aGlzLmEKdD1zIT09bnVsbCYmdHlwZW9mIHM9PT0ib2JqZWN0
-Ij9zLnN0YWNrOm51bGwKcmV0dXJuIHRoaXMuYj10PT1udWxsPyIiOnR9LAokaUd6OjF9CkguVHAucHJv
-dG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmNvbnN0cnVjdG9yLHM9dD09bnVsbD9udWxs
-OnQubmFtZQpyZXR1cm4iQ2xvc3VyZSAnIitILk5RKHM9PW51bGw/InVua25vd24iOnMpKyInIn0sCiRp
-RUg6MSwKZ1FsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXN9LAokQzoiJDEiLAokUjoxLAokRDpudWxsfQpI
-LmxjLnByb3RvdHlwZT17fQpILnp4LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy4k
-c3RhdGljX25hbWUKaWYodD09bnVsbClyZXR1cm4iQ2xvc3VyZSBvZiB1bmtub3duIHN0YXRpYyBtZXRo
-b2QiCnJldHVybiJDbG9zdXJlICciK0guTlEodCkrIicifX0KSC5yVC5wcm90b3R5cGU9ewpETjpmdW5j
-dGlvbihhLGIpe3ZhciB0PXRoaXMKaWYoYj09bnVsbClyZXR1cm4hMQppZih0PT09YilyZXR1cm4hMApp
-ZighKGIgaW5zdGFuY2VvZiBILnJUKSlyZXR1cm4hMQpyZXR1cm4gdC5hPT09Yi5hJiZ0LmI9PT1iLmIm
-JnQuYz09PWIuY30sCmdpTzpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuYwppZihzPT1udWxsKXQ9SC5l
-USh0aGlzLmEpCmVsc2UgdD10eXBlb2YgcyE9PSJvYmplY3QiP0ouaGYocyk6SC5lUShzKQpyZXR1cm4o
-dF5ILmVRKHRoaXMuYikpPj4+MH0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCmlmKHQ9PW51bGwp
-dD10aGlzLmEKcmV0dXJuIkNsb3N1cmUgJyIrSC5kKHRoaXMuZCkrIicgb2YgIisoIkluc3RhbmNlIG9m
-ICciK0guZChILk0odCkpKyInIil9fQpILkVxLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
-IlJ1bnRpbWVFcnJvcjogIitILmQodGhpcy5hKX19Ckgua1kucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
-KXtyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLnAodGhpcy5hKX19CkguTjUucHJvdG90eXBlPXsK
-Z0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCmdWOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBILmk1
-KHRoaXMsSC5MaCh0aGlzKS5DKCJpNTwxPiIpKX0sCng0OmZ1bmN0aW9uKGEpe3ZhciB0LHMKaWYodHlw
-ZW9mIGE9PSJzdHJpbmciKXt0PXRoaXMuYgppZih0PT1udWxsKXJldHVybiExCnJldHVybiB0aGlzLlh1
-KHQsYSl9ZWxzZXtzPXRoaXMuQ1goYSkKcmV0dXJuIHN9fSwKQ1g6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhp
-cy5kCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuRmgodGhpcy5CdCh0LEouaGYoYSkmMHgz
-ZmZmZmZmKSxhKT49MH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPXRoaXMsbz1udWxsCmlm
-KHR5cGVvZiBiPT0ic3RyaW5nIil7dD1wLmIKaWYodD09bnVsbClyZXR1cm4gbwpzPXAuajIodCxiKQpy
-PXM9PW51bGw/bzpzLmIKcmV0dXJuIHJ9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjB4M2Zm
-ZmZmZik9PT1iKXtxPXAuYwppZihxPT1udWxsKXJldHVybiBvCnM9cC5qMihxLGIpCnI9cz09bnVsbD9v
-OnMuYgpyZXR1cm4gcn1lbHNlIHJldHVybiBwLmFhKGIpfSwKYWE6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
-PXRoaXMuZAppZihyPT1udWxsKXJldHVybiBudWxsCnQ9dGhpcy5CdChyLEouaGYoYSkmMHgzZmZmZmZm
-KQpzPXRoaXMuRmgodCxhKQppZihzPDApcmV0dXJuIG51bGwKcmV0dXJuIHRbc10uYn0sClk6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuPXRoaXMsbT1ILkxoKG4pCm0uZC5iKGIpCm0uY2hbMV0u
-YihjKQppZih0eXBlb2YgYj09InN0cmluZyIpe3Q9bi5iCm4uRUgodD09bnVsbD9uLmI9bi56SygpOnQs
-YixjKX1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgzZmZmZmZmKT09PWIpe3M9bi5jCm4u
-RUgocz09bnVsbD9uLmM9bi56SygpOnMsYixjKX1lbHNle3I9bi5kCmlmKHI9PW51bGwpcj1uLmQ9bi56
-SygpCnE9Si5oZihiKSYweDNmZmZmZmYKcD1uLkJ0KHIscSkKaWYocD09bnVsbCluLkVJKHIscSxbbi5I
-bihiLGMpXSkKZWxzZXtvPW4uRmgocCxiKQppZihvPj0wKXBbb10uYj1jCmVsc2UgcC5wdXNoKG4uSG4o
-YixjKSl9fX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwpILkxoKHIpLkMoIn4oMSwyKSIp
-LmIoYikKdD1yLmUKcz1yLnIKZm9yKDt0IT1udWxsOyl7Yi4kMih0LmEsdC5iKQppZihzIT09ci5yKXRo
-cm93IEguYihQLmE0KHIpKQp0PXQuY319LApFSDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz10aGlzLHI9
-SC5MaChzKQpyLmQuYihiKQpyLmNoWzFdLmIoYykKdD1zLmoyKGEsYikKaWYodD09bnVsbClzLkVJKGEs
-YixzLkhuKGIsYykpCmVsc2UgdC5iPWN9LAprczpmdW5jdGlvbigpe3RoaXMucj10aGlzLnIrMSY2NzEw
-ODg2M30sCkhuOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9SC5MaChzKSxxPW5ldyBILmRiKHIu
-ZC5iKGEpLHIuY2hbMV0uYihiKSkKaWYocy5lPT1udWxsKXMuZT1zLmY9cQplbHNle3Q9cy5mCnEuZD10
-CnMuZj10LmM9cX0rK3MuYQpzLmtzKCkKcmV0dXJuIHF9LApGaDpmdW5jdGlvbihhLGIpe3ZhciB0LHMK
-aWYoYT09bnVsbClyZXR1cm4tMQp0PWEubGVuZ3RoCmZvcihzPTA7czx0OysrcylpZihKLlJNKGFbc10u
-YSxiKSlyZXR1cm4gcwpyZXR1cm4tMX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAubk8odGhpcyl9LApq
-MjpmdW5jdGlvbihhLGIpe3JldHVybiBhW2JdfSwKQnQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYVtiXX0s
-CkVJOmZ1bmN0aW9uKGEsYixjKXthW2JdPWN9LApybjpmdW5jdGlvbihhLGIpe2RlbGV0ZSBhW2JdfSwK
-WHU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5qMihhLGIpIT1udWxsfSwKeks6ZnVuY3Rpb24oKXt2
-YXIgdD0iPG5vbi1pZGVudGlmaWVyLWtleT4iLHM9T2JqZWN0LmNyZWF0ZShudWxsKQp0aGlzLkVJKHMs
-dCxzKQp0aGlzLnJuKHMsdCkKcmV0dXJuIHN9LAokaUZvOjF9CkguZGIucHJvdG90eXBlPXt9CkguaTUu
-cHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hfSwKZ2t6OmZ1bmN0aW9uKGEp
-e3ZhciB0PXRoaXMuYSxzPW5ldyBILk42KHQsdC5yLHRoaXMuJHRpLkMoIk42PDE+IikpCnMuYz10LmUK
-cmV0dXJuIHN9fQpILk42LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6
-ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5hCmlmKHQuYiE9PXMucil0aHJvdyBILmIoUC5hNChzKSkK
-ZWxzZXtzPXQuYwppZihzPT1udWxsKXt0LnNxWShudWxsKQpyZXR1cm4hMX1lbHNle3Quc3FZKHMuYSkK
-dC5jPXQuYy5jCnJldHVybiEwfX19LApzcVk6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihh
-KX0sCiRpQW46MX0KSC5kQy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hKGEp
-fSwKJFM6NH0KSC53Ti5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEoYSxi
-KX0sCiRTOjM4fQpILlZYLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEoSC55
-KGEpKX0sCiRTOjQwfQpILlZSLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlJlZ0V4cC8i
-K3RoaXMuYSsiLyIrdGhpcy5iLmZsYWdzfSwKZ0hjOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYwpp
-ZihzIT1udWxsKXJldHVybiBzCnM9dC5iCnJldHVybiB0LmM9SC52NCh0LmEscy5tdWx0aWxpbmUsIXMu
-aWdub3JlQ2FzZSxzLnVuaWNvZGUscy5kb3RBbGwsITApfSwKZGQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-bmV3IEguS1codGhpcyxiLDApfSwKVVo6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMuZ0hjKCkKcy5s
-YXN0SW5kZXg9Ygp0PXMuZXhlYyhhKQppZih0PT1udWxsKXJldHVybiBudWxsCnJldHVybiBuZXcgSC5F
-Syh0KX0sCiRpdlg6MSwKJGl3TDoxfQpILkVLLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXt2YXIg
-dApILlNjKGIpCnQ9dGhpcy5iCmlmKGI+PXQubGVuZ3RoKXJldHVybiBILk9IKHQsYikKcmV0dXJuIHRb
-Yl19LAokaU9kOjEsCiRpaWI6MX0KSC5LVy5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJu
-IG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19CkguUGIucHJvdG90eXBlPXsKZ2w6ZnVuY3Rp
-b24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcyxvPXAuYgpp
-ZihvPT1udWxsKXJldHVybiExCnQ9cC5jCmlmKHQ8PW8ubGVuZ3RoKXtzPXAuYQpyPXMuVVoobyx0KQpp
-ZihyIT1udWxsKXtwLmQ9cgpvPXIuYgp0PW8uaW5kZXgKcT10K29bMF0ubGVuZ3RoCmlmKHQ9PT1xKXtp
-ZihzLmIudW5pY29kZSl7bz1wLmMKdD1vKzEKcz1wLmIKaWYodDxzLmxlbmd0aCl7bz1KLnJZKHMpLm0o
-cyxvKQppZihvPj01NTI5NiYmbzw9NTYzMTkpe289Qy54Qi5tKHMsdCkKbz1vPj01NjMyMCYmbzw9NTcz
-NDN9ZWxzZSBvPSExfWVsc2Ugbz0hMX1lbHNlIG89ITEKcT0obz9xKzE6cSkrMX1wLmM9cQpyZXR1cm4h
-MH19cC5iPXAuZD1udWxsCnJldHVybiExfSwKJGlBbjoxfQpILnRRLnByb3RvdHlwZT17CnE6ZnVuY3Rp
-b24oYSxiKXtILlNjKGIpCmlmKGIhPT0wKUgudmgoUC54KGIsbnVsbCkpCnJldHVybiB0aGlzLmN9LAok
-aU9kOjF9CkgudW4ucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5TZCh0aGlz
-LmEsdGhpcy5iLHRoaXMuYyl9fQpILlNkLnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9
-dGhpcyxxPXIuYyxwPXIuYixvPXAubGVuZ3RoLG49ci5hLG09bi5sZW5ndGgKaWYocStvPm0pe3IuZD1u
-dWxsCnJldHVybiExfXQ9bi5pbmRleE9mKHAscSkKaWYodDwwKXtyLmM9bSsxCnIuZD1udWxsCnJldHVy
-biExfXM9dCtvCnIuZD1uZXcgSC50USh0LHApCnIuYz1zPT09ci5jP3MrMTpzCnJldHVybiEwfSwKZ2w6
-ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKJGlBbjoxfQpILkVULnByb3RvdHlwZT17JGlFVDoxLCRp
-QVM6MX0KSC5iMC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVhq
-OjF9CkguRGcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5n
-dGgpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC5JZyhjKQpILm9kKGIsYSxhLmxlbmd0
-aCkKYVtiXT1jfSwKJGljWDoxLAokaXpNOjF9CkguUGcucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIs
-Yyl7SC5TYyhjKQpILm9kKGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGljWDoxLAokaXpNOjF9CkgueGou
-cHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVy
-biBhW2JdfX0KSC5kRS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQpILm9kKGIsYSxh
-Lmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlpBLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNj
-KGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19Ckgud2YucHJvdG90eXBlPXsKcTpmdW5j
-dGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5QcS5wcm90
-b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFb
-Yl19fQpILmVFLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVu
-Y3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguVjYucHJv
-dG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0gu
-U2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKJGlWNjoxLAokaW42OjF9CkguUkcu
-cHJvdG90eXBlPXt9CkguVlAucHJvdG90eXBlPXt9CkguV0IucHJvdG90eXBlPXt9CkguWkcucHJvdG90
-eXBlPXt9CkguSmMucHJvdG90eXBlPXsKQzpmdW5jdGlvbihhKXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2
-ZXJzZSx0aGlzLGEpfSwKS3E6ZnVuY3Rpb24oYSl7cmV0dXJuIEgudjUodi50eXBlVW5pdmVyc2UsdGhp
-cyxhKX19CkguRy5wcm90b3R5cGU9e30KSC51OS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVy
-biB0aGlzLmF9fQpILmh6LnByb3RvdHlwZT17fQpILmlNLnByb3RvdHlwZT17fQpQLnRoLnByb3RvdHlw
-ZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQuYQp0LmE9bnVsbApzLiQwKCl9LAokUzox
-OH0KUC5oYS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzCnRoaXMuYS5hPXUuTS5iKGEp
-CnQ9dGhpcy5iCnM9dGhpcy5jCnQuZmlyc3RDaGlsZD90LnJlbW92ZUNoaWxkKHMpOnQuYXBwZW5kQ2hp
-bGQocyl9LAokUzoyMX0KUC5Wcy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS4kMCgpfSwK
-JEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5GdC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS4k
-MCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5XMy5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhLGIp
-e2lmKHNlbGYuc2V0VGltZW91dCE9bnVsbClzZWxmLnNldFRpbWVvdXQoSC50UihuZXcgUC55SCh0aGlz
-LGIpLDApLGEpCmVsc2UgdGhyb3cgSC5iKFAuTDQoImBzZXRUaW1lb3V0KClgIG5vdCBmb3VuZC4iKSl9
-fQpQLnlILnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5iLiQwKCl9LAokQzoiJDAiLAokUjow
-LAokUzoyfQpQLmloLnByb3RvdHlwZT17CmFNOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMuJHRp
-CnIuQygiMS8iKS5iKGIpCnQ9IXRoaXMuYnx8ci5DKCJiODwxPiIpLmMoYikKcz10aGlzLmEKaWYodClz
-LlhmKGIpCmVsc2Ugcy5YMihyLmQuYihiKSl9LAp3MDpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQpp
-Zih0aGlzLmIpdC5aTChhLGIpCmVsc2UgdC5OayhhLGIpfX0KUC5XTS5wcm90b3R5cGU9ewokMTpmdW5j
-dGlvbihhKXtyZXR1cm4gdGhpcy5hLiQyKDAsYSl9LAokUzoyMH0KUC5TWC5wcm90b3R5cGU9ewokMjpm
-dW5jdGlvbihhLGIpe3RoaXMuYS4kMigxLG5ldyBILmJxKGEsdS5sLmIoYikpKX0sCiRDOiIkMiIsCiRS
-OjIsCiRTOjMzfQpQLkdzLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hKEguU2MoYSks
-Yil9LAokUzoyM30KUC5QZi5wcm90b3R5cGU9ewp3MDpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PW51
-bGwpYT1uZXcgUC5uKCkKdD10aGlzLmEKaWYodC5hIT09MCl0aHJvdyBILmIoUC5QVigiRnV0dXJlIGFs
-cmVhZHkgY29tcGxldGVkIikpCnQuTmsoYSxiKX0sCnBtOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLncw
-KGEsbnVsbCl9fQpQLlpmLnByb3RvdHlwZT17CmFNOmZ1bmN0aW9uKGEsYil7dmFyIHQKdGhpcy4kdGku
-QygiMS8iKS5iKGIpCnQ9dGhpcy5hCmlmKHQuYSE9PTApdGhyb3cgSC5iKFAuUFYoIkZ1dHVyZSBhbHJl
-YWR5IGNvbXBsZXRlZCIpKQp0LlhmKGIpfX0KUC5GZS5wcm90b3R5cGU9ewpIUjpmdW5jdGlvbihhKXtp
-ZigodGhpcy5jJjE1KSE9PTYpcmV0dXJuITAKcmV0dXJuIHRoaXMuYi5iLmJ2KHUuYWwuYih0aGlzLmQp
-LGEuYSx1LmNKLHUuSyl9LApLdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmUscz11Lnoscj11LksscT10
-aGlzLiR0aS5DKCIyLyIpLHA9dGhpcy5iLmIKaWYodS5XLmModCkpcmV0dXJuIHEuYihwLnJwKHQsYS5h
-LGEuYixzLHIsdS5sKSkKZWxzZSByZXR1cm4gcS5iKHAuYnYodS55LmIodCksYS5hLHMscikpfX0KUC52
-cy5wcm90b3R5cGU9ewpTcTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9dGhpcy4kdGkKcS5LcShj
-KS5DKCIxLygyKSIpLmIoYSkKdD0kLlgzCmlmKHQhPT1DLk5VKXtjLkMoIkA8MC8+IikuS3EocS5kKS5D
-KCIxKDIpIikuYihhKQppZihiIT1udWxsKWI9UC5WSChiLHQpfXM9bmV3IFAudnMoJC5YMyxjLkMoInZz
-PDA+IikpCnI9Yj09bnVsbD8xOjMKdGhpcy54ZihuZXcgUC5GZShzLHIsYSxiLHEuQygiQDwxPiIpLktx
-KGMpLkMoIkZlPDEsMj4iKSkpCnJldHVybiBzfSwKVzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5T
-cShhLG51bGwsYil9LApRZDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz10aGlzLiR0aQpzLktxKGMpLkMo
-IjEvKDIpIikuYihhKQp0PW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQp0aGlzLnhmKG5ldyBQLkZl
-KHQsKGI9PW51bGw/MTozKXwxNixhLGIscy5DKCJAPDE+IikuS3EoYykuQygiRmU8MSwyPiIpKSkKcmV0
-dXJuIHR9LApPQTpmdW5jdGlvbihhKXt2YXIgdCxzLHIKdS5iZi5iKG51bGwpCnQ9dGhpcy4kdGkKcz0k
-LlgzCnI9bmV3IFAudnMocyx0KQppZihzIT09Qy5OVSlhPVAuVkgoYSxzKQp0aGlzLnhmKG5ldyBQLkZl
-KHIsMixudWxsLGEsdC5DKCJAPDE+IikuS3EodC5kKS5DKCJGZTwxLDI+IikpKQpyZXR1cm4gcn0sCnhm
-OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxyPXMuYQppZihyPD0xKXthLmE9dS54LmIocy5jKQpzLmM9
-YX1lbHNle2lmKHI9PT0yKXt0PXUuXy5iKHMuYykKcj10LmEKaWYocjw0KXt0LnhmKGEpCnJldHVybn1z
-LmE9cgpzLmM9dC5jfVAuVGsobnVsbCxudWxsLHMuYix1Lk0uYihuZXcgUC5kYShzLGEpKSl9fSwKalE6
-ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvPXRoaXMsbj17fQpuLmE9YQppZihhPT1udWxsKXJldHVy
-bgp0PW8uYQppZih0PD0xKXtzPXUueC5iKG8uYykKcj1vLmM9YQppZihzIT1udWxsKXtmb3IoO3E9ci5h
-LHEhPW51bGw7cj1xKTtyLmE9c319ZWxzZXtpZih0PT09Mil7cD11Ll8uYihvLmMpCnQ9cC5hCmlmKHQ8
-NCl7cC5qUShhKQpyZXR1cm59by5hPXQKby5jPXAuY31uLmE9by5OOChhKQpQLlRrKG51bGwsbnVsbCxv
-LmIsdS5NLmIobmV3IFAub1EobixvKSkpfX0sCmFoOmZ1bmN0aW9uKCl7dmFyIHQ9dS54LmIodGhpcy5j
-KQp0aGlzLmM9bnVsbApyZXR1cm4gdGhpcy5OOCh0KX0sCk44OmZ1bmN0aW9uKGEpe3ZhciB0LHMscgpm
-b3IodD1hLHM9bnVsbDt0IT1udWxsO3M9dCx0PXIpe3I9dC5hCnQuYT1zfXJldHVybiBzfSwKSEg6ZnVu
-Y3Rpb24oYSl7dmFyIHQscz10aGlzLHI9cy4kdGkKci5DKCIxLyIpLmIoYSkKaWYoci5DKCJiODwxPiIp
-LmMoYSkpaWYoci5jKGEpKVAuQTkoYSxzKQplbHNlIFAuazMoYSxzKQplbHNle3Q9cy5haCgpCnIuZC5i
-KGEpCnMuYT00CnMuYz1hClAuSFoocyx0KX19LApYMjpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMKcy4k
-dGkuZC5iKGEpCnQ9cy5haCgpCnMuYT00CnMuYz1hClAuSFoocyx0KX0sClpMOmZ1bmN0aW9uKGEsYil7
-dmFyIHQscz10aGlzCnUubC5iKGIpCnQ9cy5haCgpCnMuYT04CnMuYz1uZXcgUC5DdyhhLGIpClAuSFoo
-cyx0KX0sClhmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz10LiR0aQpzLkMoIjEvIikuYihhKQppZihz
-LkMoImI4PDE+IikuYyhhKSl7dC5jVShhKQpyZXR1cm59dC5hPTEKUC5UayhudWxsLG51bGwsdC5iLHUu
-TS5iKG5ldyBQLnJIKHQsYSkpKX0sCmNVOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz10LiR0aQpzLkMo
-ImI4PDE+IikuYihhKQppZihzLmMoYSkpe2lmKGEuYT09PTgpe3QuYT0xClAuVGsobnVsbCxudWxsLHQu
-Yix1Lk0uYihuZXcgUC5LRih0LGEpKSl9ZWxzZSBQLkE5KGEsdCkKcmV0dXJufVAuazMoYSx0KX0sCk5r
-OmZ1bmN0aW9uKGEsYil7dGhpcy5hPTEKUC5UayhudWxsLG51bGwsdGhpcy5iLHUuTS5iKG5ldyBQLlpM
-KHRoaXMsYSxiKSkpfSwKJGliODoxfQpQLmRhLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5IWih0
-aGlzLmEsdGhpcy5iKX0sCiRTOjB9ClAub1EucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkhaKHRo
-aXMuYix0aGlzLmEuYSl9LAokUzowfQpQLnBWLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0
-PXRoaXMuYQp0LmE9MAp0LkhIKGEpfSwKJFM6MTh9ClAuVTcucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24o
-YSxiKXt1LmwuYihiKQp0aGlzLmEuWkwoYSxiKX0sCiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLiQy
-KGEsbnVsbCl9LAokQzoiJDIiLAokRDpmdW5jdGlvbigpe3JldHVybltudWxsXX0sCiRTOjQyfQpQLnZy
-LnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLlpMKHRoaXMuYix0aGlzLmMpfSwKJFM6MH0K
-UC5ySC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuYQp0LlgyKHQuJHRpLmQuYih0
-aGlzLmIpKX0sCiRTOjB9ClAuS0YucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkE5KHRoaXMuYix0
-aGlzLmEpfSwKJFM6MH0KUC5aTC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlz
-LmIsdGhpcy5jKX0sCiRTOjB9ClAuUlQucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIs
-cSxwLG8sbj10aGlzLG09bnVsbAp0cnl7cj1uLmMKbT1yLmIuYi56eih1LmZPLmIoci5kKSx1LnopfWNh
-dGNoKHEpe3Q9SC5SdShxKQpzPUgudHMocSkKaWYobi5kKXtyPXUubi5iKG4uYS5hLmMpLmEKcD10CnA9
-cj09bnVsbD9wPT1udWxsOnI9PT1wCnI9cH1lbHNlIHI9ITEKcD1uLmIKaWYocilwLmI9dS5uLmIobi5h
-LmEuYykKZWxzZSBwLmI9bmV3IFAuQ3codCxzKQpwLmE9ITAKcmV0dXJufWlmKHUuYy5jKG0pKXtpZiht
-IGluc3RhbmNlb2YgUC52cyYmbS5hPj00KXtpZihtLmE9PT04KXtyPW4uYgpyLmI9dS5uLmIobS5jKQpy
-LmE9ITB9cmV0dXJufW89bi5hLmEKcj1uLmIKci5iPW0uVzcobmV3IFAualoobyksdS56KQpyLmE9ITF9
-fSwKJFM6Mn0KUC5qWi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKJFM6
-Mzd9ClAucnEucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtPXRoaXMK
-dHJ5e3I9bS5iCnE9ci4kdGkKcD1xLmQKbz1wLmIobS5jKQptLmEuYj1yLmIuYi5idihxLkMoIjIvKDEp
-IikuYihyLmQpLG8scS5DKCIyLyIpLHApfWNhdGNoKG4pe3Q9SC5SdShuKQpzPUgudHMobikKcj1tLmEK
-ci5iPW5ldyBQLkN3KHQscykKci5hPSEwfX0sCiRTOjJ9ClAuUlcucHJvdG90eXBlPXsKJDA6ZnVuY3Rp
-b24oKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcwp0cnl7dD11Lm4uYihsLmEuYS5jKQpxPWwuYwpp
-ZihILm9UKHEuSFIodCkpJiZxLmUhPW51bGwpe3A9bC5iCnAuYj1xLkt3KHQpCnAuYT0hMX19Y2F0Y2go
-byl7cz1ILlJ1KG8pCnI9SC50cyhvKQpxPXUubi5iKGwuYS5hLmMpCnA9cS5hCm49cwptPWwuYgppZihw
-PT1udWxsP249PW51bGw6cD09PW4pbS5iPXEKZWxzZSBtLmI9bmV3IFAuQ3cocyxyKQptLmE9ITB9fSwK
-JFM6Mn0KUC5PTS5wcm90b3R5cGU9e30KUC5xaC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXt2YXIg
-dCxzLHI9dGhpcyxxPXt9LHA9bmV3IFAudnMoJC5YMyx1LmZKKQpxLmE9MAp0PUguTGgocikKcz10LkMo
-In4oMSkiKS5iKG5ldyBQLkI1KHEscikpCnUuTS5iKG5ldyBQLlBJKHEscCkpClcuSkUoci5hLHIuYixz
-LCExLHQuZCkKcmV0dXJuIHB9fQpQLkI1LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe0guTGgodGhp
-cy5iKS5kLmIoYSk7Kyt0aGlzLmEuYX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIEguTGgodGhpcy5iKS5D
-KCJjOCgxKSIpfX0KUC5QSS5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYi5ISCh0aGlzLmEu
-YSl9LAokUzowfQpQLk1PLnByb3RvdHlwZT17fQpQLmtULnByb3RvdHlwZT17fQpQLnhJLnByb3RvdHlw
-ZT17fQpQLkN3LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIEguZCh0aGlzLmEpfSwKJGlY
-UzoxfQpQLm0wLnByb3RvdHlwZT17JGlKQjoxfQpQLnBLLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7
-dmFyIHQscz10aGlzLmEscj1zLmEKcz1yPT1udWxsP3MuYT1uZXcgUC5uKCk6cgpyPXRoaXMuYgppZihy
-PT1udWxsKXRocm93IEguYihzKQp0PUguYihzKQp0LnN0YWNrPXIudygwKQp0aHJvdyB0fSwKJFM6MH0K
-UC5KaS5wcm90b3R5cGU9ewpiSDpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT1udWxsCnUuTS5iKGEpCnRy
-eXtpZihDLk5VPT09JC5YMyl7YS4kMCgpCnJldHVybn1QLlQ4KHEscSx0aGlzLGEsdS5IKX1jYXRjaChy
-KXt0PUguUnUocikKcz1ILnRzKHIpClAuTDIocSxxLHRoaXMsdCx1LmwuYihzKSl9fSwKRGw6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciB0LHMscixxPW51bGwKYy5DKCJ+KDApIikuYihhKQpjLmIoYikKdHJ5e2lmKEMu
-TlU9PT0kLlgzKXthLiQxKGIpCnJldHVybn1QLnl2KHEscSx0aGlzLGEsYix1LkgsYyl9Y2F0Y2gocil7
-dD1ILlJ1KHIpCnM9SC50cyhyKQpQLkwyKHEscSx0aGlzLHQsdS5sLmIocykpfX0sClJUOmZ1bmN0aW9u
-KGEsYil7cmV0dXJuIG5ldyBQLmhqKHRoaXMsYi5DKCIwKCkiKS5iKGEpLGIpfSwKR1k6ZnVuY3Rpb24o
-YSl7cmV0dXJuIG5ldyBQLlZwKHRoaXMsdS5NLmIoYSkpfSwKUHk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-bmV3IFAuT1IodGhpcyxiLkMoIn4oMCkiKS5iKGEpLGIpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiBu
-dWxsfSwKeno6ZnVuY3Rpb24oYSxiKXtiLkMoIjAoKSIpLmIoYSkKaWYoJC5YMz09PUMuTlUpcmV0dXJu
-IGEuJDAoKQpyZXR1cm4gUC5UOChudWxsLG51bGwsdGhpcyxhLGIpfSwKYnY6ZnVuY3Rpb24oYSxiLGMs
-ZCl7Yy5DKCJAPDA+IikuS3EoZCkuQygiMSgyKSIpLmIoYSkKZC5iKGIpCmlmKCQuWDM9PT1DLk5VKXJl
-dHVybiBhLiQxKGIpCnJldHVybiBQLnl2KG51bGwsbnVsbCx0aGlzLGEsYixjLGQpfSwKcnA6ZnVuY3Rp
-b24oYSxiLGMsZCxlLGYpe2QuQygiQDwwPiIpLktxKGUpLktxKGYpLkMoIjEoMiwzKSIpLmIoYSkKZS5i
-KGIpCmYuYihjKQppZigkLlgzPT09Qy5OVSlyZXR1cm4gYS4kMihiLGMpCnJldHVybiBQLlF4KG51bGws
-bnVsbCx0aGlzLGEsYixjLGQsZSxmKX0sCkxqOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBiLkMoIkA8
-MD4iKS5LcShjKS5LcShkKS5DKCIxKDIsMykiKS5iKGEpfX0KUC5oai5wcm90b3R5cGU9ewokMDpmdW5j
-dGlvbigpe3JldHVybiB0aGlzLmEuenoodGhpcy5iLHRoaXMuYyl9LAokUzpmdW5jdGlvbigpe3JldHVy
-biB0aGlzLmMuQygiMCgpIil9fQpQLlZwLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7cmV0dXJuIHRo
-aXMuYS5iSCh0aGlzLmIpfSwKJFM6Mn0KUC5PUi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIg
-dD10aGlzLmMKcmV0dXJuIHRoaXMuYS5EbCh0aGlzLmIsdC5iKGEpLHQpfSwKJFM6ZnVuY3Rpb24oKXty
-ZXR1cm4gdGhpcy5jLkMoIn4oMCkiKX19ClAuYjYucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3Zh
-ciB0PXRoaXMscz1uZXcgUC5sbSh0LHQucixILkxoKHQpLkMoImxtPDE+IikpCnMuYz10LmUKcmV0dXJu
-IHN9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
-CmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXt0PXRoaXMuYgppZih0PT1udWxs
-KXJldHVybiExCnJldHVybiB1LkouYih0W2JdKSE9bnVsbH1lbHNle3M9dGhpcy5QUihiKQpyZXR1cm4g
-c319LApQUjpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmQKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4g
-dGhpcy5ERih0W3RoaXMuTihhKV0sYSk+PTB9LAppOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMK
-SC5MaChyKS5kLmIoYikKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpe3Q9ci5i
-CnJldHVybiByLmJRKHQ9PW51bGw/ci5iPVAuVDIoKTp0LGIpfWVsc2UgaWYodHlwZW9mIGI9PSJudW1i
-ZXIiJiYoYiYxMDczNzQxODIzKT09PWIpe3M9ci5jCnJldHVybiByLmJRKHM9PW51bGw/ci5jPVAuVDIo
-KTpzLGIpfWVsc2UgcmV0dXJuIHIuQjcoYil9LApCNzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT10aGlz
-CkguTGgocSkuZC5iKGEpCnQ9cS5kCmlmKHQ9PW51bGwpdD1xLmQ9UC5UMigpCnM9cS5OKGEpCnI9dFtz
-XQppZihyPT1udWxsKXRbc109W3EueW8oYSldCmVsc2V7aWYocS5ERihyLGEpPj0wKXJldHVybiExCnIu
-cHVzaChxLnlvKGEpKX1yZXR1cm4hMH0sClI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzCmlmKHR5cGVv
-ZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXJldHVybiB0LkwodC5iLGIpCmVsc2UgaWYodHlw
-ZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpcmV0dXJuIHQuTCh0LmMsYikKZWxzZSBy
-ZXR1cm4gdC5xZyhiKX0sCnFnOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHA9dGhpcyxvPXAuZAppZihv
-PT1udWxsKXJldHVybiExCnQ9cC5OKGEpCnM9b1t0XQpyPXAuREYocyxhKQppZihyPDApcmV0dXJuITEK
-cT1zLnNwbGljZShyLDEpWzBdCmlmKDA9PT1zLmxlbmd0aClkZWxldGUgb1t0XQpwLkdTKHEpCnJldHVy
-biEwfSwKYlE6ZnVuY3Rpb24oYSxiKXtILkxoKHRoaXMpLmQuYihiKQppZih1LkouYihhW2JdKSE9bnVs
-bClyZXR1cm4hMQphW2JdPXRoaXMueW8oYikKcmV0dXJuITB9LApMOmZ1bmN0aW9uKGEsYil7dmFyIHQK
-aWYoYT09bnVsbClyZXR1cm4hMQp0PXUuSi5iKGFbYl0pCmlmKHQ9PW51bGwpcmV0dXJuITEKdGhpcy5H
-Uyh0KQpkZWxldGUgYVtiXQpyZXR1cm4hMH0sClM6ZnVuY3Rpb24oKXt0aGlzLnI9MTA3Mzc0MTgyMyZ0
-aGlzLnIrMX0sCnlvOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxyPW5ldyBQLmJuKEguTGgocykuZC5i
-KGEpKQppZihzLmU9PW51bGwpcy5lPXMuZj1yCmVsc2V7dD1zLmYKci5jPXQKcy5mPXQuYj1yfSsrcy5h
-CnMuUygpCnJldHVybiByfSwKR1M6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPWEuYyxyPWEuYgppZihz
-PT1udWxsKXQuZT1yCmVsc2Ugcy5iPXIKaWYocj09bnVsbCl0LmY9cwplbHNlIHIuYz1zOy0tdC5hCnQu
-UygpfSwKTjpmdW5jdGlvbihhKXtyZXR1cm4gSi5oZihhKSYxMDczNzQxODIzfSwKREY6ZnVuY3Rpb24o
-YSxiKXt2YXIgdCxzCmlmKGE9PW51bGwpcmV0dXJuLTEKdD1hLmxlbmd0aApmb3Iocz0wO3M8dDsrK3Mp
-aWYoSi5STShhW3NdLmEsYikpcmV0dXJuIHMKcmV0dXJuLTF9fQpQLmJuLnByb3RvdHlwZT17fQpQLmxt
-LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIg
-dD10aGlzLHM9dC5hCmlmKHQuYiE9PXMucil0aHJvdyBILmIoUC5hNChzKSkKZWxzZXtzPXQuYwppZihz
-PT1udWxsKXt0LnNqKG51bGwpCnJldHVybiExfWVsc2V7dC5zaih0LiR0aS5kLmIocy5hKSkKdC5jPXQu
-Yy5iCnJldHVybiEwfX19LApzajpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuZC5iKGEpfSwKJGlB
-bjoxfQpQLm1XLnByb3RvdHlwZT17fQpQLkxVLnByb3RvdHlwZT17JGljWDoxLCRpek06MX0KUC5sRC5w
-cm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILmE3KGEsdGhpcy5nQShhKSxILnpL
-KGEpLkMoImE3PGxELkU+IikpfSwKRTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnEoYSxiKX0sCks6
-ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkgueksoYSkuQygifihsRC5FKSIpLmIoYikKdD10aGlzLmdBKGEp
-CmZvcihzPTA7czx0Oysrcyl7Yi4kMSh0aGlzLnEoYSxzKSkKaWYodCE9PXRoaXMuZ0EoYSkpdGhyb3cg
-SC5iKFAuYTQoYSkpfX0sCkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILnpLKGEpCnJldHVybiBuZXcg
-SC5BOChhLHQuS3EoYykuQygiMShsRC5FKSIpLmIoYiksdC5DKCJAPGxELkU+IikuS3EoYykuQygiQTg8
-MSwyPiIpKX0sCmR1OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0CkgueksoYSkuQygibEQuRSIpLmIoZCkK
-UC5qQihiLGMsdGhpcy5nQShhKSkKZm9yKHQ9Yjt0PGM7Kyt0KXRoaXMuWShhLHQsZCl9LAp3OmZ1bmN0
-aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJdIil9fQpQLmlsLnByb3RvdHlwZT17fQpQLnJhLnByb3Rv
-dHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmEKaWYoIXMuYSl0aGlzLmIuYSs9Iiwg
-IgpzLmE9ITEKcz10aGlzLmIKdD1zLmErPUguZChhKQpzLmE9dCsiOiAiCnMuYSs9SC5kKGIpfSwKJFM6
-MX0KUC5Zay5wcm90b3R5cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILkxoKHRoaXMpLkMoIn4o
-WWsuSyxZay5WKSIpLmIoYikKZm9yKHQ9Si5JVCh0aGlzLmdWKCkpO3QuRigpOyl7cz10LmdsKCkKYi4k
-MihzLHRoaXMucSgwLHMpKX19LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gSi5IbSh0aGlzLmdWKCkpfSwK
-dzpmdW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sCiRpWjA6MX0KUC5LUC5wcm90b3R5cGU9ewpZ
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMpCnQuZC5iKGIpCnQuY2hbMV0uYihjKQp0aHJv
-dyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1vZGlmaWFibGUgbWFwIikpfX0KUC5Qbi5wcm90b3R5
-cGU9ewpxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5xKDAsYil9LApZOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgdD1ILkxoKHRoaXMpCnRoaXMuYS5ZKDAsdC5kLmIoYiksdC5jaFsxXS5iKGMpKX0sCks6ZnVu
-Y3Rpb24oYSxiKXt0aGlzLmEuSygwLEguTGgodGhpcykuQygifigxLDIpIikuYihiKSl9LApnQTpmdW5j
-dGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuZ0EodCl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBK
-LmoodGhpcy5hKX0sCiRpWjA6MX0KUC5Hai5wcm90b3R5cGU9e30KUC5sZi5wcm90b3R5cGU9ewp3OmZ1
-bmN0aW9uKGEpe3JldHVybiBQLldFKHRoaXMsInsiLCJ9Iil9fQpQLlZqLnByb3RvdHlwZT17JGljWDox
-LCRpeHU6MX0KUC5Ydi5wcm90b3R5cGU9ewpGVjpmdW5jdGlvbihhLGIpe3ZhciB0CmZvcih0PUouSVQo
-SC5MaCh0aGlzKS5DKCJjWDwxPiIpLmIoYikpO3QuRigpOyl0aGlzLmkoMCx0LmdsKCkpfSwKdzpmdW5j
-dGlvbihhKXtyZXR1cm4gUC5XRSh0aGlzLCJ7IiwifSIpfSwKSDpmdW5jdGlvbihhLGIpe3ZhciB0LHM9
-UC5yaih0aGlzLHRoaXMucixILkxoKHRoaXMpLmQpCmlmKCFzLkYoKSlyZXR1cm4iIgppZihiPT09IiIp
-e3Q9IiIKZG8gdCs9SC5kKHMuZCkKd2hpbGUocy5GKCkpfWVsc2V7dD1ILmQocy5kKQpmb3IoO3MuRigp
-Oyl0PXQrYitILmQocy5kKX1yZXR1cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH0sCiRpY1g6MSwKJGl4
-dToxfQpQLm5ZLnByb3RvdHlwZT17fQpQLldZLnByb3RvdHlwZT17fQpQLlJVLnByb3RvdHlwZT17fQpQ
-LnV3LnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMuYgppZihzPT1udWxsKXJl
-dHVybiB0aGlzLmMucSgwLGIpCmVsc2UgaWYodHlwZW9mIGIhPSJzdHJpbmciKXJldHVybiBudWxsCmVs
-c2V7dD1zW2JdCnJldHVybiB0eXBlb2YgdD09InVuZGVmaW5lZCI/dGhpcy5mYihiKTp0fX0sCmdBOmZ1
-bmN0aW9uKGEpe3JldHVybiB0aGlzLmI9PW51bGw/dGhpcy5jLmE6dGhpcy5DZigpLmxlbmd0aH0sCmdW
-OmZ1bmN0aW9uKCl7aWYodGhpcy5iPT1udWxsKXt2YXIgdD10aGlzLmMKcmV0dXJuIG5ldyBILmk1KHQs
-SC5MaCh0KS5DKCJpNTwxPiIpKX1yZXR1cm4gbmV3IFAuaTgodGhpcyl9LApZOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgdCxzLHI9dGhpcwppZihyLmI9PW51bGwpci5jLlkoMCxiLGMpCmVsc2UgaWYoci54NChiKSl7
-dD1yLmIKdFtiXT1jCnM9ci5hCmlmKHM9PW51bGw/dCE9bnVsbDpzIT09dClzW2JdPW51bGx9ZWxzZSBy
-LlhLKCkuWSgwLGIsYyl9LAp4NDpmdW5jdGlvbihhKXtpZih0aGlzLmI9PW51bGwpcmV0dXJuIHRoaXMu
-Yy54NChhKQpyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuYSxh
-KX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPXRoaXMKdS5jQS5iKGIpCmlmKHAuYj09bnVs
-bClyZXR1cm4gcC5jLksoMCxiKQp0PXAuQ2YoKQpmb3Iocz0wO3M8dC5sZW5ndGg7KytzKXtyPXRbc10K
-cT1wLmJbcl0KaWYodHlwZW9mIHE9PSJ1bmRlZmluZWQiKXtxPVAuUWUocC5hW3JdKQpwLmJbcl09cX1i
-LiQyKHIscSkKaWYodCE9PXAuYyl0aHJvdyBILmIoUC5hNChwKSl9fSwKQ2Y6ZnVuY3Rpb24oKXt2YXIg
-dD11LmouYih0aGlzLmMpCmlmKHQ9PW51bGwpdD10aGlzLmM9SC5WTShPYmplY3Qua2V5cyh0aGlzLmEp
-LHUucykKcmV0dXJuIHR9LApYSzpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbz10aGlzCmlmKG8uYj09
-bnVsbClyZXR1cm4gby5jCnQ9UC5GbCh1Lk4sdS56KQpzPW8uQ2YoKQpmb3Iocj0wO3E9cy5sZW5ndGgs
-cjxxOysrcil7cD1zW3JdCnQuWSgwLHAsby5xKDAscCkpfWlmKHE9PT0wKUMuTm0uaShzLG51bGwpCmVs
-c2UgQy5ObS5zQShzLDApCm8uYT1vLmI9bnVsbApyZXR1cm4gby5jPXR9LApmYjpmdW5jdGlvbihhKXt2
-YXIgdAppZighT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuYSxhKSlyZXR1
-cm4gbnVsbAp0PVAuUWUodGhpcy5hW2FdKQpyZXR1cm4gdGhpcy5iW2FdPXR9fQpQLmk4LnByb3RvdHlw
-ZT17CmdBOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5nQSh0KX0sCkU6ZnVuY3Rpb24o
-YSxiKXt2YXIgdD10aGlzLmEKaWYodC5iPT1udWxsKXQ9dC5nVigpLkUoMCxiKQplbHNle3Q9dC5DZigp
-CmlmKGI8MHx8Yj49dC5sZW5ndGgpcmV0dXJuIEguT0godCxiKQp0PXRbYl19cmV0dXJuIHR9LApna3o6
-ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCmlmKHQuYj09bnVsbCl7dD10LmdWKCkKdD10Lmdreih0KX1l
-bHNle3Q9dC5DZigpCnQ9bmV3IEoubTEodCx0Lmxlbmd0aCxILnQ2KHQpLkMoIm0xPDE+IikpfXJldHVy
-biB0fX0KUC5DVi5wcm90b3R5cGU9ewp5cjpmdW5jdGlvbihhLGEwLGExKXt2YXIgdCxzLHIscSxwLG8s
-bixtLGwsayxqLGksaCxnLGYsZSxkLGMsYj0iSW52YWxpZCBiYXNlNjQgZW5jb2RpbmcgbGVuZ3RoICIK
-YTE9UC5qQihhMCxhMSxhLmxlbmd0aCkKdD0kLlY3KCkKZm9yKHM9YTAscj1zLHE9bnVsbCxwPS0xLG89
-LTEsbj0wO3M8YTE7cz1tKXttPXMrMQpsPUMueEIuVyhhLHMpCmlmKGw9PT0zNyl7az1tKzIKaWYoazw9
-YTEpe2o9SC5vbyhDLnhCLlcoYSxtKSkKaT1ILm9vKEMueEIuVyhhLG0rMSkpCmg9aioxNitpLShpJjI1
-NikKaWYoaD09PTM3KWg9LTEKbT1rfWVsc2UgaD0tMX1lbHNlIGg9bAppZigwPD1oJiZoPD0xMjcpe2lm
-KGg8MHx8aD49dC5sZW5ndGgpcmV0dXJuIEguT0godCxoKQpnPXRbaF0KaWYoZz49MCl7aD1DLnhCLm0o
-IkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2
-Nzg5Ky8iLGcpCmlmKGg9PT1sKWNvbnRpbnVlCmw9aH1lbHNle2lmKGc9PT0tMSl7aWYocDwwKXtmPXE9
-PW51bGw/bnVsbDpxLmEubGVuZ3RoCmlmKGY9PW51bGwpZj0wCnA9Zisocy1yKQpvPXN9KytuCmlmKGw9
-PT02MSljb250aW51ZX1sPWh9aWYoZyE9PS0yKXtpZihxPT1udWxsKXE9bmV3IFAuUm4oIiIpCnEuYSs9
-Qy54Qi5OaihhLHIscykKcS5hKz1ILkx3KGwpCnI9bQpjb250aW51ZX19dGhyb3cgSC5iKFAucnIoIklu
-dmFsaWQgYmFzZTY0IGRhdGEiLGEscykpfWlmKHEhPW51bGwpe2Y9cS5hKz1DLnhCLk5qKGEscixhMSkK
-ZT1mLmxlbmd0aAppZihwPj0wKVAueE0oYSxvLGExLHAsbixlKQplbHNle2Q9Qy5qbi56WShlLTEsNCkr
-MQppZihkPT09MSl0aHJvdyBILmIoUC5ycihiLGEsYTEpKQpmb3IoO2Q8NDspe2YrPSI9IgpxLmE9Zjsr
-K2R9fWY9cS5hCnJldHVybiBDLnhCLmk3KGEsYTAsYTEsZi5jaGFyQ29kZUF0KDApPT0wP2Y6Zil9Yz1h
-MS1hMAppZihwPj0wKVAueE0oYSxvLGExLHAsbixjKQplbHNle2Q9Qy5qbi56WShjLDQpCmlmKGQ9PT0x
-KXRocm93IEguYihQLnJyKGIsYSxhMSkpCmlmKGQ+MSlhPUMueEIuaTcoYSxhMSxhMSxkPT09Mj8iPT0i
-OiI9Iil9cmV0dXJuIGF9fQpQLlU4LnByb3RvdHlwZT17fQpQLlVrLnByb3RvdHlwZT17fQpQLndJLnBy
-b3RvdHlwZT17fQpQLlppLnByb3RvdHlwZT17fQpQLmJ5LnByb3RvdHlwZT17CnBXOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgdAp1LmVwLmIoYykKdD1QLkJTKGIsdGhpcy5nSGUoKS5hKQpyZXR1cm4gdH0sCmdIZTpm
-dW5jdGlvbigpe3JldHVybiBDLkEzfX0KUC5NeC5wcm90b3R5cGU9e30KUC51NS5wcm90b3R5cGU9ewpn
-WkU6ZnVuY3Rpb24oKXtyZXR1cm4gQy5Ra319ClAuRTMucHJvdG90eXBlPXsKV0o6ZnVuY3Rpb24oYSl7
-dmFyIHQscyxyPVAuakIoMCxudWxsLGEubGVuZ3RoKSxxPXItMAppZihxPT09MClyZXR1cm4gbmV3IFVp
-bnQ4QXJyYXkoMCkKdD1uZXcgVWludDhBcnJheShxKjMpCnM9bmV3IFAuUncodCkKaWYocy5HeChhLDAs
-cikhPT1yKXMuTzYoSi5hNihhLHItMSksMCkKcmV0dXJuIG5ldyBVaW50OEFycmF5KHQuc3ViYXJyYXko
-MCxILnJNKDAscy5iLHQubGVuZ3RoKSkpfX0KUC5Sdy5wcm90b3R5cGU9ewpPNjpmdW5jdGlvbihhLGIp
-e3ZhciB0LHM9dGhpcyxyPXMuYyxxPXMuYixwPXErMSxvPXIubGVuZ3RoCmlmKChiJjY0NTEyKT09PTU2
-MzIwKXt0PTY1NTM2KygoYSYxMDIzKTw8MTApfGImMTAyMwpzLmI9cAppZihxPj1vKXJldHVybiBILk9I
-KHIscSkKcltxXT0yNDB8dD4+PjE4CnE9cy5iPXArMQppZihwPj1vKXJldHVybiBILk9IKHIscCkKcltw
-XT0xMjh8dD4+PjEyJjYzCnA9cy5iPXErMQppZihxPj1vKXJldHVybiBILk9IKHIscSkKcltxXT0xMjh8
-dD4+PjYmNjMKcy5iPXArMQppZihwPj1vKXJldHVybiBILk9IKHIscCkKcltwXT0xMjh8dCY2MwpyZXR1
-cm4hMH1lbHNle3MuYj1wCmlmKHE+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTIyNHxhPj4+MTIKcT1z
-LmI9cCsxCmlmKHA+PW8pcmV0dXJuIEguT0gocixwKQpyW3BdPTEyOHxhPj4+NiY2MwpzLmI9cSsxCmlm
-KHE+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTEyOHxhJjYzCnJldHVybiExfX0sCkd4OmZ1bmN0aW9u
-KGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtPXRoaXMKaWYoYiE9PWMmJihDLnhCLm0oYSxjLTEpJjY0
-NTEyKT09PTU1Mjk2KS0tYwpmb3IodD1tLmMscz10Lmxlbmd0aCxyPWI7cjxjOysrcil7cT1DLnhCLlco
-YSxyKQppZihxPD0xMjcpe3A9bS5iCmlmKHA+PXMpYnJlYWsKbS5iPXArMQp0W3BdPXF9ZWxzZSBpZigo
-cSY2NDUxMik9PT01NTI5Nil7aWYobS5iKzM+PXMpYnJlYWsKbz1yKzEKaWYobS5PNihxLEMueEIuVyhh
-LG8pKSlyPW99ZWxzZSBpZihxPD0yMDQ3KXtwPW0uYgpuPXArMQppZihuPj1zKWJyZWFrCm0uYj1uCmlm
-KHA+PXMpcmV0dXJuIEguT0godCxwKQp0W3BdPTE5MnxxPj4+NgptLmI9bisxCnRbbl09MTI4fHEmNjN9
-ZWxzZXtwPW0uYgppZihwKzI+PXMpYnJlYWsKbj1tLmI9cCsxCmlmKHA+PXMpcmV0dXJuIEguT0godCxw
-KQp0W3BdPTIyNHxxPj4+MTIKcD1tLmI9bisxCmlmKG4+PXMpcmV0dXJuIEguT0godCxuKQp0W25dPTEy
-OHxxPj4+NiY2MwptLmI9cCsxCmlmKHA+PXMpcmV0dXJuIEguT0godCxwKQp0W3BdPTEyOHxxJjYzfX1y
-ZXR1cm4gcn19ClAuR1kucHJvdG90eXBlPXsKV0o6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4s
-bSxsCnUuTC5iKGEpCnQ9UC5reSghMSxhLDAsbnVsbCkKaWYodCE9bnVsbClyZXR1cm4gdApzPVAuakIo
-MCxudWxsLEouSG0oYSkpCnI9UC5jUChhLDAscykKaWYocj4wKXtxPVAuSE0oYSwwLHIpCmlmKHI9PT1z
-KXJldHVybiBxCnA9bmV3IFAuUm4ocSkKbz1yCm49ITF9ZWxzZXtvPTAKcD1udWxsCm49ITB9aWYocD09
-bnVsbClwPW5ldyBQLlJuKCIiKQptPW5ldyBQLmJ6KCExLHApCm0uYz1uCm0uTUUoYSxvLHMpCmlmKG0u
-ZT4wKXtILnZoKFAucnIoIlVuZmluaXNoZWQgVVRGLTggb2N0ZXQgc2VxdWVuY2UiLGEscykpCnAuYSs9
-SC5Mdyg2NTUzMykKbS5mPW0uZT1tLmQ9MH1sPXAuYQpyZXR1cm4gbC5jaGFyQ29kZUF0KDApPT0wP2w6
-bH19ClAuYnoucHJvdG90eXBlPXsKTUU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0s
-bCxrLGosaSxoPXRoaXMsZz0iQmFkIFVURi04IGVuY29kaW5nIDB4Igp1LkwuYihhKQp0PWguZApzPWgu
-ZQpyPWguZgpoLmY9aC5lPWguZD0wCiRsYWJlbDAkMDpmb3IocT1KLlU2KGEpLHA9aC5iLG89YjshMDtv
-PWopeyRsYWJlbDEkMTppZihzPjApe2Rve2lmKG89PT1jKWJyZWFrICRsYWJlbDAkMApuPXEucShhLG8p
-CmlmKHR5cGVvZiBuIT09Im51bWJlciIpcmV0dXJuIG4uek0oKQppZigobiYxOTIpIT09MTI4KXttPVAu
-cnIoZytDLmpuLldaKG4sMTYpLGEsbykKdGhyb3cgSC5iKG0pfWVsc2V7dD0odDw8NnxuJjYzKT4+PjA7
-LS1zOysrb319d2hpbGUocz4wKQptPXItMQppZihtPDB8fG0+PTQpcmV0dXJuIEguT0goQy5HYixtKQpp
-Zih0PD1DLkdiW21dKXttPVAucnIoIk92ZXJsb25nIGVuY29kaW5nIG9mIDB4IitDLmpuLldaKHQsMTYp
-LGEsby1yLTEpCnRocm93IEguYihtKX1pZih0PjExMTQxMTEpe209UC5ycigiQ2hhcmFjdGVyIG91dHNp
-ZGUgdmFsaWQgVW5pY29kZSByYW5nZTogMHgiK0Muam4uV1oodCwxNiksYSxvLXItMSkKdGhyb3cgSC5i
-KG0pfWlmKCFoLmN8fHQhPT02NTI3OSlwLmErPUguTHcodCkKaC5jPSExfWZvcihtPW88YzttOyl7bD1Q
-LmNQKGEsbyxjKQppZihsPjApe2guYz0hMQprPW8rbApwLmErPVAuSE0oYSxvLGspCmlmKGs9PT1jKWJy
-ZWFrfWVsc2Ugaz1vCmo9aysxCm49cS5xKGEsaykKaWYodHlwZW9mIG4hPT0ibnVtYmVyIilyZXR1cm4g
-bi5KKCkKaWYobjwwKXtpPVAucnIoIk5lZ2F0aXZlIFVURi04IGNvZGUgdW5pdDogLTB4IitDLmpuLlda
-KC1uLDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfWVsc2V7aWYoKG4mMjI0KT09PTE5Mil7dD1uJjMxCnM9
-MQpyPTEKY29udGludWUgJGxhYmVsMCQwfWlmKChuJjI0MCk9PT0yMjQpe3Q9biYxNQpzPTIKcj0yCmNv
-bnRpbnVlICRsYWJlbDAkMH1pZigobiYyNDgpPT09MjQwJiZuPDI0NSl7dD1uJjcKcz0zCnI9Mwpjb250
-aW51ZSAkbGFiZWwwJDB9aT1QLnJyKGcrQy5qbi5XWihuLDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfX1i
-cmVhayAkbGFiZWwwJDB9aWYocz4wKXtoLmQ9dApoLmU9cwpoLmY9cn19fQpQLldGLnByb3RvdHlwZT17
-CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCnUuZm8uYihhKQp0PXRoaXMuYgpzPXRoaXMuYQp0LmEr
-PXMuYQpyPXQuYSs9SC5kKGEuYSkKdC5hPXIrIjogIgp0LmErPVAucChiKQpzLmE9IiwgIn0sCiRTOjMy
-fQpQLmEyLnByb3RvdHlwZT17fQpQLmlQLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7aWYoYj09
-bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIFAuaVAmJnRoaXMuYT09PWIuYSYmITB9LApn
-aU86ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybih0XkMuam4ud0codCwzMCkpJjEwNzM3NDE4
-MjN9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1QLkdxKEgudEoodCkpLHI9UC5oMChILk5TKHQp
-KSxxPVAuaDAoSC5qQSh0KSkscD1QLmgwKEguS0wodCkpLG89UC5oMChILmNoKHQpKSxuPVAuaDAoSC5K
-ZCh0KSksbT1QLlZ4KEgubzEodCkpLGw9cysiLSIrcisiLSIrcSsiICIrcCsiOiIrbysiOiIrbisiLiIr
-bQpyZXR1cm4gbH19ClAuQ1AucHJvdG90eXBlPXt9ClAuWFMucHJvdG90eXBlPXt9ClAuQzYucHJvdG90
-eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKaWYodCE9bnVsbClyZXR1cm4iQXNzZXJ0aW9u
-IGZhaWxlZDogIitQLnAodCkKcmV0dXJuIkFzc2VydGlvbiBmYWlsZWQifX0KUC5uLnByb3RvdHlwZT17
-Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlRocm93IG9mIG51bGwuIn19ClAudS5wcm90b3R5cGU9ewpnWjpm
-dW5jdGlvbigpe3JldHVybiJJbnZhbGlkIGFyZ3VtZW50IisoIXRoaXMuYT8iKHMpIjoiIil9LApndTpm
-dW5jdGlvbigpe3JldHVybiIifSwKdzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwPXRoaXMsbz1wLmMs
-bj1vIT1udWxsPyIgKCIrbysiKSI6IiIKbz1wLmQKdD1vPT1udWxsPyIiOiI6ICIrSC5kKG8pCnM9cC5n
-WigpK24rdAppZighcC5hKXJldHVybiBzCnI9cC5ndSgpCnE9UC5wKHAuYikKcmV0dXJuIHMrcisiOiAi
-K3F9fQpQLmJKLnByb3RvdHlwZT17CmdaOmZ1bmN0aW9uKCl7cmV0dXJuIlJhbmdlRXJyb3IifSwKZ3U6
-ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcy5lCmlmKHI9PW51bGwpe3I9dGhpcy5mCnQ9ciE9bnVsbD8i
-OiBOb3QgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICIrSC5kKHIpOiIifWVsc2V7cz10aGlzLmYKaWYocz09
-bnVsbCl0PSI6IE5vdCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gIitILmQocikKZWxzZSBpZihzPnIp
-dD0iOiBOb3QgaW4gcmFuZ2UgIitILmQocikrIi4uIitILmQocykrIiwgaW5jbHVzaXZlIgplbHNlIHQ9
-czxyPyI6IFZhbGlkIHZhbHVlIHJhbmdlIGlzIGVtcHR5IjoiOiBPbmx5IHZhbGlkIHZhbHVlIGlzICIr
-SC5kKHIpfXJldHVybiB0fX0KUC5lWS5wcm90b3R5cGU9ewpnWjpmdW5jdGlvbigpe3JldHVybiJSYW5n
-ZUVycm9yIn0sCmd1OmZ1bmN0aW9uKCl7dmFyIHQscz1ILlNjKHRoaXMuYikKaWYodHlwZW9mIHMhPT0i
-bnVtYmVyIilyZXR1cm4gcy5KKCkKaWYoczwwKXJldHVybiI6IGluZGV4IG11c3Qgbm90IGJlIG5lZ2F0
-aXZlIgp0PXRoaXMuZgppZih0PT09MClyZXR1cm4iOiBubyBpbmRpY2VzIGFyZSB2YWxpZCIKcmV0dXJu
-IjogaW5kZXggc2hvdWxkIGJlIGxlc3MgdGhhbiAiK0guZCh0KX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVy
-biB0aGlzLmZ9fQpQLm1wLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4s
-bSxsPXRoaXMsaz17fSxqPW5ldyBQLlJuKCIiKQprLmE9IiIKZm9yKHQ9bC5jLHM9dC5sZW5ndGgscj0w
-LHE9IiIscD0iIjtyPHM7KytyLHA9IiwgIil7bz10W3JdCmouYT1xK3AKcT1qLmErPVAucChvKQprLmE9
-IiwgIn1sLmQuSygwLG5ldyBQLldGKGssaikpCm49UC5wKGwuYSkKbT1qLncoMCkKdD0iTm9TdWNoTWV0
-aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK0guZChsLmIuYSkrIidcblJlY2VpdmVyOiAiK24r
-IlxuQXJndW1lbnRzOiBbIittKyJdIgpyZXR1cm4gdH19ClAudWIucHJvdG90eXBlPXsKdzpmdW5jdGlv
-bihhKXtyZXR1cm4iVW5zdXBwb3J0ZWQgb3BlcmF0aW9uOiAiK3RoaXMuYX19ClAuZHMucHJvdG90eXBl
-PXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQhPW51bGw/IlVuaW1wbGVtZW50ZWRF
-cnJvcjogIit0OiJVbmltcGxlbWVudGVkRXJyb3IifX0KUC5sai5wcm90b3R5cGU9ewp3OmZ1bmN0aW9u
-KGEpe3JldHVybiJCYWQgc3RhdGU6ICIrdGhpcy5hfX0KUC5VVi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9u
-KGEpe3ZhciB0PXRoaXMuYQppZih0PT1udWxsKXJldHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBk
-dXJpbmcgaXRlcmF0aW9uLiIKcmV0dXJuIkNvbmN1cnJlbnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVy
-YXRpb246ICIrUC5wKHQpKyIuIn19ClAuazUucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4i
-T3V0IG9mIE1lbW9yeSJ9LAokaVhTOjF9ClAuS1kucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1
-cm4iU3RhY2sgT3ZlcmZsb3cifSwKJGlYUzoxfQpQLmMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2
-YXIgdD10aGlzLmEKcmV0dXJuIHQ9PW51bGw/IlJlYWRpbmcgc3RhdGljIHZhcmlhYmxlIGR1cmluZyBp
-dHMgaW5pdGlhbGl6YXRpb24iOiJSZWFkaW5nIHN0YXRpYyB2YXJpYWJsZSAnIit0KyInIGR1cmluZyBp
-dHMgaW5pdGlhbGl6YXRpb24ifX0KUC5DRC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJF
-eGNlcHRpb246ICIrdGhpcy5hfX0KUC5hRS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMs
-cixxLHAsbyxuLG0sbCxrLGosaSxoPXRoaXMuYSxnPWghPW51bGwmJiIiIT09aD8iRm9ybWF0RXhjZXB0
-aW9uOiAiK0guZChoKToiRm9ybWF0RXhjZXB0aW9uIixmPXRoaXMuYyxlPXRoaXMuYgppZih0eXBlb2Yg
-ZT09InN0cmluZyIpe2lmKGYhPW51bGwpaD1mPDB8fGY+ZS5sZW5ndGgKZWxzZSBoPSExCmlmKGgpZj1u
-dWxsCmlmKGY9PW51bGwpe3Q9ZS5sZW5ndGg+Nzg/Qy54Qi5OaihlLDAsNzUpKyIuLi4iOmUKcmV0dXJu
-IGcrIlxuIit0fWZvcihzPTEscj0wLHE9ITEscD0wO3A8ZjsrK3Ape289Qy54Qi5XKGUscCkKaWYobz09
-PTEwKXtpZihyIT09cHx8IXEpKytzCnI9cCsxCnE9ITF9ZWxzZSBpZihvPT09MTMpeysrcwpyPXArMQpx
-PSEwfX1nPXM+MT9nKygiIChhdCBsaW5lICIrcysiLCBjaGFyYWN0ZXIgIisoZi1yKzEpKyIpXG4iKTpn
-KygiIChhdCBjaGFyYWN0ZXIgIisoZisxKSsiKVxuIikKbj1lLmxlbmd0aApmb3IocD1mO3A8bjsrK3Ap
-e289Qy54Qi5tKGUscCkKaWYobz09PTEwfHxvPT09MTMpe249cApicmVha319aWYobi1yPjc4KWlmKGYt
-cjw3NSl7bT1yKzc1Cmw9cgprPSIiCmo9Ii4uLiJ9ZWxzZXtpZihuLWY8NzUpe2w9bi03NQptPW4Kaj0i
-In1lbHNle2w9Zi0zNgptPWYrMzYKaj0iLi4uIn1rPSIuLi4ifWVsc2V7bT1uCmw9cgprPSIiCmo9IiJ9
-aT1DLnhCLk5qKGUsbCxtKQpyZXR1cm4gZytrK2kraisiXG4iK0MueEIuSXgoIiAiLGYtbCtrLmxlbmd0
-aCkrIl5cbiJ9ZWxzZSByZXR1cm4gZiE9bnVsbD9nKygiIChhdCBvZmZzZXQgIitILmQoZikrIikiKTpn
-fX0KUC5FSC5wcm90b3R5cGU9e30KUC5LTi5wcm90b3R5cGU9e30KUC5jWC5wcm90b3R5cGU9ewpldjpm
-dW5jdGlvbihhLGIpe3ZhciB0PUguTGgodGhpcykKcmV0dXJuIG5ldyBILlU1KHRoaXMsdC5DKCJhMihj
-WC5FKSIpLmIoYiksdC5DKCJVNTxjWC5FPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5n
-a3oodGhpcykKZm9yKHQ9MDtzLkYoKTspKyt0CnJldHVybiB0fSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVy
-biF0aGlzLmdreih0aGlzKS5GKCl9LApncjg6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmdreih0aGlz
-KQppZighcy5GKCkpdGhyb3cgSC5iKEguV3AoKSkKdD1zLmdsKCkKaWYocy5GKCkpdGhyb3cgSC5iKEgu
-ZFUoKSkKcmV0dXJuIHR9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyClAuazEoYiwiaW5kZXgiKQpm
-b3IodD10aGlzLmdreih0aGlzKSxzPTA7dC5GKCk7KXtyPXQuZ2woKQppZihiPT09cylyZXR1cm4gcjsr
-K3N9dGhyb3cgSC5iKFAuQ2YoYix0aGlzLCJpbmRleCIsbnVsbCxzKSl9LAp3OmZ1bmN0aW9uKGEpe3Jl
-dHVybiBQLkVQKHRoaXMsIigiLCIpIil9fQpQLkFuLnByb3RvdHlwZT17fQpQLnpNLnByb3RvdHlwZT17
-JGljWDoxfQpQLlowLnByb3RvdHlwZT17fQpQLmM4LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXty
-ZXR1cm4gUC5rLnByb3RvdHlwZS5naU8uY2FsbCh0aGlzLHRoaXMpfSwKdzpmdW5jdGlvbihhKXtyZXR1
-cm4ibnVsbCJ9fQpQLkZLLnByb3RvdHlwZT17fQpQLmsucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpQLmss
-JGlrOjEsCkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXM9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBILmVRKHRoaXMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5kKEgu
-TSh0aGlzKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt1Lm8uYihiKQp0aHJvdyBILmIoUC5scih0aGlz
-LGIuZ1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9LAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiB0aGlz
-LncodGhpcyl9fQpQLk9kLnByb3RvdHlwZT17fQpQLmliLnByb3RvdHlwZT17JGlPZDoxfQpQLnh1LnBy
-b3RvdHlwZT17fQpQLkd6LnByb3RvdHlwZT17fQpQLnFVLnByb3RvdHlwZT17JGl2WDoxfQpQLlJuLnBy
-b3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKdzpmdW5jdGlvbihh
-KXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuY2hhckNvZGVBdCgwKT09MD90OnR9LAokaUJMOjF9ClAuR0Qu
-cHJvdG90eXBlPXt9ClAubjEucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1
-LmYuYihhKQpILnkoYikKdD1KLnJZKGIpLk9ZKGIsIj0iKQppZih0PT09LTEpe2lmKGIhPT0iIilhLlko
-MCxQLmt1KGIsMCxiLmxlbmd0aCx0aGlzLmEsITApLCIiKX1lbHNlIGlmKHQhPT0wKXtzPUMueEIuTmoo
-YiwwLHQpCnI9Qy54Qi5HKGIsdCsxKQpxPXRoaXMuYQphLlkoMCxQLmt1KHMsMCxzLmxlbmd0aCxxLCEw
-KSxQLmt1KHIsMCxyLmxlbmd0aCxxLCEwKSl9cmV0dXJuIGF9LAokUzozOX0KUC5jUy5wcm90b3R5cGU9
-ewokMjpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLnJyKCJJbGxlZ2FsIElQdjQgYWRkcmVzcywgIith
-LHRoaXMuYSxiKSl9LAokUzoyOX0KUC5WQy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Rocm93
-IEguYihQLnJyKCJJbGxlZ2FsIElQdjYgYWRkcmVzcywgIithLHRoaXMuYSxiKSl9LAokMTpmdW5jdGlv
-bihhKXtyZXR1cm4gdGhpcy4kMihhLG51bGwpfSwKJFM6MjZ9ClAudHAucHJvdG90eXBlPXsKJDI6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdAppZihiLWE+NCl0aGlzLmEuJDIoImFuIElQdjYgcGFydCBjYW4gb25seSBj
-b250YWluIGEgbWF4aW11bSBvZiA0IGhleCBkaWdpdHMiLGEpCnQ9UC5RQShDLnhCLk5qKHRoaXMuYixh
-LGIpLG51bGwsMTYpCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigpCmlmKHQ8MHx8dD42
-NTUzNSl0aGlzLmEuJDIoImVhY2ggcGFydCBtdXN0IGJlIGluIHRoZSByYW5nZSBvZiBgMHgwLi4weEZG
-RkZgIixhKQpyZXR1cm4gdH0sCiRTOjE5fQpQLkRuLnByb3RvdHlwZT17CmdrdTpmdW5jdGlvbigpe3Jl
-dHVybiB0aGlzLmJ9LApnSmY6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jCmlmKHQ9PW51bGwpcmV0dXJu
-IiIKaWYoQy54Qi5uKHQsIlsiKSlyZXR1cm4gQy54Qi5Oaih0LDEsdC5sZW5ndGgtMSkKcmV0dXJuIHR9
-LApndHA6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5kCmlmKHQ9PW51bGwpcmV0dXJuIFAud0sodGhpcy5h
-KQpyZXR1cm4gdH0sCmd0UDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZgpyZXR1cm4gdD09bnVsbD8iIjp0
-fSwKZ0thOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5yCnJldHVybiB0PT1udWxsPyIiOnR9LApubTpmdW5j
-dGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10aGlzCnUuWC5iKG51bGwpCnUuYi5iKGIpCnQ9
-bC5hCnM9dD09PSJmaWxlIgpyPWwuYgpxPWwuZApwPWwuYwppZighKHAhPW51bGwpKXA9ci5sZW5ndGgh
-PT0wfHxxIT1udWxsfHxzPyIiOm51bGwKbz1sLmUKaWYoIXMpbj1wIT1udWxsJiZvLmxlbmd0aCE9PTAK
-ZWxzZSBuPSEwCmlmKG4mJiFDLnhCLm4obywiLyIpKW89Ii8iK28KaWYoYiE9bnVsbCltPVAubGUobnVs
-bCwwLDAsYikKZWxzZSBtPWwuZgpyZXR1cm4gbmV3IFAuRG4odCxyLHAscSxvLG0sbC5yKX0sCmdGajpm
-dW5jdGlvbigpe3ZhciB0LHM9dGhpcy54CmlmKHMhPW51bGwpcmV0dXJuIHMKdD10aGlzLmUKaWYodC5s
-ZW5ndGghPT0wJiZDLnhCLlcodCwwKT09PTQ3KXQ9Qy54Qi5HKHQsMSkKcz10PT09IiI/Qy5kbjpQLkFG
-KG5ldyBILkE4KEguVk0odC5zcGxpdCgiLyIpLHUucyksdS5kTy5iKFAuUEgoKSksdS5kbyksdS5OKQp0
-aGlzLnNvNihzKQpyZXR1cm4gc30sCmdoWTpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcwppZihzLlE9PW51
-bGwpe3Q9cy5mCnMuc1JIKG5ldyBQLkdqKFAuV1godD09bnVsbD8iIjp0KSx1LlQpKX1yZXR1cm4gcy5R
-fSwKSmg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8KZm9yKHQ9MCxzPTA7Qy54Qi5RaShiLCIu
-Li8iLHMpOyl7cys9MzsrK3R9cj1DLnhCLmNuKGEsIi8iKQp3aGlsZSghMCl7aWYoIShyPjAmJnQ+MCkp
-YnJlYWsKcT1DLnhCLlBrKGEsIi8iLHItMSkKaWYocTwwKWJyZWFrCnA9ci1xCm89cCE9PTIKaWYoIW98
-fHA9PT0zKWlmKEMueEIubShhLHErMSk9PT00NilvPSFvfHxDLnhCLm0oYSxxKzIpPT09NDYKZWxzZSBv
-PSExCmVsc2Ugbz0hMQppZihvKWJyZWFrOy0tdApyPXF9cmV0dXJuIEMueEIuaTcoYSxyKzEsbnVsbCxD
-LnhCLkcoYixzLTMqdCkpfSwKWkk6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LApt
-UzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsaz10aGlzLGo9bnVsbAppZihhLmdGaSgp
-Lmxlbmd0aCE9PTApe3Q9YS5nRmkoKQppZihhLmdjaigpKXtzPWEuZ2t1KCkKcj1hLmdKZihhKQpxPWEu
-Z3hBKCk/YS5ndHAoYSk6an1lbHNle3E9agpyPXEKcz0iIn1wPVAueGUoYS5nSWkoYSkpCm89YS5nUUQo
-KT9hLmd0UCgpOmp9ZWxzZXt0PWsuYQppZihhLmdjaigpKXtzPWEuZ2t1KCkKcj1hLmdKZihhKQpxPVAu
-d0IoYS5neEEoKT9hLmd0cChhKTpqLHQpCnA9UC54ZShhLmdJaShhKSkKbz1hLmdRRCgpP2EuZ3RQKCk6
-an1lbHNle3M9ay5iCnI9ay5jCnE9ay5kCmlmKGEuZ0lpKGEpPT09IiIpe3A9ay5lCm89YS5nUUQoKT9h
-Lmd0UCgpOmsuZn1lbHNle2lmKGEuZ3RUKCkpcD1QLnhlKGEuZ0lpKGEpKQplbHNle249ay5lCmlmKG4u
-bGVuZ3RoPT09MClpZihyPT1udWxsKXA9dC5sZW5ndGg9PT0wP2EuZ0lpKGEpOlAueGUoYS5nSWkoYSkp
-CmVsc2UgcD1QLnhlKCIvIithLmdJaShhKSkKZWxzZXttPWsuSmgobixhLmdJaShhKSkKbD10Lmxlbmd0
-aD09PTAKaWYoIWx8fHIhPW51bGx8fEMueEIubihuLCIvIikpcD1QLnhlKG0pCmVsc2UgcD1QLndGKG0s
-IWx8fHIhPW51bGwpfX1vPWEuZ1FEKCk/YS5ndFAoKTpqfX19cmV0dXJuIG5ldyBQLkRuKHQscyxyLHEs
-cCxvLGEuZ1o4KCk/YS5nS2EoKTpqKX0sCmdjajpmdW5jdGlvbigpe3JldHVybiB0aGlzLmMhPW51bGx9
-LApneEE6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kIT1udWxsfSwKZ1FEOmZ1bmN0aW9uKCl7cmV0dXJu
-IHRoaXMuZiE9bnVsbH0sCmdaODpmdW5jdGlvbigpe3JldHVybiB0aGlzLnIhPW51bGx9LApndFQ6ZnVu
-Y3Rpb24oKXtyZXR1cm4gQy54Qi5uKHRoaXMuZSwiLyIpfSwKdDQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9
-dGhpcyxxPXIuYQppZihxIT09IiImJnEhPT0iZmlsZSIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRy
-YWN0IGEgZmlsZSBwYXRoIGZyb20gYSAiK0guZChxKSsiIFVSSSIpKQpxPXIuZgppZigocT09bnVsbD8i
-IjpxKSE9PSIiKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEg
-VVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQiKSkKcT1yLnIKaWYoKHE9PW51bGw/IiI6cSkhPT0iIil0
-aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEg
-ZnJhZ21lbnQgY29tcG9uZW50IikpCnQ9JC53USgpCmlmKEgub1QodCkpcT1QLm1uKHIpCmVsc2V7aWYo
-ci5jIT1udWxsJiZyLmdKZihyKSE9PSIiKUgudmgoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBub24tV2lu
-ZG93cyBmaWxlIHBhdGggZnJvbSBhIGZpbGUgVVJJIHdpdGggYW4gYXV0aG9yaXR5IikpCnM9ci5nRmoo
-KQpQLmtFKHMsITEpCnE9UC52ZyhDLnhCLm4oci5lLCIvIik/Ii8iOiIiLHMsIi8iKQpxPXEuY2hhckNv
-ZGVBdCgwKT09MD9xOnF9cmV0dXJuIHF9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPXRoaXMscD1x
-LnkKaWYocD09bnVsbCl7cD1xLmEKdD1wLmxlbmd0aCE9PTA/cCsiOiI6IiIKcz1xLmMKcj1zPT1udWxs
-CmlmKCFyfHxwPT09ImZpbGUiKXtwPXQrIi8vIgp0PXEuYgppZih0Lmxlbmd0aCE9PTApcD1wK3QrIkAi
-CmlmKCFyKXArPXMKdD1xLmQKaWYodCE9bnVsbClwPXArIjoiK0guZCh0KX1lbHNlIHA9dApwKz1xLmUK
-dD1xLmYKaWYodCE9bnVsbClwPXArIj8iK3QKdD1xLnIKaWYodCE9bnVsbClwPXArIiMiK3QKcD1xLnk9
-cC5jaGFyQ29kZUF0KDApPT0wP3A6cH1yZXR1cm4gcH0sCkROOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxy
-PXRoaXMKaWYoYj09bnVsbClyZXR1cm4hMQppZihyPT09YilyZXR1cm4hMAppZih1LkQuYyhiKSlpZihy
-LmE9PWIuZ0ZpKCkpaWYoci5jIT1udWxsPT09Yi5nY2ooKSlpZihyLmI9PWIuZ2t1KCkpaWYoci5nSmYo
-cik9PWIuZ0pmKGIpKWlmKHIuZ3RwKHIpPT1iLmd0cChiKSlpZihyLmU9PT1iLmdJaShiKSl7dD1yLmYK
-cz10PT1udWxsCmlmKCFzPT09Yi5nUUQoKSl7aWYocyl0PSIiCmlmKHQ9PT1iLmd0UCgpKXt0PXIucgpz
-PXQ9PW51bGwKaWYoIXM9PT1iLmdaOCgpKXtpZihzKXQ9IiIKdD10PT09Yi5nS2EoKX1lbHNlIHQ9ITF9
-ZWxzZSB0PSExfWVsc2UgdD0hMX1lbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEK
-ZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKcmV0dXJuIHR9LApnaU86ZnVuY3Rpb24oYSl7dmFy
-IHQ9dGhpcy56CnJldHVybiB0PT1udWxsP3RoaXMuej1DLnhCLmdpTyh0aGlzLncoMCkpOnR9LApzbzY6
-ZnVuY3Rpb24oYSl7dGhpcy54PXUuYS5iKGEpfSwKc1JIOmZ1bmN0aW9uKGEpe3RoaXMuUT11LmYuYihh
-KX0sCiRpaUQ6MSwKZ0ZpOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYX0sCmdJaTpmdW5jdGlvbihhKXty
-ZXR1cm4gdGhpcy5lfX0KUC5lMS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt0aHJvdyBILmIoUC5y
-cigiSW52YWxpZCBwb3J0Iix0aGlzLmEsdGhpcy5iKzEpKX0sCiRTOjExfQpQLk5ZLnByb3RvdHlwZT17
-CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PSJJbGxlZ2FsIHBhdGggY2hhcmFjdGVyICIKSC55KGEpCmlmKEou
-emwoYSwiLyIpKWlmKHRoaXMuYSl0aHJvdyBILmIoUC54WSh0K2EpKQplbHNlIHRocm93IEguYihQLkw0
-KHQrYSkpfSwKJFM6MTF9ClAuUloucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuZVAo
-Qy5aSixhLEMueE0sITEpfSwKJFM6NX0KUC5NRS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Zh
-ciB0PXRoaXMuYixzPXRoaXMuYQp0LmErPXMuYQpzLmE9IiYiCnM9dC5hKz1ILmQoUC5lUChDLkYzLGEs
-Qy54TSwhMCkpCmlmKGIhPW51bGwmJmIubGVuZ3RoIT09MCl7dC5hPXMrIj0iCnQuYSs9SC5kKFAuZVAo
-Qy5GMyxiLEMueE0sITApKX19LAokUzoyMn0KUC55NS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIp
-e3ZhciB0LHMKSC55KGEpCmlmKGI9PW51bGx8fHR5cGVvZiBiPT0ic3RyaW5nIil0aGlzLmEuJDIoYSxI
-LnkoYikpCmVsc2UgZm9yKHQ9Si5JVCh1LlIuYihiKSkscz10aGlzLmE7dC5GKCk7KXMuJDIoYSxILnko
-dC5nbCgpKSl9LAokUzoxMn0KUC5QRS5wcm90b3R5cGU9ewpnbFI6ZnVuY3Rpb24oKXt2YXIgdCxzLHIs
-cSxwPXRoaXMsbz1udWxsLG49cC5jCmlmKG4hPW51bGwpcmV0dXJuIG4Kbj1wLmIKaWYoMD49bi5sZW5n
-dGgpcmV0dXJuIEguT0gobiwwKQp0PXAuYQpuPW5bMF0rMQpzPUMueEIuWFUodCwiPyIsbikKcj10Lmxl
-bmd0aAppZihzPj0wKXtxPVAudU8odCxzKzEscixDLlZDLCExKQpyPXN9ZWxzZSBxPW8KcmV0dXJuIHAu
-Yz1uZXcgUC5xZSgiZGF0YSIsbyxvLG8sUC51Tyh0LG4scixDLldkLCExKSxxLG8pfSwKdzpmdW5jdGlv
-bihhKXt2YXIgdCxzPXRoaXMuYgppZigwPj1zLmxlbmd0aClyZXR1cm4gSC5PSChzLDApCnQ9dGhpcy5h
-CnJldHVybiBzWzBdPT09LTE/ImRhdGE6Iit0OnR9fQpQLnEzLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9u
-KGEpe3JldHVybiBuZXcgVWludDhBcnJheSg5Nil9LAokUzo0Nn0KUC55SS5wcm90b3R5cGU9ewokMjpm
-dW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZihhPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGEpCnQ9
-dFthXQpKLkNNKHQsMCw5NixiKQpyZXR1cm4gdH0sCiRTOjI0fQpQLmM2LnByb3RvdHlwZT17CiQzOmZ1
-bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscQpmb3IodD1iLmxlbmd0aCxzPWEubGVuZ3RoLHI9MDtyPHQ7
-KytyKXtxPUMueEIuVyhiLHIpXjk2CmlmKHE+PXMpcmV0dXJuIEguT0goYSxxKQphW3FdPWN9fX0KUC5x
-ZC5wcm90b3R5cGU9ewokMzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKZm9yKHQ9Qy54Qi5XKGIs
-MCkscz1DLnhCLlcoYiwxKSxyPWEubGVuZ3RoO3Q8PXM7Kyt0KXtxPSh0Xjk2KT4+PjAKaWYocT49cily
-ZXR1cm4gSC5PSChhLHEpCmFbcV09Y319fQpQLlVmLnByb3RvdHlwZT17CmdjajpmdW5jdGlvbigpe3Jl
-dHVybiB0aGlzLmM+MH0sCmd4QTpmdW5jdGlvbigpe3ZhciB0LHMKaWYodGhpcy5jPjApe3Q9dGhpcy5k
-CmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCnM9dGhpcy5lCmlmKHR5cGVvZiBzIT09
-Im51bWJlciIpcmV0dXJuIEgucFkocykKcz10KzE8cwp0PXN9ZWxzZSB0PSExCnJldHVybiB0fSwKZ1FE
-OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5mCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigp
-CnJldHVybiB0PHRoaXMucn0sCmdaODpmdW5jdGlvbigpe3JldHVybiB0aGlzLnI8dGhpcy5hLmxlbmd0
-aH0sCmdOdzpmdW5jdGlvbigpe3JldHVybiB0aGlzLmI9PT00JiZDLnhCLm4odGhpcy5hLCJmaWxlIil9
-LApndmg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09NCYmQy54Qi5uKHRoaXMuYSwiaHR0cCIpfSwK
-Z3FCOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYj09PTUmJkMueEIubih0aGlzLmEsImh0dHBzIil9LApn
-dFQ6ZnVuY3Rpb24oKXtyZXR1cm4gQy54Qi5RaSh0aGlzLmEsIi8iLHRoaXMuZSl9LApnRmk6ZnVuY3Rp
-b24oKXt2YXIgdCxzPXRoaXMscj0icGFja2FnZSIscT1zLmIKaWYocTw9MClyZXR1cm4iIgp0PXMueApp
-Zih0IT1udWxsKXJldHVybiB0CmlmKHMuZ3ZoKCkpcT1zLng9Imh0dHAiCmVsc2UgaWYocy5ncUIoKSl7
-cy54PSJodHRwcyIKcT0iaHR0cHMifWVsc2UgaWYocy5nTncoKSl7cy54PSJmaWxlIgpxPSJmaWxlIn1l
-bHNlIGlmKHE9PT03JiZDLnhCLm4ocy5hLHIpKXtzLng9cgpxPXJ9ZWxzZXtxPUMueEIuTmoocy5hLDAs
-cSkKcy54PXF9cmV0dXJuIHF9LApna3U6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmMscz10aGlzLmIrMwpy
-ZXR1cm4gdD5zP0MueEIuTmoodGhpcy5hLHMsdC0xKToiIn0sCmdKZjpmdW5jdGlvbihhKXt2YXIgdD10
-aGlzLmMKcmV0dXJuIHQ+MD9DLnhCLk5qKHRoaXMuYSx0LHRoaXMuZCk6IiJ9LApndHA6ZnVuY3Rpb24o
-YSl7dmFyIHQscz10aGlzCmlmKHMuZ3hBKCkpe3Q9cy5kCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0
-dXJuIHQuaCgpCnJldHVybiBQLlFBKEMueEIuTmoocy5hLHQrMSxzLmUpLG51bGwsbnVsbCl9aWYocy5n
-dmgoKSlyZXR1cm4gODAKaWYocy5ncUIoKSlyZXR1cm4gNDQzCnJldHVybiAwfSwKZ0lpOmZ1bmN0aW9u
-KGEpe3JldHVybiBDLnhCLk5qKHRoaXMuYSx0aGlzLmUsdGhpcy5mKX0sCmd0UDpmdW5jdGlvbigpe3Zh
-ciB0PXRoaXMuZixzPXRoaXMucgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQpyZXR1
-cm4gdDxzP0MueEIuTmoodGhpcy5hLHQrMSxzKToiIn0sCmdLYTpmdW5jdGlvbigpe3ZhciB0PXRoaXMu
-cixzPXRoaXMuYQpyZXR1cm4gdDxzLmxlbmd0aD9DLnhCLkcocyx0KzEpOiIifSwKZ0ZqOmZ1bmN0aW9u
-KCl7dmFyIHQscyxyPXRoaXMuZSxxPXRoaXMuZixwPXRoaXMuYQppZihDLnhCLlFpKHAsIi8iLHIpKXtp
-Zih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLmgoKTsrK3J9aWYocj09cSlyZXR1cm4gQy5kbgp0
-PUguVk0oW10sdS5zKQpzPXIKd2hpbGUoITApe2lmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMu
-SigpCmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJuIEgucFkocSkKaWYoIShzPHEpKWJyZWFrCmlm
-KEMueEIubShwLHMpPT09NDcpe0MuTm0uaSh0LEMueEIuTmoocCxyLHMpKQpyPXMrMX0rK3N9Qy5ObS5p
-KHQsQy54Qi5OaihwLHIscSkpCnJldHVybiBQLkFGKHQsdS5OKX0sCmdoWTpmdW5jdGlvbigpe3ZhciB0
-PXRoaXMuZgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQppZih0Pj10aGlzLnIpcmV0
-dXJuIEMuV08KcmV0dXJuIG5ldyBQLkdqKFAuV1godGhpcy5ndFAoKSksdS5UKX0sCmtYOmZ1bmN0aW9u
-KGEpe3ZhciB0LHM9dGhpcy5kCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuaCgpCnQ9cysx
-CnJldHVybiB0K2EubGVuZ3RoPT09dGhpcy5lJiZDLnhCLlFpKHRoaXMuYSxhLHQpfSwKTjk6ZnVuY3Rp
-b24oKXt2YXIgdD10aGlzLHM9dC5yLHI9dC5hCmlmKHM+PXIubGVuZ3RoKXJldHVybiB0CnJldHVybiBu
-ZXcgUC5VZihDLnhCLk5qKHIsMCxzKSx0LmIsdC5jLHQuZCx0LmUsdC5mLHMsdC54KX0sCm5tOmZ1bmN0
-aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpPXRoaXMsaD1udWxsCnUuWC5iKG51bGwp
-CnUuYi5iKGIpCnQ9aS5nRmkoKQpzPXQ9PT0iZmlsZSIKcj1pLmMKcT1yPjA/Qy54Qi5OaihpLmEsaS5i
-KzMscik6IiIKcD1pLmd4QSgpP2kuZ3RwKGkpOmgKcj1pLmMKaWYocj4wKW89Qy54Qi5OaihpLmEscixp
-LmQpCmVsc2Ugbz1xLmxlbmd0aCE9PTB8fHAhPW51bGx8fHM/IiI6aApyPWkuYQpuPWkuZgptPUMueEIu
-TmoocixpLmUsbikKaWYoIXMpbD1vIT1udWxsJiZtLmxlbmd0aCE9PTAKZWxzZSBsPSEwCmlmKGwmJiFD
-LnhCLm4obSwiLyIpKW09Ii8iK20KaWYoYiE9bnVsbClrPVAubGUoaCwwLDAsYikKZWxzZXtsPWkucgpp
-Zih0eXBlb2YgbiE9PSJudW1iZXIiKXJldHVybiBuLkooKQprPW48bD9DLnhCLk5qKHIsbisxLGwpOmh9
-bj1pLnIKaj1uPHIubGVuZ3RoP0MueEIuRyhyLG4rMSk6aApyZXR1cm4gbmV3IFAuRG4odCxxLG8scCxt
-LGssail9LApaSTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5tUyhQLmhLKGEpKX0sCm1TOmZ1bmN0aW9u
-KGEpe2lmKGEgaW5zdGFuY2VvZiBQLlVmKXJldHVybiB0aGlzLnUxKHRoaXMsYSkKcmV0dXJuIHRoaXMu
-UmUoKS5tUyhhKX0sCnUxOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgs
-ZyxmLGU9Yi5iCmlmKGU+MClyZXR1cm4gYgp0PWIuYwppZih0PjApe3M9YS5iCmlmKHM8PTApcmV0dXJu
-IGIKaWYoYS5nTncoKSlyPWIuZSE9Yi5mCmVsc2UgaWYoYS5ndmgoKSlyPSFiLmtYKCI4MCIpCmVsc2Ug
-cj0hYS5ncUIoKXx8IWIua1goIjQ0MyIpCmlmKHIpe3E9cysxCnA9Qy54Qi5OaihhLmEsMCxxKStDLnhC
-LkcoYi5hLGUrMSkKZT1iLmQKaWYodHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1cm4gZS5oKCkKbz1iLmUK
-aWYodHlwZW9mIG8hPT0ibnVtYmVyIilyZXR1cm4gby5oKCkKbj1iLmYKaWYodHlwZW9mIG4hPT0ibnVt
-YmVyIilyZXR1cm4gbi5oKCkKcmV0dXJuIG5ldyBQLlVmKHAscyx0K3EsZStxLG8rcSxuK3EsYi5yK3Es
-YS54KX1lbHNlIHJldHVybiB0aGlzLlJlKCkubVMoYil9bT1iLmUKZT1iLmYKaWYobT09ZSl7dD1iLnIK
-aWYodHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1cm4gZS5KKCkKaWYoZTx0KXtzPWEuZgppZih0eXBlb2Yg
-cyE9PSJudW1iZXIiKXJldHVybiBzLkhOKCkKcT1zLWUKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5h
-LDAscykrQy54Qi5HKGIuYSxlKSxhLmIsYS5jLGEuZCxhLmUsZStxLHQrcSxhLngpfWU9Yi5hCmlmKHQ8
-ZS5sZW5ndGgpe3M9YS5yCnJldHVybiBuZXcgUC5VZihDLnhCLk5qKGEuYSwwLHMpK0MueEIuRyhlLHQp
-LGEuYixhLmMsYS5kLGEuZSxhLmYsdCsocy10KSxhLngpfXJldHVybiBhLk45KCl9dD1iLmEKaWYoQy54
-Qi5RaSh0LCIvIixtKSl7cz1hLmUKaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5ITigpCmlm
-KHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIEgucFkobSkKcT1zLW0KcD1DLnhCLk5qKGEuYSwwLHMp
-K0MueEIuRyh0LG0pCmlmKHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIGUuaCgpCnJldHVybiBuZXcg
-UC5VZihwLGEuYixhLmMsYS5kLHMsZStxLGIucitxLGEueCl9bD1hLmUKaz1hLmYKaWYobD09ayYmYS5j
-PjApe2Zvcig7Qy54Qi5RaSh0LCIuLi8iLG0pOyl7aWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4g
-bS5oKCkKbSs9M31pZih0eXBlb2YgbCE9PSJudW1iZXIiKXJldHVybiBsLkhOKCkKaWYodHlwZW9mIG0h
-PT0ibnVtYmVyIilyZXR1cm4gSC5wWShtKQpxPWwtbSsxCnA9Qy54Qi5OaihhLmEsMCxsKSsiLyIrQy54
-Qi5HKHQsbSkKaWYodHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1cm4gZS5oKCkKcmV0dXJuIG5ldyBQLlVm
-KHAsYS5iLGEuYyxhLmQsbCxlK3EsYi5yK3EsYS54KX1qPWEuYQpmb3IoaT1sO0MueEIuUWkoaiwiLi4v
-IixpKTspe2lmKHR5cGVvZiBpIT09Im51bWJlciIpcmV0dXJuIGkuaCgpCmkrPTN9aD0wCndoaWxlKCEw
-KXtpZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBtLmgoKQpnPW0rMwppZih0eXBlb2YgZSE9PSJu
-dW1iZXIiKXJldHVybiBILnBZKGUpCmlmKCEoZzw9ZSYmQy54Qi5RaSh0LCIuLi8iLG0pKSlicmVhazsr
-K2gKbT1nfWY9IiIKd2hpbGUoITApe2lmKHR5cGVvZiBrIT09Im51bWJlciIpcmV0dXJuIGsub3MoKQpp
-Zih0eXBlb2YgaSE9PSJudW1iZXIiKXJldHVybiBILnBZKGkpCmlmKCEoaz5pKSlicmVhazstLWsKaWYo
-Qy54Qi5tKGosayk9PT00Nyl7aWYoaD09PTApe2Y9Ii8iCmJyZWFrfS0taApmPSIvIn19aWYoaz09PWkm
-JmEuYjw9MCYmIUMueEIuUWkoaiwiLyIsbCkpe20tPWgqMwpmPSIifXE9ay1tK2YubGVuZ3RoCnJldHVy
-biBuZXcgUC5VZihDLnhCLk5qKGosMCxrKStmK0MueEIuRyh0LG0pLGEuYixhLmMsYS5kLGwsZStxLGIu
-citxLGEueCl9LAp0NDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcwppZihwLmI+PTAmJiFwLmdO
-dygpKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgIitILmQo
-cC5nRmkoKSkrIiBVUkkiKSkKdD1wLmYKcz1wLmEKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4g
-dC5KKCkKaWYodDxzLmxlbmd0aCl7aWYodDxwLnIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0
-IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIHF1ZXJ5IGNvbXBvbmVudCIpKQp0aHJvdyBILmIo
-UC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgZnJhZ21lbnQg
-Y29tcG9uZW50IikpfXI9JC53USgpCmlmKEgub1QocikpdD1QLm1uKHApCmVsc2V7cT1wLmQKaWYodHlw
-ZW9mIHEhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShxKQppZihwLmM8cSlILnZoKFAuTDQoIkNhbm5vdCBl
-eHRyYWN0IGEgbm9uLVdpbmRvd3MgZmlsZSBwYXRoIGZyb20gYSBmaWxlIFVSSSB3aXRoIGFuIGF1dGhv
-cml0eSIpKQp0PUMueEIuTmoocyxwLmUsdCl9cmV0dXJuIHR9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQ9
-dGhpcy55CnJldHVybiB0PT1udWxsP3RoaXMueT1DLnhCLmdpTyh0aGlzLmEpOnR9LApETjpmdW5jdGlv
-bihhLGIpe2lmKGI9PW51bGwpcmV0dXJuITEKaWYodGhpcz09PWIpcmV0dXJuITAKcmV0dXJuIHUuRC5j
-KGIpJiZ0aGlzLmE9PT1iLncoMCl9LApSZTpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz1udWxsLHI9dC5n
-RmkoKSxxPXQuZ2t1KCkscD10LmM+MD90LmdKZih0KTpzLG89dC5neEEoKT90Lmd0cCh0KTpzLG49dC5h
-LG09dC5mLGw9Qy54Qi5OaihuLHQuZSxtKSxrPXQucgppZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVy
-biBtLkooKQptPW08az90Lmd0UCgpOnMKcmV0dXJuIG5ldyBQLkRuKHIscSxwLG8sbCxtLGs8bi5sZW5n
-dGg/dC5nS2EoKTpzKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCiRpaUQ6MX0KUC5xZS5w
-cm90b3R5cGU9e30KVy5xRS5wcm90b3R5cGU9e30KVy5HaC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEp
-e3JldHVybiBTdHJpbmcoYSl9LAokaUdoOjF9ClcuZlkucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXty
-ZXR1cm4gU3RyaW5nKGEpfX0KVy5uQi5wcm90b3R5cGU9eyRpbkI6MX0KVy5Bei5wcm90b3R5cGU9eyRp
-QXo6MX0KVy5RUC5wcm90b3R5cGU9eyRpUVA6MX0KVy5ueC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihh
-KXtyZXR1cm4gYS5sZW5ndGh9fQpXLm9KLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBh
-Lmxlbmd0aH19ClcuaWQucHJvdG90eXBlPXt9ClcuUUYucHJvdG90eXBlPXt9ClcuTmgucHJvdG90eXBl
-PXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfX0KVy5JQi5wcm90b3R5cGU9ewp3OmZ1bmN0
-aW9uKGEpe3JldHVybiJSZWN0YW5nbGUgKCIrSC5kKGEubGVmdCkrIiwgIitILmQoYS50b3ApKyIpICIr
-SC5kKGEud2lkdGgpKyIgeCAiK0guZChhLmhlaWdodCl9LApETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51
-bGwpcmV0dXJuITEKcmV0dXJuIHUucS5jKGIpJiZhLmxlZnQ9PT1iLmxlZnQmJmEudG9wPT09Yi50b3Am
-JmEud2lkdGg9PT1iLndpZHRoJiZhLmhlaWdodD09PWIuaGVpZ2h0fSwKZ2lPOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBXLnJFKEMuQ0QuZ2lPKGEubGVmdCksQy5DRC5naU8oYS50b3ApLEMuQ0QuZ2lPKGEud2lkdGgp
-LEMuQ0QuZ2lPKGEuaGVpZ2h0KSl9LAokaXRuOjF9ClcubjcucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24o
-YSl7cmV0dXJuIGEubGVuZ3RofX0KVy53ei5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4g
-dGhpcy5hLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILlNjKGIpCnQ9dGhpcy5hCmlmKGI8
-MHx8Yj49dC5sZW5ndGgpcmV0dXJuIEguT0godCxiKQpyZXR1cm4gdGhpcy4kdGkuZC5iKHRbYl0pfSwK
-WTpmdW5jdGlvbihhLGIsYyl7dGhpcy4kdGkuZC5iKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgbW9k
-aWZ5IGxpc3QiKSl9fQpXLmN2LnByb3RvdHlwZT17CmdRZzpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcu
-aTcoYSl9LApnRDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuSTQoYSl9LApzRDpmdW5jdGlvbihhLGIp
-e3ZhciB0CnUuWC5iKGIpCnQ9dGhpcy5nRChhKQp0LlYxKDApCnQuRlYoMCxiKX0sCnc6ZnVuY3Rpb24o
-YSl7cmV0dXJuIGEubG9jYWxOYW1lfSwKdG46ZnVuY3Rpb24oYSl7dmFyIHQ9ISFhLnNjcm9sbEludG9W
-aWV3SWZOZWVkZWQKaWYodClhLnNjcm9sbEludG9WaWV3SWZOZWVkZWQoKQplbHNlIGEuc2Nyb2xsSW50
-b1ZpZXcoKX0sCnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxCmlmKGM9PW51bGwpe2lmKGQ9
-PW51bGwpe3Q9JC5sdAppZih0PT1udWxsKXt0PUguVk0oW10sdS5rKQpzPW5ldyBXLnZEKHQpCkMuTm0u
-aSh0LFcuVHcobnVsbCkpCkMuTm0uaSh0LFcuQmwoKSkKJC5sdD1zCmQ9c31lbHNlIGQ9dH10PSQuRVUK
-aWYodD09bnVsbCl7dD1uZXcgVy5LbyhkKQokLkVVPXQKYz10fWVsc2V7dC5hPWQKYz10fX1lbHNlIGlm
-KGQhPW51bGwpdGhyb3cgSC5iKFAueFkoInZhbGlkYXRvciBjYW4gb25seSBiZSBwYXNzZWQgaWYgdHJl
-ZVNhbml0aXplciBpcyBudWxsIikpCmlmKCQueG89PW51bGwpe3Q9ZG9jdW1lbnQKcz10LmltcGxlbWVu
-dGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudCgiIikKJC54bz1zCiQuQk89cy5jcmVhdGVSYW5nZSgpCnM9
-JC54by5jcmVhdGVFbGVtZW50KCJiYXNlIikKdS5jUi5iKHMpCnMuaHJlZj10LmJhc2VVUkkKJC54by5o
-ZWFkLmFwcGVuZENoaWxkKHMpfXQ9JC54bwppZih0LmJvZHk9PW51bGwpe3M9dC5jcmVhdGVFbGVtZW50
-KCJib2R5IikKdC5ib2R5PXUuWS5iKHMpfXQ9JC54bwppZih1LlkuYyhhKSlyPXQuYm9keQplbHNle3I9
-dC5jcmVhdGVFbGVtZW50KGEudGFnTmFtZSkKJC54by5ib2R5LmFwcGVuZENoaWxkKHIpfWlmKCJjcmVh
-dGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUmJiFDLk5tLnRnKEMu
-U3EsYS50YWdOYW1lKSl7JC5CTy5zZWxlY3ROb2RlQ29udGVudHMocikKcT0kLkJPLmNyZWF0ZUNvbnRl
-eHR1YWxGcmFnbWVudChiKX1lbHNle3IuaW5uZXJIVE1MPWIKcT0kLnhvLmNyZWF0ZURvY3VtZW50RnJh
-Z21lbnQoKQpmb3IoO3Q9ci5maXJzdENoaWxkLHQhPW51bGw7KXEuYXBwZW5kQ2hpbGQodCl9dD0kLnhv
-LmJvZHkKaWYocj09bnVsbD90IT1udWxsOnIhPT10KUouTHQocikKYy5QbihxKQpkb2N1bWVudC5hZG9w
-dE5vZGUocSkKcmV0dXJuIHF9LApBSDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMucjYoYSxiLGMs
-bnVsbCl9LApzaGY6ZnVuY3Rpb24oYSxiKXt0aGlzLllDKGEsYil9LApwazpmdW5jdGlvbihhLGIsYyl7
-YS50ZXh0Q29udGVudD1udWxsCmEuYXBwZW5kQ2hpbGQodGhpcy5yNihhLGIsbnVsbCxjKSl9LApZQzpm
-dW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnBrKGEsYixudWxsKX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1
-cm4gbmV3IFcuQ3EoYSwiY2xpY2siLCExLHUuUSl9LAokaWN2OjEsCmduczpmdW5jdGlvbihhKXtyZXR1
-cm4gYS50YWdOYW1lfX0KVy5Ddi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5oLmMo
-dS5BLmIoYSkpfSwKJFM6MjV9ClcuZWEucHJvdG90eXBlPXskaWVhOjF9ClcuRDAucHJvdG90eXBlPXsK
-T246ZnVuY3Rpb24oYSxiLGMsZCl7dS5VLmIoYykKaWYoYyE9bnVsbCl0aGlzLnYoYSxiLGMsZCl9LApC
-OmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gdGhpcy5PbihhLGIsYyxudWxsKX0sCnY6ZnVuY3Rpb24oYSxi
-LGMsZCl7cmV0dXJuIGEuYWRkRXZlbnRMaXN0ZW5lcihiLEgudFIodS5VLmIoYyksMSksZCl9LAokaUQw
-OjF9ClcuVDUucHJvdG90eXBlPXskaVQ1OjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGEubGVuZ3RofX0KVy5ici5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5s
-ZW5ndGh9fQpXLlZiLnByb3RvdHlwZT17fQpXLk83LnByb3RvdHlwZT17CmVvOmZ1bmN0aW9uKGEsYixj
-LGQpe3JldHVybiBhLm9wZW4oYixjLCEwKX0sCiRpTzc6MX0KVy5iVS5wcm90b3R5cGU9ewokMjpmdW5j
-dGlvbihhLGIpe3RoaXMuYS5zZXRSZXF1ZXN0SGVhZGVyKEgueShhKSxILnkoYikpfSwKJFM6MTB9Clcu
-aEgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscAp1LnAuYihhKQp0PXRoaXMu
-YQpzPXQuc3RhdHVzCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMudEIoKQpyPXM+PTIwMCYm
-czwzMDAKcT1zPjMwNyYmczw0MDAKcz1yfHxzPT09MHx8cz09PTMwNHx8cQpwPXRoaXMuYgppZihzKXAu
-YU0oMCx0KQplbHNlIHAucG0oYSl9LAokUzoyN30KVy53YS5wcm90b3R5cGU9e30KVy5TZy5wcm90b3R5
-cGU9eyRpU2c6MX0KVy51OC5wcm90b3R5cGU9ewpnRHI6ZnVuY3Rpb24oYSl7aWYoIm9yaWdpbiIgaW4g
-YSlyZXR1cm4gYS5vcmlnaW4KcmV0dXJuIEguZChhLnByb3RvY29sKSsiLy8iK0guZChhLmhvc3QpfSwK
-dzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGl1ODoxfQpXLkFqLnByb3RvdHlwZT17JGlB
-ajoxfQpXLmU3LnByb3RvdHlwZT17CmdyODpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEscz10LmNoaWxk
-Tm9kZXMubGVuZ3RoCmlmKHM9PT0wKXRocm93IEguYihQLlBWKCJObyBlbGVtZW50cyIpKQppZihzPjEp
-dGhyb3cgSC5iKFAuUFYoIk1vcmUgdGhhbiBvbmUgZWxlbWVudCIpKQpyZXR1cm4gdC5maXJzdENoaWxk
-fSwKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1LmVoLmIoYikKdD1iLmEKcz10aGlzLmEKaWYo
-dCE9PXMpZm9yKHI9dC5jaGlsZE5vZGVzLmxlbmd0aCxxPTA7cTxyOysrcSlzLmFwcGVuZENoaWxkKHQu
-Zmlyc3RDaGlsZCkKcmV0dXJufSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscwp1LkEuYihjKQp0PXRo
-aXMuYQpzPXQuY2hpbGROb2RlcwppZihiPDB8fGI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsYikKdC5y
-ZXBsYWNlQ2hpbGQoYyxzW2JdKX0sCmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEuY2hpbGROb2Rl
-cwpyZXR1cm4gbmV3IFcuVzkodCx0Lmxlbmd0aCxILnpLKHQpLkMoIlc5PEdtLkU+IikpfSwKZ0E6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5jaGlsZE5vZGVzLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXt2
-YXIgdApILlNjKGIpCnQ9dGhpcy5hLmNoaWxkTm9kZXMKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4g
-SC5PSCh0LGIpCnJldHVybiB0W2JdfX0KVy51SC5wcm90b3R5cGU9ewp3ZzpmdW5jdGlvbihhKXt2YXIg
-dD1hLnBhcmVudE5vZGUKaWYodCE9bnVsbCl0LnJlbW92ZUNoaWxkKGEpfSwKRDQ6ZnVuY3Rpb24oYSl7
-dmFyIHQKZm9yKDt0PWEuZmlyc3RDaGlsZCx0IT1udWxsOylhLnJlbW92ZUNoaWxkKHQpfSwKdzpmdW5j
-dGlvbihhKXt2YXIgdD1hLm5vZGVWYWx1ZQpyZXR1cm4gdD09bnVsbD90aGlzLlUoYSk6dH0sCiRpdUg6
-MX0KVy5CSC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0
-aW9uKGEsYil7SC5TYyhiKQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRocm93IEguYihQLkNmKGIs
-YSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7dS5BLmIoYykK
-dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUgTGlzdC4iKSl9
-LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5PSChhLGIpCnJldHVy
-biBhW2JdfSwKJGlYajoxLAokaWNYOjEsCiRpek06MX0KVy5TTi5wcm90b3R5cGU9e30KVy5ldy5wcm90
-b3R5cGU9eyRpZXc6MX0KVy5scC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5n
-dGh9fQpXLlRiLnByb3RvdHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMKaWYoImNyZWF0
-ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJhbmdlLnByb3RvdHlwZSlyZXR1cm4gdGhpcy5E
-VyhhLGIsYyxkKQp0PVcuVTkoIjx0YWJsZT4iK0guZChiKSsiPC90YWJsZT4iLGMsZCkKcz1kb2N1bWVu
-dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkKcy50b1N0cmluZwp0LnRvU3RyaW5nCm5ldyBXLmU3KHMp
-LkZWKDAsbmV3IFcuZTcodCkpCnJldHVybiBzfX0KVy5Jdi5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihh
-LGIsYyxkKXt2YXIgdCxzLHIscQppZigiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5kb3cu
-UmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnQ9ZG9jdW1lbnQKcz10LmNyZWF0
-ZURvY3VtZW50RnJhZ21lbnQoKQp0PUMuSWUucjYodC5jcmVhdGVFbGVtZW50KCJ0YWJsZSIpLGIsYyxk
-KQp0LnRvU3RyaW5nCnQ9bmV3IFcuZTcodCkKcj10LmdyOCh0KQpyLnRvU3RyaW5nCnQ9bmV3IFcuZTco
-cikKcT10LmdyOCh0KQpzLnRvU3RyaW5nCnEudG9TdHJpbmcKbmV3IFcuZTcocykuRlYoMCxuZXcgVy5l
-NyhxKSkKcmV0dXJuIHN9fQpXLkJULnByb3RvdHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0
-LHMscgppZigiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBl
-KXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnQ9ZG9jdW1lbnQKcz10LmNyZWF0ZURvY3VtZW50RnJhZ21l
-bnQoKQp0PUMuSWUucjYodC5jcmVhdGVFbGVtZW50KCJ0YWJsZSIpLGIsYyxkKQp0LnRvU3RyaW5nCnQ9
-bmV3IFcuZTcodCkKcj10LmdyOCh0KQpzLnRvU3RyaW5nCnIudG9TdHJpbmcKbmV3IFcuZTcocykuRlYo
-MCxuZXcgVy5lNyhyKSkKcmV0dXJuIHN9fQpXLnlZLnByb3RvdHlwZT17CnBrOmZ1bmN0aW9uKGEsYixj
-KXt2YXIgdCxzCmEudGV4dENvbnRlbnQ9bnVsbAp0PWEuY29udGVudAp0LnRvU3RyaW5nCkouYlQodCkK
-cz10aGlzLnI2KGEsYixudWxsLGMpCmEuY29udGVudC5hcHBlbmRDaGlsZChzKX0sCllDOmZ1bmN0aW9u
-KGEsYil7cmV0dXJuIHRoaXMucGsoYSxiLG51bGwpfSwKJGl5WToxfQpXLnc2LnByb3RvdHlwZT17fQpX
-Lks1LnByb3RvdHlwZT17CmdtVzpmdW5jdGlvbihhKXtyZXR1cm4gYS5sb2NhdGlvbn0sCiRpSzU6MSwK
-JGl2NjoxfQpXLkNtLnByb3RvdHlwZT17JGlDbToxfQpXLkNRLnByb3RvdHlwZT17JGlDUToxfQpXLnc0
-LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlJlY3RhbmdsZSAoIitILmQoYS5sZWZ0KSsi
-LCAiK0guZChhLnRvcCkrIikgIitILmQoYS53aWR0aCkrIiB4ICIrSC5kKGEuaGVpZ2h0KX0sCkROOmZ1
-bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gdS5xLmMoYikmJmEubGVmdD09PWIu
-bGVmdCYmYS50b3A9PT1iLnRvcCYmYS53aWR0aD09PWIud2lkdGgmJmEuaGVpZ2h0PT09Yi5oZWlnaHR9
-LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIFcuckUoQy5DRC5naU8oYS5sZWZ0KSxDLkNELmdpTyhhLnRv
-cCksQy5DRC5naU8oYS53aWR0aCksQy5DRC5naU8oYS5oZWlnaHQpKX19ClcucmgucHJvdG90eXBlPXsK
-Z0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKaWYo
-Yj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC5DZihiLGEsbnVsbCxudWxsLG51bGwpKQpy
-ZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe3UuQS5iKGMpCnRocm93IEguYihQLkw0KCJDYW5u
-b3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3QuIikpfSwKRTpmdW5jdGlvbihhLGIpe2lm
-KGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCiRpWGo6MSwKJGlj
-WDoxLAokaXpNOjF9ClcuY2YucHJvdG90eXBlPXsKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAK
-dS5FLmIoYikKZm9yKHQ9dGhpcy5nVigpLHM9dC5sZW5ndGgscj10aGlzLmEscT0wO3E8dC5sZW5ndGg7
-dC5sZW5ndGg9PT1zfHwoMCxILmxrKSh0KSwrK3Epe3A9dFtxXQpiLiQyKHAsci5nZXRBdHRyaWJ1dGUo
-cCkpfX0sCmdWOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLmEuYXR0cmlidXRlcyxvPUguVk0o
-W10sdS5zKQpmb3IodD1wLmxlbmd0aCxzPXUuaDkscj0wO3I8dDsrK3Ipe2lmKHI+PXAubGVuZ3RoKXJl
-dHVybiBILk9IKHAscikKcT1zLmIocFtyXSkKaWYocS5uYW1lc3BhY2VVUkk9PW51bGwpQy5ObS5pKG8s
-cS5uYW1lKX1yZXR1cm4gb319ClcuaTcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0
-aGlzLmEuZ2V0QXR0cmlidXRlKEgueShiKSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLmEuc2V0QXR0
-cmlidXRlKGIsYyl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nVigpLmxlbmd0aH19ClcuU3ku
-cHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEuYS5nZXRBdHRyaWJ1dGUoImRh
-dGEtIit0aGlzLk8oSC55KGIpKSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLmEuYS5zZXRBdHRyaWJ1
-dGUoImRhdGEtIit0aGlzLk8oYiksYyl9LApLOmZ1bmN0aW9uKGEsYil7dGhpcy5hLksoMCxuZXcgVy5L
-Uyh0aGlzLHUuRS5iKGIpKSl9LApnVjpmdW5jdGlvbigpe3ZhciB0PUguVk0oW10sdS5zKQp0aGlzLmEu
-SygwLG5ldyBXLkEzKHRoaXMsdCkpCnJldHVybiB0fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMu
-Z1YoKS5sZW5ndGh9LAprOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj1ILlZNKGEuc3BsaXQoIi0iKSx1LnMp
-CmZvcih0PTE7dDxyLmxlbmd0aDsrK3Qpe3M9clt0XQppZihzLmxlbmd0aD4wKUMuTm0uWShyLHQsc1sw
-XS50b1VwcGVyQ2FzZSgpK0ouS1YocywxKSl9cmV0dXJuIEMuTm0uSChyLCIiKX0sCk86ZnVuY3Rpb24o
-YSl7dmFyIHQscyxyLHEscApmb3IodD1hLmxlbmd0aCxzPTAscj0iIjtzPHQ7KytzKXtxPWFbc10KcD1x
-LnRvTG93ZXJDYXNlKCkKcj0ocSE9PXAmJnM+MD9yKyItIjpyKStwfXJldHVybiByLmNoYXJDb2RlQXQo
-MCk9PTA/cjpyfX0KVy5LUy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe2lmKEouclkoYSkubihh
-LCJkYXRhLSIpKXRoaXMuYi4kMih0aGlzLmEuayhDLnhCLkcoYSw1KSksYil9LAokUzoxMH0KVy5BMy5w
-cm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe2lmKEouclkoYSkubihhLCJkYXRhLSIpKUMuTm0uaSh0
-aGlzLmIsdGhpcy5hLmsoQy54Qi5HKGEsNSkpKX0sCiRTOjEwfQpXLkk0LnByb3RvdHlwZT17ClA6ZnVu
-Y3Rpb24oKXt2YXIgdCxzLHIscSxwPVAuTHModS5OKQpmb3IodD10aGlzLmEuY2xhc3NOYW1lLnNwbGl0
-KCIgIikscz10Lmxlbmd0aCxyPTA7cjxzOysrcil7cT1KLlQwKHRbcl0pCmlmKHEubGVuZ3RoIT09MClw
-LmkoMCxxKX1yZXR1cm4gcH0sClg6ZnVuY3Rpb24oYSl7dGhpcy5hLmNsYXNzTmFtZT11LkMuYihhKS5I
-KDAsIiAiKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuY2xhc3NMaXN0Lmxlbmd0aH0sClYx
-OmZ1bmN0aW9uKGEpe3RoaXMuYS5jbGFzc05hbWU9IiJ9LAp0ZzpmdW5jdGlvbihhLGIpe3ZhciB0PXRo
-aXMuYS5jbGFzc0xpc3QuY29udGFpbnMoYikKcmV0dXJuIHR9LAppOmZ1bmN0aW9uKGEsYil7dmFyIHQ9
-dGhpcy5hLmNsYXNzTGlzdCxzPXQuY29udGFpbnMoYikKdC5hZGQoYikKcmV0dXJuIXN9LApSOmZ1bmN0
-aW9uKGEsYil7dmFyIHQ9dGhpcy5hLmNsYXNzTGlzdCxzPXQuY29udGFpbnMoYikKdC5yZW1vdmUoYikK
-cmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe1cuVE4odGhpcy5hLHUuWC5iKGIpKX19ClcuRmsucHJv
-dG90eXBlPXt9ClcuUk8ucHJvdG90eXBlPXt9ClcuQ3EucHJvdG90eXBlPXt9ClcueEMucHJvdG90eXBl
-PXt9Clcudk4ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS4kMSh1LkIuYihh
-KSl9LAokUzoyOH0KVy5KUS5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhKXt2YXIgdAppZigkLm9yLmE9
-PT0wKXtmb3IodD0wO3Q8MjYyOysrdCkkLm9yLlkoMCxDLmNtW3RdLFcucFMoKSkKZm9yKHQ9MDt0PDEy
-OysrdCkkLm9yLlkoMCxDLkJJW3RdLFcuVjQoKSl9fSwKaTA6ZnVuY3Rpb24oYSl7cmV0dXJuICQuQU4o
-KS50ZygwLFcuclMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PSQub3IucSgwLEguZChXLnJT
-KGEpKSsiOjoiK2IpCmlmKHQ9PW51bGwpdD0kLm9yLnEoMCwiKjo6IitiKQppZih0PT1udWxsKXJldHVy
-biExCnJldHVybiBILnhkKHQuJDQoYSxiLGMsdGhpcykpfSwKJGlrRjoxfQpXLkdtLnByb3RvdHlwZT17
-CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuVzkoYSx0aGlzLmdBKGEpLEgueksoYSkuQygiVzk8
-R20uRT4iKSl9fQpXLnZELnByb3RvdHlwZT17CmkwOmZ1bmN0aW9uKGEpe3JldHVybiBDLk5tLlZyKHRo
-aXMuYSxuZXcgVy5VdihhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEMuTm0uVnIodGhpcy5h
-LG5ldyBXLkVnKGEsYixjKSl9LAokaWtGOjF9ClcuVXYucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
-cmV0dXJuIHUuZS5iKGEpLmkwKHRoaXMuYSl9LAokUzoxN30KVy5FZy5wcm90b3R5cGU9ewokMTpmdW5j
-dGlvbihhKXtyZXR1cm4gdS5lLmIoYSkuRWIodGhpcy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MTd9Clcu
-bTYucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCnRoaXMuYS5GVigwLGMp
-CnQ9Yi5ldigwLG5ldyBXLkVvKCkpCnM9Yi5ldigwLG5ldyBXLldrKCkpCnRoaXMuYi5GVigwLHQpCnI9
-dGhpcy5jCnIuRlYoMCxDLmRuKQpyLkZWKDAscyl9LAppMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
-LnRnKDAsVy5yUyhhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9dGhpcyxzPVcuclMoYSkscj10
-LmMKaWYoci50ZygwLEguZChzKSsiOjoiK2IpKXJldHVybiB0LmQuRHQoYykKZWxzZSBpZihyLnRnKDAs
-Iio6OiIrYikpcmV0dXJuIHQuZC5EdChjKQplbHNle3I9dC5iCmlmKHIudGcoMCxILmQocykrIjo6Iiti
-KSlyZXR1cm4hMAplbHNlIGlmKHIudGcoMCwiKjo6IitiKSlyZXR1cm4hMAplbHNlIGlmKHIudGcoMCxI
-LmQocykrIjo6KiIpKXJldHVybiEwCmVsc2UgaWYoci50ZygwLCIqOjoqIikpcmV0dXJuITB9cmV0dXJu
-ITF9LAokaWtGOjF9ClcuRW8ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIUMuTm0udGco
-Qy5CSSxILnkoYSkpfSwKJFM6OH0KVy5Xay5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4g
-Qy5ObS50ZyhDLkJJLEgueShhKSl9LAokUzo4fQpXLmN0LnByb3RvdHlwZT17CkViOmZ1bmN0aW9uKGEs
-YixjKXtpZih0aGlzLmpGKGEsYixjKSlyZXR1cm4hMAppZihiPT09InRlbXBsYXRlIiYmYz09PSIiKXJl
-dHVybiEwCmlmKGEuZ2V0QXR0cmlidXRlKCJ0ZW1wbGF0ZSIpPT09IiIpcmV0dXJuIHRoaXMuZS50Zygw
-LGIpCnJldHVybiExfX0KVy5JQS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4iVEVNUExB
-VEU6OiIrSC5kKEgueShhKSl9LAokUzo1fQpXLk93LnByb3RvdHlwZT17CmkwOmZ1bmN0aW9uKGEpe3Zh
-ciB0CmlmKHUuZXcuYyhhKSlyZXR1cm4hMQp0PXUuZzcuYyhhKQppZih0JiZXLnJTKGEpPT09ImZvcmVp
-Z25PYmplY3QiKXJldHVybiExCmlmKHQpcmV0dXJuITAKcmV0dXJuITF9LApFYjpmdW5jdGlvbihhLGIs
-Yyl7aWYoYj09PSJpcyJ8fEMueEIubihiLCJvbiIpKXJldHVybiExCnJldHVybiB0aGlzLmkwKGEpfSwK
-JGlrRjoxfQpXLlc5LnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5jKzEscj10
-LmIKaWYoczxyKXt0LnNwKEoudzIodC5hLHMpKQp0LmM9cwpyZXR1cm4hMH10LnNwKG51bGwpCnQuYz1y
-CnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKc3A6ZnVuY3Rpb24oYSl7dGhp
-cy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KVy5kVy5wcm90b3R5cGU9ewpnbVc6ZnVuY3Rpb24o
-YSl7cmV0dXJuIFcuelgodGhpcy5hLmxvY2F0aW9uKX0sCiRpRDA6MSwKJGl2NjoxfQpXLkZiLnByb3Rv
-dHlwZT17fQpXLmtGLnByb3RvdHlwZT17fQpXLm1rLnByb3RvdHlwZT17JGl5MDoxfQpXLktvLnByb3Rv
-dHlwZT17ClBuOmZ1bmN0aW9uKGEpe25ldyBXLmZtKHRoaXMpLiQyKGEsbnVsbCl9LApFUDpmdW5jdGlv
-bihhLGIpe2lmKGI9PW51bGwpSi5MdChhKQplbHNlIGIucmVtb3ZlQ2hpbGQoYSl9LApJNDpmdW5jdGlv
-bihhLGIpe3ZhciB0LHMscixxLHAsbz0hMCxuPW51bGwsbT1udWxsCnRyeXtuPUouaWcoYSkKbT1uLmEu
-Z2V0QXR0cmlidXRlKCJpcyIpCnUuaC5iKGEpCnQ9ZnVuY3Rpb24oYyl7aWYoIShjLmF0dHJpYnV0ZXMg
-aW5zdGFuY2VvZiBOYW1lZE5vZGVNYXApKXJldHVybiB0cnVlCnZhciBsPWMuY2hpbGROb2RlcwppZihj
-Lmxhc3RDaGlsZCYmYy5sYXN0Q2hpbGQhPT1sW2wubGVuZ3RoLTFdKXJldHVybiB0cnVlCmlmKGMuY2hp
-bGRyZW4paWYoIShjLmNoaWxkcmVuIGluc3RhbmNlb2YgSFRNTENvbGxlY3Rpb258fGMuY2hpbGRyZW4g
-aW5zdGFuY2VvZiBOb2RlTGlzdCkpcmV0dXJuIHRydWUKdmFyIGs9MAppZihjLmNoaWxkcmVuKWs9Yy5j
-aGlsZHJlbi5sZW5ndGgKZm9yKHZhciBqPTA7ajxrO2orKyl7dmFyIGk9Yy5jaGlsZHJlbltqXQppZihp
-LmlkPT0nYXR0cmlidXRlcyd8fGkubmFtZT09J2F0dHJpYnV0ZXMnfHxpLmlkPT0nbGFzdENoaWxkJ3x8
-aS5uYW1lPT0nbGFzdENoaWxkJ3x8aS5pZD09J2NoaWxkcmVuJ3x8aS5uYW1lPT0nY2hpbGRyZW4nKXJl
-dHVybiB0cnVlfXJldHVybiBmYWxzZX0oYSkKbz1ILm9UKHQpPyEwOiEoYS5hdHRyaWJ1dGVzIGluc3Rh
-bmNlb2YgTmFtZWROb2RlTWFwKX1jYXRjaChxKXtILlJ1KHEpfXM9ImVsZW1lbnQgdW5wcmludGFibGUi
-CnRyeXtzPUouaihhKX1jYXRjaChxKXtILlJ1KHEpfXRyeXtyPVcuclMoYSkKdGhpcy5rUih1LmguYihh
-KSxiLG8scyxyLHUuRy5iKG4pLEgueShtKSl9Y2F0Y2gocSl7aWYoSC5SdShxKSBpbnN0YW5jZW9mIFAu
-dSl0aHJvdyBxCmVsc2V7dGhpcy5FUChhLGIpCndpbmRvdwpwPSJSZW1vdmluZyBjb3JydXB0ZWQgZWxl
-bWVudCAiK0guZChzKQppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUu
-d2FybihwKX19fSwKa1I6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxvLG49dGhp
-cwppZihjKXtuLkVQKGEsYikKd2luZG93CnQ9IlJlbW92aW5nIGVsZW1lbnQgZHVlIHRvIGNvcnJ1cHRl
-ZCBhdHRyaWJ1dGVzIG9uIDwiK2QrIj4iCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5k
-b3cuY29uc29sZS53YXJuKHQpCnJldHVybn1pZighbi5hLmkwKGEpKXtuLkVQKGEsYikKd2luZG93CnQ9
-IlJlbW92aW5nIGRpc2FsbG93ZWQgZWxlbWVudCA8IitILmQoZSkrIj4gZnJvbSAiK0guZChiKQppZih0
-eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2Fybih0KQpyZXR1cm59aWYo
-ZyE9bnVsbClpZighbi5hLkViKGEsImlzIixnKSl7bi5FUChhLGIpCndpbmRvdwp0PSJSZW1vdmluZyBk
-aXNhbGxvd2VkIHR5cGUgZXh0ZW5zaW9uIDwiK0guZChlKSsnIGlzPSInK2crJyI+JwppZih0eXBlb2Yg
-Y29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2Fybih0KQpyZXR1cm59dD1mLmdWKCkK
-cz1ILlZNKHQuc2xpY2UoMCksSC50Nih0KS5DKCJqZDwxPiIpKQpmb3Iocj1mLmdWKCkubGVuZ3RoLTEs
-dD1mLmE7cj49MDstLXIpe2lmKHI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMscikKcT1zW3JdCnA9bi5h
-Cm89Si5jSChxKQpILnkocSkKaWYoIXAuRWIoYSxvLHQuZ2V0QXR0cmlidXRlKHEpKSl7d2luZG93CnA9
-IlJlbW92aW5nIGRpc2FsbG93ZWQgYXR0cmlidXRlIDwiK0guZChlKSsiICIrcSsnPSInK0guZCh0Lmdl
-dEF0dHJpYnV0ZShxKSkrJyI+JwppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNv
-bnNvbGUud2FybihwKQp0LnJlbW92ZUF0dHJpYnV0ZShxKX19aWYodS5hVy5jKGEpKW4uUG4oYS5jb250
-ZW50KX0sCiRpb246MX0KVy5mbS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixx
-LHA9dGhpcy5hCnN3aXRjaChhLm5vZGVUeXBlKXtjYXNlIDE6cC5JNChhLGIpCmJyZWFrCmNhc2UgODpj
-YXNlIDExOmNhc2UgMzpjYXNlIDQ6YnJlYWsKZGVmYXVsdDpwLkVQKGEsYil9dD1hLmxhc3RDaGlsZApm
-b3IocD11LkE7bnVsbCE9dDspe3M9bnVsbAp0cnl7cz10LnByZXZpb3VzU2libGluZ31jYXRjaChyKXtI
-LlJ1KHIpCnE9cC5iKHQpCmEucmVtb3ZlQ2hpbGQocSkKdD1udWxsCnM9YS5sYXN0Q2hpbGR9aWYodCE9
-bnVsbCl0aGlzLiQyKHQsYSkKdD1wLmIocyl9fSwKJFM6MzF9ClcuTGUucHJvdG90eXBlPXt9ClcuSzcu
-cHJvdG90eXBlPXt9ClcuckIucHJvdG90eXBlPXt9ClcuWFcucHJvdG90eXBlPXt9Clcub2EucHJvdG90
-eXBlPXt9ClAuaUoucHJvdG90eXBlPXsKVkg6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmEscj1zLmxl
-bmd0aApmb3IodD0wO3Q8cjsrK3QpaWYoc1t0XT09PWEpcmV0dXJuIHQKQy5ObS5pKHMsYSkKQy5ObS5p
-KHRoaXMuYixudWxsKQpyZXR1cm4gcn0sClB2OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPXRoaXMscD17
-fQppZihhPT1udWxsKXJldHVybiBhCmlmKEgubChhKSlyZXR1cm4gYQppZih0eXBlb2YgYT09Im51bWJl
-ciIpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQ
-LmlQKXJldHVybiBuZXcgRGF0ZShhLmEpCmlmKHUuZnYuYyhhKSl0aHJvdyBILmIoUC5TWSgic3RydWN0
-dXJlZCBjbG9uZSBvZiBSZWdFeHAiKSkKaWYodS5jOC5jKGEpKXJldHVybiBhCmlmKHUuZC5jKGEpKXJl
-dHVybiBhCmlmKHUuSS5jKGEpKXJldHVybiBhCnQ9dS5kRC5jKGEpfHwhMQppZih0KXJldHVybiBhCmlm
-KHUuRy5jKGEpKXtzPXEuVkgoYSkKdD1xLmIKaWYocz49dC5sZW5ndGgpcmV0dXJuIEguT0godCxzKQpy
-PXAuYT10W3NdCmlmKHIhPW51bGwpcmV0dXJuIHIKcj17fQpwLmE9cgpDLk5tLlkodCxzLHIpCmEuSygw
-LG5ldyBQLmxSKHAscSkpCnJldHVybiBwLmF9aWYodS5qLmMoYSkpe3M9cS5WSChhKQpwPXEuYgppZihz
-Pj1wLmxlbmd0aClyZXR1cm4gSC5PSChwLHMpCnI9cFtzXQppZihyIT1udWxsKXJldHVybiByCnJldHVy
-biBxLmVrKGEscyl9aWYodS5lSC5jKGEpKXtzPXEuVkgoYSkKdD1xLmIKaWYocz49dC5sZW5ndGgpcmV0
-dXJuIEguT0godCxzKQpyPXAuYj10W3NdCmlmKHIhPW51bGwpcmV0dXJuIHIKcj17fQpwLmI9cgpDLk5t
-LlkodCxzLHIpCnEuaW0oYSxuZXcgUC5qZyhwLHEpKQpyZXR1cm4gcC5ifXRocm93IEguYihQLlNZKCJz
-dHJ1Y3R1cmVkIGNsb25lIG9mIG90aGVyIHR5cGUiKSl9LAplazpmdW5jdGlvbihhLGIpe3ZhciB0LHM9
-Si5VNihhKSxyPXMuZ0EoYSkscT1uZXcgQXJyYXkocikKQy5ObS5ZKHRoaXMuYixiLHEpCmZvcih0PTA7
-dDxyOysrdClDLk5tLlkocSx0LHRoaXMuUHYocy5xKGEsdCkpKQpyZXR1cm4gcX19ClAubFIucHJvdG90
-eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuYVthXT10aGlzLmIuUHYoYil9LAokUzoxfQpQLmpn
-LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhpcy5hLmJbYV09dGhpcy5iLlB2KGIpfSwKJFM6
-MX0KUC5CZi5wcm90b3R5cGU9ewppbTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxCnUuYjguYihiKQpm
-b3IodD1PYmplY3Qua2V5cyhhKSxzPXQubGVuZ3RoLHI9MDtyPHM7KytyKXtxPXRbcl0KYi4kMihxLGFb
-cV0pfX19ClAuQXMucHJvdG90eXBlPXsKVDpmdW5jdGlvbihhKXt2YXIgdApILnkoYSkKdD0kLmhHKCku
-YgppZih0eXBlb2YgYSE9InN0cmluZyIpSC52aChILnRMKGEpKQppZih0LnRlc3QoYSkpcmV0dXJuIGEK
-dGhyb3cgSC5iKFAuTDMoYSwidmFsdWUiLCJOb3QgYSB2YWxpZCBjbGFzcyB0b2tlbiIpKX0sCnc6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIHRoaXMuUCgpLkgoMCwiICIpfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRo
-aXMuUCgpCnJldHVybiBQLnJqKHQsdC5yLEguTGgodCkuZCl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4g
-dGhpcy5QKCkuYX0sCnRnOmZ1bmN0aW9uKGEsYil7dGhpcy5UKGIpCnJldHVybiB0aGlzLlAoKS50Zygw
-LGIpfSwKaTpmdW5jdGlvbihhLGIpe3RoaXMuVChiKQpyZXR1cm4gSC54ZCh0aGlzLk9TKG5ldyBQLkdF
-KGIpKSl9LApSOmZ1bmN0aW9uKGEsYil7dmFyIHQscwp0aGlzLlQoYikKdD10aGlzLlAoKQpzPXQuUigw
-LGIpCnRoaXMuWCh0KQpyZXR1cm4gc30sCkZWOmZ1bmN0aW9uKGEsYil7dGhpcy5PUyhuZXcgUC5ONyh0
-aGlzLHUuWC5iKGIpKSl9LApWMTpmdW5jdGlvbihhKXt0aGlzLk9TKG5ldyBQLnVRKCkpfSwKT1M6ZnVu
-Y3Rpb24oYSl7dmFyIHQscwp1LmNoLmIoYSkKdD10aGlzLlAoKQpzPWEuJDEodCkKdGhpcy5YKHQpCnJl
-dHVybiBzfX0KUC5HRS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5DLmIoYSkuaSgw
-LHRoaXMuYSl9LAokUzo0NX0KUC5ONy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlz
-LmIscz1ILnQ2KHQpCnJldHVybiB1LkMuYihhKS5GVigwLG5ldyBILkE4KHQscy5DKCJxVSgxKSIpLmIo
-dGhpcy5hLmd1TSgpKSxzLkMoIkE4PDEscVU+IikpKX0sCiRTOjE0fQpQLnVRLnByb3RvdHlwZT17CiQx
-OmZ1bmN0aW9uKGEpe3UuQy5iKGEpCmlmKGEuYT4wKXthLmI9YS5jPWEuZD1hLmU9YS5mPW51bGwKYS5h
-PTAKYS5TKCl9cmV0dXJuIG51bGx9LAokUzoxNH0KUC5oRi5wcm90b3R5cGU9eyRpaEY6MX0KUC5QQy5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LlouYihhKQp0PWZ1bmN0aW9uKGIsYyxkKXty
-ZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gYihjLGQsdGhpcyxBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBw
-bHkoYXJndW1lbnRzKSl9fShQLlI0LGEsITEpClAuRG0odCwkLncoKSxhKQpyZXR1cm4gdH0sCiRTOjR9
-ClAuWW0ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyB0aGlzLmEoYSl9LAokUzo0
-fQpQLk56LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5yNyhhKX0sCiRTOjM0
-fQpQLm5wLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5UeihhLHUuYW0pfSwK
-JFM6MzV9ClAuVXQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkU0KGEpfSwK
-JFM6MzZ9ClAuRTQucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBiIT0ic3RyaW5n
-IiYmdHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9wZXJ0eSBpcyBub3QgYSBTdHJp
-bmcgb3IgbnVtIikpCnJldHVybiBQLkw3KHRoaXMuYVtiXSl9LApZOmZ1bmN0aW9uKGEsYixjKXtpZih0
-eXBlb2YgYiE9InN0cmluZyImJnR5cGVvZiBiIT0ibnVtYmVyIil0aHJvdyBILmIoUC54WSgicHJvcGVy
-dHkgaXMgbm90IGEgU3RyaW5nIG9yIG51bSIpKQp0aGlzLmFbYl09UC53WShjKX0sCkROOmZ1bmN0aW9u
-KGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIFAuRTQmJnRoaXMuYT09
-PWIuYX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQscwp0cnl7dD1TdHJpbmcodGhpcy5hKQpyZXR1cm4gdH1j
-YXRjaChzKXtILlJ1KHMpCnQ9dGhpcy54YigwKQpyZXR1cm4gdH19LApWNzpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHM9dGhpcy5hCmlmKGI9PW51bGwpdD1udWxsCmVsc2V7dD1ILnQ2KGIpCnQ9UC5DSChuZXcgSC5B
-OChiLHQuQygiQCgxKSIpLmIoUC5pRygpKSx0LkMoIkE4PDEsQD4iKSksITAsdS56KX1yZXR1cm4gUC5M
-NyhzW2FdLmFwcGx5KHMsdCkpfSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiAwfX0KUC5yNy5wcm90b3R5
-cGU9e30KUC5Uei5wcm90b3R5cGU9ewpjUDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9YTwwfHxhPj10
-LmdBKHQpCmlmKHMpdGhyb3cgSC5iKFAuVEUoYSwwLHQuZ0EodCksbnVsbCxudWxsKSl9LApxOmZ1bmN0
-aW9uKGEsYil7aWYodHlwZW9mIGI9PSJudW1iZXIiJiZiPT09Qy5qbi55dShiKSl0aGlzLmNQKEguU2Mo
-YikpCnJldHVybiB0aGlzLiR0aS5kLmIodGhpcy5VcigwLGIpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciB0CnRoaXMuJHRpLmQuYihjKQp0PUMuam4ueXUoYikKaWYoYj09PXQpdGhpcy5jUChiKQp0aGlzLmU0
-KDAsYixjKX0sCmdBOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYS5sZW5ndGgKaWYodHlwZW9mIHQ9PT0i
-bnVtYmVyIiYmdD4+PjA9PT10KXJldHVybiB0CnRocm93IEguYihQLlBWKCJCYWQgSnNBcnJheSBsZW5n
-dGgiKSl9LAokaWNYOjEsCiRpek06MX0KUC5jby5wcm90b3R5cGU9e30KUC5uZC5wcm90b3R5cGU9eyRp
-bmQ6MX0KUC5LZS5wcm90b3R5cGU9ewpQOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLmEuZ2V0
-QXR0cmlidXRlKCJjbGFzcyIpLG89UC5Mcyh1Lk4pCmlmKHA9PW51bGwpcmV0dXJuIG8KZm9yKHQ9cC5z
-cGxpdCgiICIpLHM9dC5sZW5ndGgscj0wO3I8czsrK3Ipe3E9Si5UMCh0W3JdKQppZihxLmxlbmd0aCE9
-PTApby5pKDAscSl9cmV0dXJuIG99LApYOmZ1bmN0aW9uKGEpe3RoaXMuYS5zZXRBdHRyaWJ1dGUoImNs
-YXNzIixhLkgoMCwiICIpKX19ClAuZDUucHJvdG90eXBlPXsKZ0Q6ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
-dyBQLktlKGEpfSwKc2hmOmZ1bmN0aW9uKGEsYil7dGhpcy5ZQyhhLGIpfSwKcjY6ZnVuY3Rpb24oYSxi
-LGMsZCl7dmFyIHQscyxyLHEscCxvCmlmKGQ9PW51bGwpe3Q9SC5WTShbXSx1LmspCmQ9bmV3IFcudkQo
-dCkKQy5ObS5pKHQsVy5UdyhudWxsKSkKQy5ObS5pKHQsVy5CbCgpKQpDLk5tLmkodCxuZXcgVy5Pdygp
-KX1jPW5ldyBXLktvKGQpCnM9JzxzdmcgdmVyc2lvbj0iMS4xIj4nK0guZChiKSsiPC9zdmc+Igp0PWRv
-Y3VtZW50CnI9dC5ib2R5CnE9KHImJkMuUlkpLkFIKHIscyxjKQpwPXQuY3JlYXRlRG9jdW1lbnRGcmFn
-bWVudCgpCnEudG9TdHJpbmcKdD1uZXcgVy5lNyhxKQpvPXQuZ3I4KHQpCmZvcig7dD1vLmZpcnN0Q2hp
-bGQsdCE9bnVsbDspcC5hcHBlbmRDaGlsZCh0KQpyZXR1cm4gcH0sCmdWbDpmdW5jdGlvbihhKXtyZXR1
-cm4gbmV3IFcuQ3EoYSwiY2xpY2siLCExLHUuUSl9LAokaWQ1OjF9ClAubjYucHJvdG90eXBlPXskaWNY
-OjEsJGl6TToxLCRpQVM6MX0KVS5kMi5wcm90b3R5cGU9e30KVS5TZS5wcm90b3R5cGU9e30KVS51Ri5w
-cm90b3R5cGU9e30KVS5NbC5wcm90b3R5cGU9e30KVS55RC5wcm90b3R5cGU9e30KVS53Yi5wcm90b3R5
-cGU9e30KQi5qOC5wcm90b3R5cGU9e30KQi5xcC5wcm90b3R5cGU9e30KVC5HVi5wcm90b3R5cGU9e30K
-TC5lLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbwp1LkIuYihhKQp0PXdp
-bmRvdy5sb2NhdGlvbi5wYXRobmFtZQpzPUwuRzYod2luZG93LmxvY2F0aW9uLmhyZWYpCnI9TC5hSyh3
-aW5kb3cubG9jYXRpb24uaHJlZikKTC5HZSgpCmlmKHQhPT0iLyImJnQhPT1KLlQwKGRvY3VtZW50LnF1
-ZXJ5U2VsZWN0b3IoIi5yb290IikudGV4dENvbnRlbnQpKUwuRzcodCxzLHIsITAsbmV3IEwuVlcodCxz
-LHIpKQpxPUoucUYoZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiLmFwcGx5LW1pZ3JhdGlvbiIpKQpwPXEu
-JHRpCm89cC5DKCJ+KDEpIikuYihuZXcgTC5vWigpKQp1Lk0uYihudWxsKQpXLkpFKHEuYSxxLmIsbywh
-MSxwLmQpfSwKJFM6MTN9CkwuVlcucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYSx0
-aGlzLmIsdGhpcy5jKX0sCiRTOjB9Ckwub1oucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5WLmIo
-YSkKTC50eSgiL2FwcGx5LW1pZ3JhdGlvbiIpLlc3KG5ldyBMLmpyKCksdS5QKS5PQShuZXcgTC5xbCgp
-KX0sCiRTOjZ9CkwuanIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5yLmIoYSkKdD1k
-b2N1bWVudC5ib2R5CnQuY2xhc3NMaXN0LnJlbW92ZSgicHJvcG9zZWQiKQp0LmNsYXNzTGlzdC5hZGQo
-ImFwcGxpZWQiKX0sCiRTOjd9CkwucWwucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFKKCJh
-cHBseSBtaWdyYXRpb24gZXJyb3I6ICIrSC5kKGEpLGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90IGFw
-cGx5IG1pZ3JhdGlvbiAoIitILmQoYSkrIikuIil9LAokQzoiJDIiLAokUjoyLAokUzoxfQpMLkwucHJv
-dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyCnUuQi5iKGEpCnQ9d2luZG93LmxvY2F0aW9u
-LnBhdGhuYW1lCnM9TC5HNih3aW5kb3cubG9jYXRpb24uaHJlZikKcj1MLmFLKHdpbmRvdy5sb2NhdGlv
-bi5ocmVmKQppZih0Lmxlbmd0aD4xKUwuRzcodCxzLHIsITEsbnVsbCkKZWxzZXtMLkJFKHQsbmV3IEIu
-cXAoIiIsIiIsIiIsQy54RCksITApCkwuQlgoIiZuYnNwOyIsbnVsbCl9fSwKJFM6MTN9CkwuV3gucHJv
-dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9ImNvbGxhcHNlZCIKdS5WLmIoYSkKdD10
-aGlzLmEKcz1KLlJFKHQpCnI9dGhpcy5iCmlmKCFzLmdEKHQpLnRnKDAscSkpe3MuZ0QodCkuaSgwLHEp
-CkouZFIocikuaSgwLHEpfWVsc2V7cy5nRCh0KS5SKDAscSkKSi5kUihyKS5SKDAscSl9fSwKJFM6Nn0K
-TC5BTy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD1KLnFGKHUuaC5iKGEpKSxzPXQuJHRp
-LHI9cy5DKCJ+KDEpIikuYihuZXcgTC5kTih0aGlzLmEpKQp1Lk0uYihudWxsKQpXLkpFKHQuYSx0LmIs
-ciwhMSxzLmQpfSwKJFM6M30KTC5kTi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LlYu
-YihhKQp0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoInRhYmxlW2RhdGEtcGF0aF0iKQp0LnRvU3RyaW5n
-CkwudDIoYSx0aGlzLmEsdC5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyh0KSku
-TygicGF0aCIpKSl9LAokUzo2fQpMLkhvLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMs
-cgp1LmguYihhKQp0PUoucUYoYSkKcz10LiR0aQpyPXMuQygifigxKSIpLmIobmV3IEwueHooYSx0aGlz
-LmEpKQp1Lk0uYihudWxsKQpXLkpFKHQuYSx0LmIsciwhMSxzLmQpfSwKJFM6M30KTC54ei5wcm90b3R5
-cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LlYuYihhKQp0PXRoaXMuYQpMLmhYKHRoaXMuYixQLlFB
-KHQuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcodCkpLk8oIm9mZnNldCIpKSxu
-dWxsLG51bGwpKX0sCiRTOjZ9CkwuSUMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9Si5x
-Rih1LmguYihhKSkscz10LiR0aQpzLkMoIn4oMSkiKS5iKEwuSDAoKSkKdS5NLmIobnVsbCkKVy5KRSh0
-LmEsdC5iLEwuSDAoKSwhMSxzLmQpfSwKJFM6M30KTC5MMS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
-KXt2YXIgdAp1LnIuYihhKQp0PWEuc3RhdHVzCmlmKHQ9PT0yMDApcmV0dXJuIGEKZWxzZSB0aHJvdyBI
-LmIoIlJlcXVlc3QgZmFpbGVkOyBzdGF0dXMgb2YgIitILmQodCkpfSwKJFM6NDF9CkwublQucHJvdG90
-eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYS5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KTC5C
-Wi5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIodGhpcy5hLmEsbnVsbCxudWxsKX0sCiRTOjB9
-CkwuR0gucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5oLmIoYSkKJC56QigpLnRvU3RyaW5nCnUu
-di5iKCQub3coKS5xKDAsImhsanMiKSkuVjcoImhpZ2hsaWdodEJsb2NrIixbYV0pfSwKJFM6M30KTC5E
-VC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LnIuYihhKQp0PWEuc3RhdHVzCmlmKHQ9
-PT0yMDApe0wuVDEoVS55dShDLkN0LnBXKDAsYS5yZXNwb25zZVRleHQsbnVsbCkpKQpMLnlYKCIuZWRp
-dC1wYW5lbCAucGFuZWwtY29udGVudCIsITEpfWVsc2Ugd2luZG93LmFsZXJ0KCJSZXF1ZXN0IGZhaWxl
-ZDsgc3RhdHVzIG9mICIrSC5kKHQpKX0sCiRTOjd9CkwuZUgucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24o
-YSxiKXtMLnFKKCJsb2FkUmVnaW9uRXhwbGFuYXRpb246ICIrSC5kKGEpLGIpCndpbmRvdy5hbGVydCgi
-Q291bGQgbm90IGxvYWQgIitILmQodGhpcy5hKSsiICgiK0guZChhKSsiKS4iKX0sCiRDOiIkMiIsCiRS
-OjIsCiRTOjF9CkwuekQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMKdS5y
-LmIoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXtzPXIuYQpMLkJFKHMsQi5ZZih1LmIuYihDLkN0LnBX
-KDAsYS5yZXNwb25zZVRleHQsbnVsbCkpKSxyLmIpCnQ9ci5jCkwuZkcodCxyLmQpCkwuQlgoQy54Qi50
-ZyhzLCI/Iik/Qy54Qi5OaihzLDAsQy54Qi5PWShzLCI/IikpOnMsdCkKdD1yLmUKaWYodCE9bnVsbCl0
-LiQwKCl9ZWxzZSB3aW5kb3cuYWxlcnQoIlJlcXVlc3QgZmFpbGVkOyBzdGF0dXMgb2YgIitILmQodCkp
-fSwKJFM6N30KTC5PRS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe0wucUooImxvYWRGaWxlOiAi
-K0guZChhKSxiKQp3aW5kb3cuYWxlcnQoIkNvdWxkIG5vdCBsb2FkICIrdGhpcy5hKyIgKCIrSC5kKGEp
-KyIpLiIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6MX0KTC5UVy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
-KXt2YXIgdCxzLHIKdS5yLmIoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXtzPUMuQ3QucFcoMCxhLnJl
-c3BvbnNlVGV4dCxudWxsKQpyPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5uYXYtdHJlZSIpCkoubDUo
-ciwiIikKTC50WChyLEwubUsocykpfWVsc2Ugd2luZG93LmFsZXJ0KCJSZXF1ZXN0IGZhaWxlZDsgc3Rh
-dHVzIG9mICIrSC5kKHQpKX0sCiRTOjd9CkwueHIucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtM
-LnFKKCJsb2FkTmF2aWdhdGlvblRyZWU6ICIrSC5kKGEpLGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90
-IGxvYWQgIit0aGlzLmErIiAoIitILmQoYSkrIikuIil9LAokQzoiJDIiLAokUjoyLAokUzoxfQpMLkVF
-LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMKdS5WLmIoYSkKdD10aGlzLmEKcz10aGlz
-LmIKTC5hZih3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUsdCxzLCEwLG5ldyBMLlFMKHQscykpCkwuaFgo
-dGhpcy5jLHQpfSwKJFM6Nn0KTC5RTC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIod2luZG93
-LmxvY2F0aW9uLnBhdGhuYW1lLHRoaXMuYSx0aGlzLmIpfSwKJFM6MH0KTC5WUy5wcm90b3R5cGU9ewok
-MTpmdW5jdGlvbihhKXt2YXIgdCxzPSJzZWxlY3RlZC1maWxlIgp1LmguYihhKQphLnRvU3RyaW5nCnQ9
-Si5SRShhKQppZihhLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGEpKS5PKCJu
-YW1lIikpPT09dGhpcy5hLmEpdC5nRChhKS5pKDAscykKZWxzZSB0LmdEKGEpLlIoMCxzKX0sCiRTOjN9
-CkwuVEQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEwudDIodS5WLmIoYSksITAsbnVs
-bCl9LAokUzoxNn0KTC5YQS5wcm90b3R5cGU9ewpFYjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuITB9LApp
-MDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCiRpa0Y6MX0KTC5aWi5wcm90b3R5cGU9e30KTC55OC5wcm90
-b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpNLmxJLnByb3RvdHlwZT17CldPOmZ1
-bmN0aW9uKGEsYil7dmFyIHQscz1udWxsCk0uWUYoImFic29sdXRlIixILlZNKFtiLG51bGwsbnVsbCxu
-dWxsLG51bGwsbnVsbCxudWxsXSx1LnMpKQp0PXRoaXMuYQp0PXQuWXIoYik+MCYmIXQuaEsoYikKaWYo
-dClyZXR1cm4gYgp0PUQuUlgoKQpyZXR1cm4gdGhpcy5xNygwLHQsYixzLHMscyxzLHMscyl9LAp0TTpm
-dW5jdGlvbihhKXt2YXIgdCxzLHI9WC5DTChhLHRoaXMuYSkKci5JVigpCnQ9ci5kCnM9dC5sZW5ndGgK
-aWYocz09PTApe3Q9ci5iCnJldHVybiB0PT1udWxsPyIuIjp0fWlmKHM9PT0xKXt0PXIuYgpyZXR1cm4g
-dD09bnVsbD8iLiI6dH1pZigwPj1zKXJldHVybiBILk9IKHQsLTEpCnQucG9wKCkKQy5ObS5tdihyLmUp
-CnIuSVYoKQpyZXR1cm4gci53KDApfSwKcTc6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyxoLGkpe3ZhciB0
-PUguVk0oW2IsYyxkLGUsZixnLGgsaV0sdS5zKQpNLllGKCJqb2luIix0KQpyZXR1cm4gdGhpcy5JUChu
-ZXcgSC5VNSh0LHUuYkIuYihuZXcgTS5NaSgpKSx1LmNjKSl9LApJUDpmdW5jdGlvbihhKXt2YXIgdCxz
-LHIscSxwLG8sbixtLGwKdS5YLmIoYSkKZm9yKHQ9YS4kdGkscz10LkMoImEyKGNYLkUpIikuYihuZXcg
-TS5xNygpKSxyPWEuZ2t6KGEpLHQ9bmV3IEguU08ocixzLHQuQygiU088Y1guRT4iKSkscz10aGlzLmEs
-cT0hMSxwPSExLG89IiI7dC5GKCk7KXtuPXIuZ2woKQppZihzLmhLKG4pJiZwKXttPVguQ0wobixzKQps
-PW8uY2hhckNvZGVBdCgwKT09MD9vOm8Kbz1DLnhCLk5qKGwsMCxzLlNwKGwsITApKQptLmI9bwppZihz
-LmRzKG8pKUMuTm0uWShtLmUsMCxzLmdtSSgpKQpvPW0udygwKX1lbHNlIGlmKHMuWXIobik+MCl7cD0h
-cy5oSyhuKQpvPUguZChuKX1lbHNle2lmKCEobi5sZW5ndGg+MCYmcy5VZChuWzBdKSkpaWYocSlvKz1z
-LmdtSSgpCm8rPUguZChuKX1xPXMuZHMobil9cmV0dXJuIG8uY2hhckNvZGVBdCgwKT09MD9vOm99LApv
-NTpmdW5jdGlvbihhKXt2YXIgdAppZighdGhpcy55MyhhKSlyZXR1cm4gYQp0PVguQ0woYSx0aGlzLmEp
-CnQuclIoKQpyZXR1cm4gdC53KDApfSwKeTM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxs
-LGsKYS50b1N0cmluZwp0PXRoaXMuYQpzPXQuWXIoYSkKaWYocyE9PTApe2lmKHQ9PT0kLktrKCkpZm9y
-KHI9MDtyPHM7KytyKWlmKEMueEIuVyhhLHIpPT09NDcpcmV0dXJuITAKcT1zCnA9NDd9ZWxzZXtxPTAK
-cD1udWxsfWZvcihvPW5ldyBILnFqKGEpLmEsbj1vLmxlbmd0aCxyPXEsbT1udWxsO3I8bjsrK3IsbT1w
-LHA9bCl7bD1DLnhCLm0obyxyKQppZih0LnI0KGwpKXtpZih0PT09JC5LaygpJiZsPT09NDcpcmV0dXJu
-ITAKaWYocCE9bnVsbCYmdC5yNChwKSlyZXR1cm4hMAppZihwPT09NDYpaz1tPT1udWxsfHxtPT09NDZ8
-fHQucjQobSkKZWxzZSBrPSExCmlmKGspcmV0dXJuITB9fWlmKHA9PW51bGwpcmV0dXJuITAKaWYodC5y
-NChwKSlyZXR1cm4hMAppZihwPT09NDYpdD1tPT1udWxsfHx0LnI0KG0pfHxtPT09NDYKZWxzZSB0PSEx
-CmlmKHQpcmV0dXJuITAKcmV0dXJuITF9LApIUDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz10
-aGlzLG49J1VuYWJsZSB0byBmaW5kIGEgcGF0aCB0byAiJwpiPW8uV08oMCxiKQp0PW8uYQppZih0Llly
-KGIpPD0wJiZ0LllyKGEpPjApcmV0dXJuIG8ubzUoYSkKaWYodC5ZcihhKTw9MHx8dC5oSyhhKSlhPW8u
-V08oMCxhKQppZih0LllyKGEpPD0wJiZ0LllyKGIpPjApdGhyb3cgSC5iKFguSlQobitILmQoYSkrJyIg
-ZnJvbSAiJytILmQoYikrJyIuJykpCnM9WC5DTChiLHQpCnMuclIoKQpyPVguQ0woYSx0KQpyLnJSKCkK
-cT1zLmQKaWYocS5sZW5ndGg+MCYmSi5STShxWzBdLCIuIikpcmV0dXJuIHIudygwKQpxPXMuYgpwPXIu
-YgppZihxIT1wKXE9cT09bnVsbHx8cD09bnVsbHx8IXQuTmMocSxwKQplbHNlIHE9ITEKaWYocSlyZXR1
-cm4gci53KDApCndoaWxlKCEwKXtxPXMuZAppZihxLmxlbmd0aD4wKXtwPXIuZApxPXAubGVuZ3RoPjAm
-JnQuTmMocVswXSxwWzBdKX1lbHNlIHE9ITEKaWYoIXEpYnJlYWsKQy5ObS5XNChzLmQsMCkKQy5ObS5X
-NChzLmUsMSkKQy5ObS5XNChyLmQsMCkKQy5ObS5XNChyLmUsMSl9cT1zLmQKaWYocS5sZW5ndGg+MCYm
-Si5STShxWzBdLCIuLiIpKXRocm93IEguYihYLkpUKG4rSC5kKGEpKyciIGZyb20gIicrSC5kKGIpKyci
-LicpKQpxPXUuTgpDLk5tLlVHKHIuZCwwLFAuTzgocy5kLmxlbmd0aCwiLi4iLHEpKQpDLk5tLlkoci5l
-LDAsIiIpCkMuTm0uVUcoci5lLDEsUC5POChzLmQubGVuZ3RoLHQuZ21JKCkscSkpCnQ9ci5kCnE9dC5s
-ZW5ndGgKaWYocT09PTApcmV0dXJuIi4iCmlmKHE+MSYmSi5STShDLk5tLmdyWih0KSwiLiIpKXt0PXIu
-ZAppZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LC0xKQp0LnBvcCgpCnQ9ci5lCkMuTm0ubXYodCkK
-Qy5ObS5tdih0KQpDLk5tLmkodCwiIil9ci5iPSIiCnIuSVYoKQpyZXR1cm4gci53KDApfX0KTS5NaS5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gSC55KGEpIT1udWxsfSwKJFM6OH0KTS5xNy5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gSC55KGEpIT09IiJ9LAokUzo4fQpNLk5vLnBy
-b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe0gueShhKQpyZXR1cm4gYT09bnVsbD8ibnVsbCI6JyInK2Er
-JyInfSwKJFM6NX0KQi5MdS5wcm90b3R5cGU9ewp4WjpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuWXIo
-YSkKaWYocz4wKXJldHVybiBKLmxkKGEsMCxzKQppZih0aGlzLmhLKGEpKXtpZigwPj1hLmxlbmd0aCly
-ZXR1cm4gSC5PSChhLDApCnQ9YVswXX1lbHNlIHQ9bnVsbApyZXR1cm4gdH0sCk5jOmZ1bmN0aW9uKGEs
-Yil7cmV0dXJuIGE9PWJ9fQpYLldELnByb3RvdHlwZT17CklWOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRo
-aXMKd2hpbGUoITApe3Q9ci5kCmlmKCEodC5sZW5ndGghPT0wJiZKLlJNKEMuTm0uZ3JaKHQpLCIiKSkp
-YnJlYWsKdD1yLmQKaWYoMD49dC5sZW5ndGgpcmV0dXJuIEguT0godCwtMSkKdC5wb3AoKQpDLk5tLm12
-KHIuZSl9dD1yLmUKcz10Lmxlbmd0aAppZihzPjApQy5ObS5ZKHQscy0xLCIiKX0sCnJSOmZ1bmN0aW9u
-KCl7dmFyIHQscyxyLHEscCxvLG4sbT10aGlzLGw9SC5WTShbXSx1LnMpCmZvcih0PW0uZCxzPXQubGVu
-Z3RoLHI9MCxxPTA7cTx0Lmxlbmd0aDt0Lmxlbmd0aD09PXN8fCgwLEgubGspKHQpLCsrcSl7cD10W3Fd
-Cm89Si5pYShwKQppZighKG8uRE4ocCwiLiIpfHxvLkROKHAsIiIpKSlpZihvLkROKHAsIi4uIikpaWYo
-bC5sZW5ndGg+MClsLnBvcCgpCmVsc2UgKytyCmVsc2UgQy5ObS5pKGwscCl9aWYobS5iPT1udWxsKUMu
-Tm0uVUcobCwwLFAuTzgociwiLi4iLHUuTikpCmlmKGwubGVuZ3RoPT09MCYmbS5iPT1udWxsKUMuTm0u
-aShsLCIuIikKbj1QLmRIKGwubGVuZ3RoLG5ldyBYLnFSKG0pLCEwLHUuTikKdD1tLmIKdD10IT1udWxs
-JiZsLmxlbmd0aD4wJiZtLmEuZHModCk/bS5hLmdtSSgpOiIiCkgudDYobikuZC5iKHQpCmlmKCEhbi5m
-aXhlZCRsZW5ndGgpSC52aChQLkw0KCJpbnNlcnQiKSkKbi5zcGxpY2UoMCwwLHQpCm0uc25KKGwpCm0u
-c1BoKG4pCnQ9bS5iCmlmKHQhPW51bGwmJm0uYT09PSQuS2soKSl7dC50b1N0cmluZwptLmI9SC55cyh0
-LCIvIiwiXFwiKX1tLklWKCl9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9ci5iCnE9cSE9
-bnVsbD9xOiIiCmZvcih0PTA7dDxyLmQubGVuZ3RoOysrdCl7cz1yLmUKaWYodD49cy5sZW5ndGgpcmV0
-dXJuIEguT0gocyx0KQpzPXErSC5kKHNbdF0pCnE9ci5kCmlmKHQ+PXEubGVuZ3RoKXJldHVybiBILk9I
-KHEsdCkKcT1zK0guZChxW3RdKX1xKz1ILmQoQy5ObS5nclooci5lKSkKcmV0dXJuIHEuY2hhckNvZGVB
-dCgwKT09MD9xOnF9LApzbko6ZnVuY3Rpb24oYSl7dGhpcy5kPXUuYS5iKGEpfSwKc1BoOmZ1bmN0aW9u
-KGEpe3RoaXMuZT11LmEuYihhKX19ClgucVIucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuYS5hLmdtSSgpfSwKJFM6NDN9ClguZHYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1
-cm4iUGF0aEV4Y2VwdGlvbjogIit0aGlzLmF9fQpPLnpMLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7
-cmV0dXJuIHRoaXMuZ29jKHRoaXMpfX0KRS5PRi5wcm90b3R5cGU9ewpVZDpmdW5jdGlvbihhKXtyZXR1
-cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fSwKZHM6ZnVuY3Rp
-b24oYSl7dmFyIHQ9YS5sZW5ndGgKcmV0dXJuIHQhPT0wJiZDLnhCLm0oYSx0LTEpIT09NDd9LApTcDpm
-dW5jdGlvbihhLGIpe2lmKGEubGVuZ3RoIT09MCYmQy54Qi5XKGEsMCk9PT00NylyZXR1cm4gMQpyZXR1
-cm4gMH0sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlNwKGEsITEpfSwKaEs6ZnVuY3Rpb24oYSl7
-cmV0dXJuITF9LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4icG9zaXgifSwKZ21JOmZ1bmN0aW9uKCl7cmV0
-dXJuIi8ifX0KRi5ydS5wcm90b3R5cGU9ewpVZDpmdW5jdGlvbihhKXtyZXR1cm4gQy54Qi50ZyhhLCIv
-Iil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fSwKZHM6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5s
-ZW5ndGgKaWYodD09PTApcmV0dXJuITEKaWYoQy54Qi5tKGEsdC0xKSE9PTQ3KXJldHVybiEwCnJldHVy
-biBDLnhCLlRjKGEsIjovLyIpJiZ0aGlzLllyKGEpPT09dH0sClNwOmZ1bmN0aW9uKGEsYil7dmFyIHQs
-cyxyLHEscD1hLmxlbmd0aAppZihwPT09MClyZXR1cm4gMAppZihDLnhCLlcoYSwwKT09PTQ3KXJldHVy
-biAxCmZvcih0PTA7dDxwOysrdCl7cz1DLnhCLlcoYSx0KQppZihzPT09NDcpcmV0dXJuIDAKaWYocz09
-PTU4KXtpZih0PT09MClyZXR1cm4gMApyPUMueEIuWFUoYSwiLyIsQy54Qi5RaShhLCIvLyIsdCsxKT90
-KzM6dCkKaWYocjw9MClyZXR1cm4gcAppZighYnx8cDxyKzMpcmV0dXJuIHIKaWYoIUMueEIubihhLCJm
-aWxlOi8vIikpcmV0dXJuIHIKaWYoIUIuWXUoYSxyKzEpKXJldHVybiByCnE9ciszCnJldHVybiBwPT09
-cT9xOnIrNH19cmV0dXJuIDB9LApZcjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhL
-OmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aCE9PTAmJkMueEIuVyhhLDApPT09NDd9LApnb2M6ZnVu
-Y3Rpb24oKXtyZXR1cm4idXJsIn0sCmdtSTpmdW5jdGlvbigpe3JldHVybiIvIn19CkwuSVYucHJvdG90
-eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIudGcoYSwiLyIpfSwKcjQ6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGE9PT00N3x8YT09PTkyfSwKZHM6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5sZW5ndGgKaWYodD09
-PTApcmV0dXJuITEKdD1DLnhCLm0oYSx0LTEpCnJldHVybiEodD09PTQ3fHx0PT09OTIpfSwKU3A6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdCxzLHI9YS5sZW5ndGgKaWYocj09PTApcmV0dXJuIDAKdD1DLnhCLlcoYSww
-KQppZih0PT09NDcpcmV0dXJuIDEKaWYodD09PTkyKXtpZihyPDJ8fEMueEIuVyhhLDEpIT09OTIpcmV0
-dXJuIDEKcz1DLnhCLlhVKGEsIlxcIiwyKQppZihzPjApe3M9Qy54Qi5YVShhLCJcXCIscysxKQppZihz
-PjApcmV0dXJuIHN9cmV0dXJuIHJ9aWYocjwzKXJldHVybiAwCmlmKCFCLk9TKHQpKXJldHVybiAwCmlm
-KEMueEIuVyhhLDEpIT09NTgpcmV0dXJuIDAKcj1DLnhCLlcoYSwyKQppZighKHI9PT00N3x8cj09PTky
-KSlyZXR1cm4gMApyZXR1cm4gM30sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlNwKGEsITEpfSwK
-aEs6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuWXIoYSk9PT0xfSwKT3Q6ZnVuY3Rpb24oYSxiKXt2YXIg
-dAppZihhPT09YilyZXR1cm4hMAppZihhPT09NDcpcmV0dXJuIGI9PT05MgppZihhPT09OTIpcmV0dXJu
-IGI9PT00NwppZigoYV5iKSE9PTMyKXJldHVybiExCnQ9YXwzMgpyZXR1cm4gdD49OTcmJnQ8PTEyMn0s
-Ck5jOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmlmKGE9PWIpcmV0dXJuITAKdD1hLmxlbmd0aAppZih0
-IT09Yi5sZW5ndGgpcmV0dXJuITEKZm9yKHM9Si5yWShiKSxyPTA7cjx0OysrcilpZighdGhpcy5PdChD
-LnhCLlcoYSxyKSxzLlcoYixyKSkpcmV0dXJuITEKcmV0dXJuITB9LApnb2M6ZnVuY3Rpb24oKXtyZXR1
-cm4id2luZG93cyJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iXFwifX07KGZ1bmN0aW9uIGFsaWFzZXMo
-KXt2YXIgdD1KLnZCLnByb3RvdHlwZQp0LlU9dC53CnQuU2o9dC5lNwp0PUouTUYucHJvdG90eXBlCnQu
-dD10LncKdD1QLmNYLnByb3RvdHlwZQp0LkdHPXQuZXYKdD1QLmsucHJvdG90eXBlCnQueGI9dC53CnQ9
-Vy5jdi5wcm90b3R5cGUKdC5EVz10LnI2CnQ9Vy5tNi5wcm90b3R5cGUKdC5qRj10LkViCnQ9UC5FNC5w
-cm90b3R5cGUKdC5Vcj10LnEKdC5lND10Lll9KSgpOyhmdW5jdGlvbiBpbnN0YWxsVGVhck9mZnMoKXt2
-YXIgdD1odW5rSGVscGVycy5fc3RhdGljXzEscz1odW5rSGVscGVycy5fc3RhdGljXzAscj1odW5rSGVs
-cGVycy5pbnN0YWxsSW5zdGFuY2VUZWFyT2ZmLHE9aHVua0hlbHBlcnMuaW5zdGFsbFN0YXRpY1RlYXJP
-ZmYscD1odW5rSGVscGVycy5faW5zdGFuY2VfMXUKdChQLCJFWCIsIlpWIiw5KQp0KFAsInl0Iiwib0Ei
-LDkpCnQoUCwicVciLCJCeiIsOSkKcyhQLCJVSSIsImVOIiwyKQpyKFAuUGYucHJvdG90eXBlLCJnWUoi
-LDAsMSxudWxsLFsiJDIiLCIkMSJdLFsidzAiLCJwbSJdLDQ0LDApCnQoUCwiUEgiLCJNdCIsNSkKcShX
-LCJwUyIsNCxudWxsLFsiJDQiXSxbInlXIl0sMTUsMCkKcShXLCJWNCIsNCxudWxsLFsiJDQiXSxbIlFX
-Il0sMTUsMCkKcChQLkFzLnByb3RvdHlwZSwiZ3VNIiwiVCIsNSkKdChQLCJpRyIsIndZIiw0KQp0KFAs
-IncwIiwiTDciLDMwKQp0KEwsIkgwIiwidW0iLDE2KX0pKCk7KGZ1bmN0aW9uIGluaGVyaXRhbmNlKCl7
-dmFyIHQ9aHVua0hlbHBlcnMubWl4aW4scz1odW5rSGVscGVycy5pbmhlcml0LHI9aHVua0hlbHBlcnMu
-aW5oZXJpdE1hbnkKcyhQLmssbnVsbCkKcihQLmssW0guZW8sSi52QixKLm0xLFAublksUC5jWCxILmE3
-LFAuQW4sSC5TVSxILlJlLEgud3YsUC5QbixILldVLEguTEksSC5UcCxILmY5LFAuWFMsSC5icSxILlhP
-LFAuWWssSC5kYixILk42LEguVlIsSC5FSyxILlBiLEgudFEsSC5TZCxILkpjLEguRyxQLlczLFAuaWgs
-UC5QZixQLkZlLFAudnMsUC5PTSxQLnFoLFAuTU8sUC5rVCxQLnhJLFAuQ3csUC5tMCxQLlh2LFAuYm4s
-UC5sbSxQLmxELFAuS1AsUC5sZixQLldZLFAuVWssUC5SdyxQLmJ6LFAuYTIsUC5pUCxQLkZLLFAuazUs
-UC5LWSxQLkNELFAuYUUsUC5FSCxQLnpNLFAuWjAsUC5jOCxQLk9kLFAuaWIsUC5HeixQLnFVLFAuUm4s
-UC5HRCxQLkRuLFAuUEUsUC5VZixXLmlkLFcuRmssVy5KUSxXLkdtLFcudkQsVy5tNixXLk93LFcuVzks
-Vy5kVyxXLkZiLFcua0YsVy5tayxXLktvLFAuaUosUC5FNCxQLm42LFUuZDIsVS5TZSxVLnVGLFUuTWws
-VS55RCxVLndiLEIuajgsQi5xcCxULkdWLEwuWEEsTC5aWixMLnk4LE0ubEksTy56TCxYLldELFguZHZd
-KQpyKEoudkIsW0oueUUsSi5ZRSxKLk1GLEouamQsSi5xSSxKLkRyLEguRVQsVy5EMCxXLkF6LFcuTGUs
-Vy5OaCxXLklCLFcubjcsVy5lYSxXLmJyLFcuU2csVy51OCxXLks3LFcuWFcsUC5oRl0pCnIoSi5NRixb
-Si5pQyxKLmtkLEouYzVdKQpzKEouUG8sSi5qZCkKcihKLnFJLFtKLnVyLEouVkFdKQpzKFAuTFUsUC5u
-WSkKcihQLkxVLFtILlhDLFcud3osVy5lN10pCnMoSC5xaixILlhDKQpyKFAuY1gsW0guYlEsSC5VNSxQ
-Lm1XLEgudW5dKQpyKEguYlEsW0guYUwsSC5pNSxQLnh1XSkKcihILmFMLFtILm5ILEguQTgsUC5pOF0p
-CnMoSC5TTyxQLkFuKQpzKFAuUlUsUC5QbikKcyhQLkdqLFAuUlUpCnMoSC5QRCxQLkdqKQpzKEguTFAs
-SC5XVSkKcihILlRwLFtILkNqLEguQW0sSC5sYyxILmRDLEgud04sSC5WWCxQLnRoLFAuaGEsUC5WcyxQ
-LkZ0LFAueUgsUC5XTSxQLlNYLFAuR3MsUC5kYSxQLm9RLFAucFYsUC5VNyxQLnZyLFAuckgsUC5LRixQ
-LlpMLFAuUlQsUC5qWixQLnJxLFAuUlcsUC5CNSxQLlBJLFAucEssUC5oaixQLlZwLFAuT1IsUC5yYSxQ
-LldGLFAubjEsUC5jUyxQLlZDLFAudHAsUC5lMSxQLk5ZLFAuUlosUC5NRSxQLnk1LFAucTMsUC55SSxQ
-LmM2LFAucWQsVy5DdixXLmJVLFcuaEgsVy5LUyxXLkEzLFcudk4sVy5VdixXLkVnLFcuRW8sVy5XayxX
-LklBLFcuZm0sUC5sUixQLmpnLFAuR0UsUC5ONyxQLnVRLFAuUEMsUC5ZbSxQLk56LFAubnAsUC5VdCxM
-LmUsTC5WVyxMLm9aLEwuanIsTC5xbCxMLkwsTC5XeCxMLkFPLEwuZE4sTC5IbyxMLnh6LEwuSUMsTC5M
-MSxMLm5ULEwuQlosTC5HSCxMLkRULEwuZUgsTC56RCxMLk9FLEwuVFcsTC54cixMLkVFLEwuUUwsTC5W
-UyxMLlRELE0uTWksTS5xNyxNLk5vLFgucVJdKQpyKFAuWFMsW0guVzAsSC5heixILnZWLEguRXEsUC5D
-NixILnU5LFAubixQLnUsUC5tcCxQLnViLFAuZHMsUC5saixQLlVWLFAuY10pCnIoSC5sYyxbSC56eCxI
-LnJUXSkKcyhILmtZLFAuQzYpCnMoUC5pbCxQLllrKQpyKFAuaWwsW0guTjUsUC51dyxXLmNmLFcuU3ld
-KQpzKEguS1csUC5tVykKcyhILmIwLEguRVQpCnIoSC5iMCxbSC5SRyxILldCXSkKcyhILlZQLEguUkcp
-CnMoSC5EZyxILlZQKQpzKEguWkcsSC5XQikKcyhILlBnLEguWkcpCnIoSC5QZyxbSC54aixILmRFLEgu
-WkEsSC53ZixILlBxLEguZUUsSC5WNl0pCnIoSC51OSxbSC5oeixILmlNXSkKcyhQLlpmLFAuUGYpCnMo
-UC5KaSxQLm0wKQpzKFAuYjYsUC5YdikKcyhQLlZqLFAuV1kpCnIoUC5VayxbUC5DVixQLlppLFAuYnld
-KQpzKFAud0ksUC5rVCkKcihQLndJLFtQLlU4LFAuTXgsUC5FMyxQLkdZXSkKcyhQLnU1LFAuWmkpCnIo
-UC5GSyxbUC5DUCxQLktOXSkKcihQLnUsW1AuYkosUC5lWV0pCnMoUC5xZSxQLkRuKQpyKFcuRDAsW1cu
-dUgsVy53YSxXLks1LFcuQ21dKQpyKFcudUgsW1cuY3YsVy5ueCxXLlFGLFcuQ1FdKQpyKFcuY3YsW1cu
-cUUsUC5kNV0pCnIoVy5xRSxbVy5HaCxXLmZZLFcubkIsVy5RUCxXLmg0LFcuU04sVy5scCxXLlRiLFcu
-SXYsVy5CVCxXLnlZXSkKcyhXLm9KLFcuTGUpCnMoVy5UNSxXLkF6KQpzKFcuVmIsVy5RRikKcyhXLk83
-LFcud2EpCnIoVy5lYSxbVy53NixXLmV3XSkKcyhXLkFqLFcudzYpCnMoVy5yQixXLks3KQpzKFcuQkgs
-Vy5yQikKcyhXLnc0LFcuSUIpCnMoVy5vYSxXLlhXKQpzKFcucmgsVy5vYSkKcyhXLmk3LFcuY2YpCnMo
-UC5BcyxQLlZqKQpyKFAuQXMsW1cuSTQsUC5LZV0pCnMoVy5STyxQLnFoKQpzKFcuQ3EsVy5STykKcyhX
-LnhDLFAuTU8pCnMoVy5jdCxXLm02KQpzKFAuQmYsUC5pSikKcihQLkU0LFtQLnI3LFAuY29dKQpzKFAu
-VHosUC5jbykKcyhQLm5kLFAuZDUpCnMoQi5MdSxPLnpMKQpyKEIuTHUsW0UuT0YsRi5ydSxMLklWXSkK
-dChILlhDLEguUmUpCnQoSC5SRyxQLmxEKQp0KEguVlAsSC5TVSkKdChILldCLFAubEQpCnQoSC5aRyxI
-LlNVKQp0KFAublksUC5sRCkKdChQLldZLFAubGYpCnQoUC5SVSxQLktQKQp0KFcuTGUsVy5pZCkKdChX
-Lks3LFAubEQpCnQoVy5yQixXLkdtKQp0KFcuWFcsUC5sRCkKdChXLm9hLFcuR20pCnQoUC5jbyxQLmxE
-KX0pKCkKdmFyIHY9e3R5cGVVbml2ZXJzZTp7ZUM6bmV3IE1hcCgpLHRSOnt9LGVUOnt9LHRQVjp7fSxz
-RUE6W119LG1hbmdsZWRHbG9iYWxOYW1lczp7S046ImludCIsQ1A6ImRvdWJsZSIsRks6Im51bSIscVU6
-IlN0cmluZyIsYTI6ImJvb2wiLGM4OiJOdWxsIix6TToiTGlzdCJ9LG1hbmdsZWROYW1lczp7fSxnZXRU
-eXBlRnJvbU5hbWU6Z2V0R2xvYmFsRnJvbU5hbWUsbWV0YWRhdGE6W10sdHlwZXM6WyJjOCgpIiwiYzgo
-QCxAKSIsIn4oKSIsImM4KGN2KSIsIkAoQCkiLCJxVShxVSkiLCJjOChBaikiLCJjOChPNykiLCJhMihx
-VSkiLCJ+KH4oKSkiLCJjOChxVSxxVSkiLCJjOChxVSkiLCJjOChxVSxAKSIsImM4KGVhKSIsIn4oeHU8
-cVU+KSIsImEyKGN2LHFVLHFVLEpRKSIsIn4oQWopIiwiYTIoa0YpIiwiYzgoQCkiLCJLTihLTixLTiki
-LCJ+KEApIiwiYzgofigpKSIsIn4ocVUscVUpIiwiYzgoS04sQCkiLCJuNihALEApIiwiYTIodUgpIiwi
-fihxVVtAXSkiLCJjOChldykiLCJAKGVhKSIsIn4ocVUsS04pIiwiayhAKSIsIn4odUgsdUgpIiwiYzgo
-R0QsQCkiLCJjOChALEd6KSIsInI3KEApIiwiVHo8QD4oQCkiLCJFNChAKSIsInZzPEA+KEApIiwiQChA
-LHFVKSIsIlowPHFVLHFVPihaMDxxVSxxVT4scVUpIiwiQChxVSkiLCJPNyhPNykiLCJjOChAW0d6XSki
-LCJxVShLTikiLCJ+KGtbR3pdKSIsImEyKHh1PHFVPikiLCJuNihLTikiXSxpbnRlcmNlcHRvcnNCeVRh
-ZzpudWxsLGxlYWZUYWdzOm51bGx9CkgueGIodi50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgneyJjNSI6
-Ik1GIiwiaUMiOiJNRiIsImtkIjoiTUYiLCJyeCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiZDUiLCJXdCI6
-ImQ1IiwidjAiOiJldyIsIk1yIjoicUUiLCJlTCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgiLCJYZyI6
-IlFGIiwieWMiOiJBaiIsInk0IjoidzYiLCJhUCI6IkNtIiwieGMiOiJueCIsImtKIjoibngiLCJ6VSI6
-IkRnIiwiZGYiOiJFVCIsInlFIjp7ImEyIjpbXX0sIllFIjp7ImM4IjpbXX0sIk1GIjp7InZtIjpbXSwi
-RUgiOltdfSwiamQiOnsiek0iOlsiMSJdLCJjWCI6WyIxIl19LCJQbyI6eyJqZCI6WyIxIl0sInpNIjpb
-IjEiXSwiY1giOlsiMSJdfSwibTEiOnsiQW4iOlsiMSJdfSwicUkiOnsiQ1AiOltdLCJGSyI6W119LCJ1
-ciI6eyJLTiI6W10sIkNQIjpbXSwiRksiOltdfSwiVkEiOnsiQ1AiOltdLCJGSyI6W119LCJEciI6eyJx
-VSI6W10sInZYIjpbXX0sInFqIjp7IlJlIjpbIktOIl0sImxEIjpbIktOIl0sInpNIjpbIktOIl0sImNY
-IjpbIktOIl0sImxELkUiOiJLTiIsIlJlLkUiOiJLTiJ9LCJiUSI6eyJjWCI6WyIxIl19LCJhTCI6eyJj
-WCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImNYIjpbIjEiXSwiYUwuRSI6IjEiLCJjWC5FIjoiMSJ9
-LCJhNyI6eyJBbiI6WyIxIl19LCJBOCI6eyJhTCI6WyIyIl0sImNYIjpbIjIiXSwiYUwuRSI6IjIiLCJj
-WC5FIjoiMiJ9LCJVNSI6eyJjWCI6WyIxIl0sImNYLkUiOiIxIn0sIlNPIjp7IkFuIjpbIjEiXX0sIlhD
-Ijp7IlJlIjpbIjEiXSwibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImNYIjpbIjEiXX0sInd2Ijp7IkdEIjpb
-XX0sIlBEIjp7IkdqIjpbIjEiLCIyIl0sIlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpb
-IjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJXVSI6eyJaMCI6WyIxIiwiMiJdfSwiTFAiOnsiV1UiOlsi
-MSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIkxJIjp7InZRIjpbXX0sIlcwIjp7IlhTIjpbXX0sImF6Ijp7
-IlhTIjpbXX0sInZWIjp7IlhTIjpbXX0sIlhPIjp7Ikd6IjpbXX0sIlRwIjp7IkVIIjpbXX0sImxjIjp7
-IkVIIjpbXX0sInp4Ijp7IkVIIjpbXX0sInJUIjp7IkVIIjpbXX0sIkVxIjp7IlhTIjpbXX0sImtZIjp7
-IlhTIjpbXX0sIk41Ijp7IkZvIjpbIjEiLCIyIl0sIllrIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl0s
-IllrLksiOiIxIiwiWWsuViI6IjIifSwiaTUiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJONiI6eyJB
-biI6WyIxIl19LCJWUiI6eyJ3TCI6W10sInZYIjpbXX0sIkVLIjp7ImliIjpbXSwiT2QiOltdfSwiS1ci
-OnsiY1giOlsiaWIiXSwiY1guRSI6ImliIn0sIlBiIjp7IkFuIjpbImliIl19LCJ0USI6eyJPZCI6W119
-LCJ1biI6eyJjWCI6WyJPZCJdLCJjWC5FIjoiT2QifSwiU2QiOnsiQW4iOlsiT2QiXX0sIkVUIjp7IkFT
-IjpbXX0sImIwIjp7IlhqIjpbIkAiXSwiRVQiOltdLCJBUyI6W119LCJEZyI6eyJsRCI6WyJDUCJdLCJY
-aiI6WyJAIl0sInpNIjpbIkNQIl0sIkVUIjpbXSwiU1UiOlsiQ1AiXSwiQVMiOltdLCJjWCI6WyJDUCJd
-LCJsRC5FIjoiQ1AifSwiUGciOnsibEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6
-W10sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04iXX0sInhqIjp7ImxEIjpbIktOIl0sInpNIjpb
-IktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJTVSI6WyJLTiJdLCJBUyI6W10sImNYIjpbIktOIl0sImxE
-LkUiOiJLTiJ9LCJkRSI6eyJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJYaiI6WyJAIl0sIkVUIjpbXSwi
-U1UiOlsiS04iXSwiQVMiOltdLCJjWCI6WyJLTiJdLCJsRC5FIjoiS04ifSwiWkEiOnsibEQiOlsiS04i
-XSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsi
-S04iXSwibEQuRSI6IktOIn0sIndmIjp7ImxEIjpbIktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwi
-RVQiOltdLCJTVSI6WyJLTiJdLCJBUyI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJQcSI6eyJs
-RCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJYaiI6WyJAIl0sIkVUIjpbXSwiU1UiOlsiS04iXSwiQVMiOltd
-LCJjWCI6WyJLTiJdLCJsRC5FIjoiS04ifSwiZUUiOnsibEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoi
-OlsiQCJdLCJFVCI6W10sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0s
-IlY2Ijp7Im42IjpbXSwibEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sIlNV
-IjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0sInU5Ijp7IlhTIjpbXX0sImh6
-Ijp7IlhTIjpbXX0sImlNIjp7IlhTIjpbXX0sIlpmIjp7IlBmIjpbIjEiXX0sInZzIjp7ImI4IjpbIjEi
-XX0sIkN3Ijp7IlhTIjpbXX0sIm0wIjp7IkpCIjpbXX0sIkppIjp7IkpCIjpbXX0sImI2Ijp7Ilh2Ijpb
-IjEiXSwieHUiOlsiMSJdLCJjWCI6WyIxIl19LCJsbSI6eyJBbiI6WyIxIl19LCJtVyI6eyJjWCI6WyIx
-Il19LCJMVSI6eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwiY1giOlsiMSJdfSwiaWwiOnsiWWsiOlsiMSIs
-IjIiXSwiWjAiOlsiMSIsIjIiXX0sIllrIjp7IlowIjpbIjEiLCIyIl19LCJQbiI6eyJaMCI6WyIxIiwi
-MiJdfSwiR2oiOnsiUlUiOlsiMSIsIjIiXSwiUG4iOlsiMSIsIjIiXSwiS1AiOlsiMSIsIjIiXSwiWjAi
-OlsiMSIsIjIiXX0sIlZqIjp7ImxmIjpbIjEiXSwieHUiOlsiMSJdLCJjWCI6WyIxIl19LCJYdiI6eyJ4
-dSI6WyIxIl0sImNYIjpbIjEiXX0sInV3Ijp7IllrIjpbInFVIiwiQCJdLCJaMCI6WyJxVSIsIkAiXSwi
-WWsuSyI6InFVIiwiWWsuViI6IkAifSwiaTgiOnsiYUwiOlsicVUiXSwiY1giOlsicVUiXSwiYUwuRSI6
-InFVIiwiY1guRSI6InFVIn0sIkNWIjp7IlVrIjpbInpNPEtOPiIsInFVIl0sIlVrLlMiOiJ6TTxLTj4i
-fSwiVTgiOnsid0kiOlsiek08S04+IiwicVUiXX0sIlppIjp7IlVrIjpbInFVIiwiek08S04+Il19LCJi
-eSI6eyJVayI6WyJrIiwicVUiXSwiVWsuUyI6ImsifSwiTXgiOnsid0kiOlsicVUiLCJrIl19LCJ1NSI6
-eyJVayI6WyJxVSIsInpNPEtOPiJdLCJVay5TIjoicVUifSwiRTMiOnsid0kiOlsicVUiLCJ6TTxLTj4i
-XX0sIkdZIjp7IndJIjpbInpNPEtOPiIsInFVIl19LCJDUCI6eyJGSyI6W119LCJDNiI6eyJYUyI6W119
-LCJuIjp7IlhTIjpbXX0sInUiOnsiWFMiOltdfSwiYkoiOnsiWFMiOltdfSwiZVkiOnsiWFMiOltdfSwi
-bXAiOnsiWFMiOltdfSwidWIiOnsiWFMiOltdfSwiZHMiOnsiWFMiOltdfSwibGoiOnsiWFMiOltdfSwi
-VVYiOnsiWFMiOltdfSwiazUiOnsiWFMiOltdfSwiS1kiOnsiWFMiOltdfSwiYyI6eyJYUyI6W119LCJL
-TiI6eyJGSyI6W119LCJ6TSI6eyJjWCI6WyIxIl19LCJpYiI6eyJPZCI6W119LCJ4dSI6eyJjWCI6WyIx
-Il19LCJxVSI6eyJ2WCI6W119LCJSbiI6eyJCTCI6W119LCJEbiI6eyJpRCI6W119LCJVZiI6eyJpRCI6
-W119LCJxZSI6eyJpRCI6W119LCJxRSI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiR2giOnsiY3Yi
-OltdLCJ1SCI6W10sIkQwIjpbXX0sImZZIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJuQiI6eyJj
-diI6W10sInVIIjpbXSwiRDAiOltdfSwiUVAiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIm54Ijp7
-InVIIjpbXSwiRDAiOltdfSwiUUYiOnsidUgiOltdLCJEMCI6W119LCJJQiI6eyJ0biI6WyJGSyJdfSwi
-d3oiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImNYIjpbIjEiXSwibEQuRSI6IjEifSwiY3YiOnsidUgi
-OltdLCJEMCI6W119LCJUNSI6eyJBeiI6W119LCJoNCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwi
-VmIiOnsidUgiOltdLCJEMCI6W119LCJPNyI6eyJEMCI6W119LCJ3YSI6eyJEMCI6W119LCJBaiI6eyJl
-YSI6W119LCJlNyI6eyJsRCI6WyJ1SCJdLCJ6TSI6WyJ1SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoidUgi
-fSwidUgiOnsiRDAiOltdfSwiQkgiOnsiR20iOlsidUgiXSwibEQiOlsidUgiXSwiek0iOlsidUgiXSwi
-WGoiOlsidUgiXSwiY1giOlsidUgiXSwibEQuRSI6InVIIiwiR20uRSI6InVIIn0sIlNOIjp7ImN2Ijpb
-XSwidUgiOltdLCJEMCI6W119LCJldyI6eyJlYSI6W119LCJscCI6eyJjdiI6W10sInVIIjpbXSwiRDAi
-OltdfSwiVGIiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIkl2Ijp7ImN2IjpbXSwidUgiOltdLCJE
-MCI6W119LCJCVCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwieVkiOnsiY3YiOltdLCJ1SCI6W10s
-IkQwIjpbXX0sInc2Ijp7ImVhIjpbXX0sIks1Ijp7InY2IjpbXSwiRDAiOltdfSwiQ20iOnsiRDAiOltd
-fSwiQ1EiOnsidUgiOltdLCJEMCI6W119LCJ3NCI6eyJ0biI6WyJGSyJdfSwicmgiOnsiR20iOlsidUgi
+bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbD0kLmhMKCkKSi5sNShsLCIiKQppZihhPT1udWxs
+KXt0PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInAiKQp0LnRleHRDb250ZW50PSJTZWUgZGV0YWlscyBh
+Ym91dCBhIHByb3Bvc2VkIGVkaXQuIgpDLkx0LnNEKHQsSC5WTShbInBsYWNlaG9sZGVyIl0sdS5zKSkK
+Si5kaCh1LmguYihsLmFwcGVuZENoaWxkKHQpKSkKcmV0dXJufXM9YS5lCnQ9JC5uVSgpCnI9dC50TShz
+KQpxPWEuYwpwPWRvY3VtZW50Cm89dC5IUChzLEouVDAocC5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRl
+eHRDb250ZW50KSkKbj1hLmQKdD1wLmNyZWF0ZUVsZW1lbnQoInAiKQptPXUuaC5iKGwuYXBwZW5kQ2hp
+bGQodCkpCm0uYXBwZW5kQ2hpbGQocC5jcmVhdGVUZXh0Tm9kZShILmQocSkrIiBhdCAiK0guZChvKSsi
+OiIrSC5kKG4pKyIuIikpCkouZGgobSkKTC5DQyhhLGwscikKTC5GeihhLGwpCkwuTkcoYSxsLHIpfSwK
+TEg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQ9JC5t
+USgpCkoubDUoZCwiIikKdD1kb2N1bWVudApzPXQuY3JlYXRlRWxlbWVudCgicCIpCnI9dS5oCnE9ci5i
+KGQuYXBwZW5kQ2hpbGQocykpCnA9Yi5sZW5ndGgKaWYocD09PTApcS5hcHBlbmRDaGlsZCh0LmNyZWF0
+ZVRleHROb2RlKCJObyBwcm9wb3NlZCBlZGl0cyIpKQplbHNlIHEuYXBwZW5kQ2hpbGQodC5jcmVhdGVU
+ZXh0Tm9kZSgiIitwKyIgcHJvcG9zZWQgIitMLkx4KHAsImVkaXQiKSsiOiIpKQpzPXQuY3JlYXRlRWxl
+bWVudCgidWwiKQpvPXIuYihkLmFwcGVuZENoaWxkKHMpKQpmb3IoZD1iLmxlbmd0aCxzPXUuaSxuPXUu
+USxtPW4uQygifigxKSIpLGw9dS5NLG49bi5kLGs9MDtrPGIubGVuZ3RoO2IubGVuZ3RoPT09ZHx8KDAs
+SC5saykoYiksKytrKXtqPWJba10KaT10LmNyZWF0ZUVsZW1lbnQoImxpIikKaD1yLmIoby5hcHBlbmRD
+aGlsZChpKSkKSi5kUihoKS5pKDAsImVkaXQiKQppPXQuY3JlYXRlRWxlbWVudCgiYSIpCmc9cy5iKGgu
+YXBwZW5kQ2hpbGQoaSkpCmcuY2xhc3NMaXN0LmFkZCgiZWRpdC1saW5rIikKZj1qLmMKaT1ILmQoZikK
+Zy5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhnKSkuTygib2Zmc2V0IiksaSkK
+ZT1qLmEKaT1ILmQoZSkKZy5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhnKSku
+TygibGluZSIpLGkpCmcuYXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9kZSgibGluZSAiK0guZChlKSkp
+Cmk9bS5iKG5ldyBMLkVFKGYsZSxhKSkKbC5iKG51bGwpClcuSkUoZywiY2xpY2siLGksITEsbikKaC5h
+cHBlbmRDaGlsZCh0LmNyZWF0ZVRleHROb2RlKCI6ICIrSC5kKGouYikpKX1pZihjKUwuVDEobnVsbCl9
+LApGcjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9d2luZG93LmxvY2F0aW9uLHA9UC5oSygocSYm
+Qy5FeCkuZ0RyKHEpK0guZChhKSkKcT11LnoKdD1QLkZsKHUuTixxKQppZihiIT1udWxsKXQuWSgwLCJv
+ZmZzZXQiLEguZChiKSkKaWYoYyE9bnVsbCl0LlkoMCwibGluZSIsSC5kKGMpKQpwPXAubm0oMCx0LmE9
+PT0wP251bGw6dCkKcz13aW5kb3cuaGlzdG9yeQpyPXAudygwKQpzLnRvU3RyaW5nCnMucHVzaFN0YXRl
+KG5ldyBQLkJmKFtdLFtdKS5QdihQLkZsKHEscSkpLCIiLHIpfSwKRW46ZnVuY3Rpb24oYSl7dmFyIHQ9
+Si5iYihkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50LCIvIikKaWYoQy54
+Qi5uKGEsdCkpcmV0dXJuIEMueEIuRyhhLHQubGVuZ3RoKQplbHNlIHJldHVybiBhfSwKQlg6ZnVuY3Rp
+b24oYSxiKXt2YXIgdCxzLHI9e30Kci5hPWEKYT1MLkVuKGEpCnIuYT1hCiQuRDkoKS50ZXh0Q29udGVu
+dD1hCnQ9ZG9jdW1lbnQKcz11LmgKSC5EaChzLHMsIlQiLCJxdWVyeVNlbGVjdG9yQWxsIikKdD1uZXcg
+Vy53eih0LnF1ZXJ5U2VsZWN0b3JBbGwoIi5uYXYtcGFuZWwgLm5hdi1saW5rIiksdS5TKQp0LksodCxu
+ZXcgTC5WUyhyKSl9LApCRTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9Ii5yZWdpb25zIixzPWRvY3VtZW50
+LHI9cy5xdWVyeVNlbGVjdG9yKHQpLHE9cy5xdWVyeVNlbGVjdG9yKCIuY29kZSIpCkoudEgocixiLmEs
+JC5LRygpKQpKLnRIKHEsYi5iLCQuS0coKSkKTC5MSChhLGIuZCxjKQpMLnZVKCkKTC55WCgiLmNvZGUi
+LCEwKQpMLnlYKHQsITApfSwKdFg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxq
+LGk9ZG9jdW1lbnQsaD1pLmNyZWF0ZUVsZW1lbnQoInVsIiksZz11LmgsZj1nLmIoYS5hcHBlbmRDaGls
+ZChoKSkKZm9yKGg9Yi5sZW5ndGgsdD11Lk0scz0wO3M8Yi5sZW5ndGg7Yi5sZW5ndGg9PT1ofHwoMCxI
+LmxrKShiKSwrK3Mpe3I9YltzXQpxPWkuY3JlYXRlRWxlbWVudCgibGkiKQpwPWcuYihmLmFwcGVuZENo
+aWxkKHEpKQpxPUouUkUocCkKaWYoci5hPT09Qy5ZMil7cS5nRChwKS5pKDAsImRpciIpCnE9aS5jcmVh
+dGVFbGVtZW50KCJzcGFuIikKbz1nLmIocC5hcHBlbmRDaGlsZChxKSkKcT1KLlJFKG8pCnEuZ0Qobyku
+aSgwLCJhcnJvdyIpCnEuc2hmKG8sIiYjeDI1QkM7IikKcT1pLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpK
+Lmw1KGcuYihwLmFwcGVuZENoaWxkKHEpKSwiJiN4MUY0QzE7IikKcC5hcHBlbmRDaGlsZChpLmNyZWF0
+ZVRleHROb2RlKHIuYikpCkwudFgocCxyLmMpCkwua3oobyl9ZWxzZXtxLnNoZihwLCImI3gxRjRDNDsi
+KQpxPWkuY3JlYXRlRWxlbWVudCgiYSIpCm49Zy5iKHAuYXBwZW5kQ2hpbGQocSkpCnE9Si5SRShuKQpx
+LmdEKG4pLmkoMCwibmF2LWxpbmsiKQpuLnNldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBX
+Lmk3KG4pKS5PKCJuYW1lIiksci5kKQpuLnNldEF0dHJpYnV0ZSgiaHJlZiIsci5lKQpuLmFwcGVuZENo
+aWxkKGkuY3JlYXRlVGV4dE5vZGUoci5iKSkKcT1xLmdWbChuKQptPXEuJHRpCmw9bS5DKCJ+KDEpIiku
+YihuZXcgTC5URCgpKQp0LmIobnVsbCkKVy5KRShxLmEscS5iLGwsITEsbS5kKQprPXIuZgppZih0eXBl
+b2YgayE9PSJudW1iZXIiKXJldHVybiBrLm9zKCkKaWYoaz4wKXtxPWkuY3JlYXRlRWxlbWVudCgic3Bh
+biIpCmo9Zy5iKHAuYXBwZW5kQ2hpbGQocSkpCkouZFIoaikuaSgwLCJlZGl0LWNvdW50IikKcT0iIitr
+KyIgIgppZihrPT09MSltPSJlZGl0IgplbHNlIG09ImVkaXRzIgpqLnNldEF0dHJpYnV0ZSgidGl0bGUi
+LHErbSkKai5hcHBlbmRDaGlsZChpLmNyZWF0ZVRleHROb2RlKEMuam4udyhrKSkpfX19fSwKYzQ6ZnVu
+Y3Rpb24oYSxiKXt2YXIgdD1kb2N1bWVudCxzPXQuY3JlYXRlRWxlbWVudCgiYSIpCnUuaS5iKHMpCnMu
+YXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9kZShILmQoYS5jKSsiOiIrSC5kKGEuYikpKQp0PUQubnIo
+YixhLmEpCnMuc2V0QXR0cmlidXRlKCJocmVmIiwkLm5VKCkubzUodCkpCnMuY2xhc3NMaXN0LmFkZCgi
+bmF2LWxpbmsiKQpyZXR1cm4gc30sCkZ6OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxs
+LGssaixpPWEuYgppZihpIT1udWxsKWZvcih0PWkubGVuZ3RoLHM9dS5oLHI9dS5zLHE9dS5YLHA9MDtw
+PGkubGVuZ3RoO2kubGVuZ3RoPT09dHx8KDAsSC5saykoaSksKytwKXtvPWlbcF0Kbj1kb2N1bWVudApt
+PW4uY3JlYXRlRWxlbWVudCgicCIpCmw9cy5iKGIuYXBwZW5kQ2hpbGQobSkpCm09bi5jcmVhdGVFbGVt
+ZW50KCJhIikKaz1zLmIobC5hcHBlbmRDaGlsZChtKSkKay5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHRO
+b2RlKG8uYSkpCmsuc2V0QXR0cmlidXRlKCJocmVmIixvLmIpCm49cS5iKEguVk0oWyJwb3N0LWxpbmsi
+LCJiZWZvcmUtYXBwbHkiXSxyKSkKaj1KLmRSKGspCmouVjEoMCkKai5GVigwLG4pfX0sCk5HOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9YS5hCmlmKGwubGVuZ3RoIT09MCl7dD1kb2N1
+bWVudApzPXQuY3JlYXRlRWxlbWVudCgicCIpCnMudGV4dENvbnRlbnQ9IkVkaXQgcmF0aW9uYWxlIChl
+eHBlcmltZW50YWwpOiIKYi5hcHBlbmRDaGlsZChzKQpzPXQuY3JlYXRlRWxlbWVudCgidWwiKQpyPXUu
+aC5iKGIuYXBwZW5kQ2hpbGQocykpCmZvcihzPWwubGVuZ3RoLHE9MDtxPGwubGVuZ3RoO2wubGVuZ3Ro
+PT09c3x8KDAsSC5saykobCksKytxKXtwPWxbcV0Kbz10LmNyZWF0ZUVsZW1lbnQoImxpIikKbj1yLmFw
+cGVuZENoaWxkKG8pCm4uYXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9kZShwLmEpKQptPXAuYgppZiht
+IT1udWxsKXtuLmFwcGVuZENoaWxkKHQuY3JlYXRlVGV4dE5vZGUoIiAoIikpCm4uYXBwZW5kQ2hpbGQo
+TC5jNChtLGMpKQpuLmFwcGVuZENoaWxkKHQuY3JlYXRlVGV4dE5vZGUoIikiKSl9fX19LApDQzpmdW5j
+dGlvbihhLGIsYTApe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYwpmb3IodD1h
+LmYscz10Lmxlbmd0aCxyPXUucyxxPXUuWCxwPTA7cDx0Lmxlbmd0aDt0Lmxlbmd0aD09PXN8fCgwLEgu
+bGspKHQpLCsrcCl7bz10W3BdCm49ZG9jdW1lbnQKbT1uLmNyZWF0ZUVsZW1lbnQoInAiKQpsPXEuYihI
+LlZNKFsidHJhY2UiXSxyKSkKaz1KLmRSKG0pCmsuVjEoMCkKay5GVigwLGwpCmo9Yi5hcHBlbmRDaGls
+ZChtKQptPW4uY3JlYXRlRWxlbWVudCgic3BhbiIpCmw9cS5iKEguVk0oWyJ0eXBlLWRlc2NyaXB0aW9u
+Il0scikpCms9Si5kUihtKQprLlYxKDApCmsuRlYoMCxsKQptLmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4
+dE5vZGUoby5hKSkKai5hcHBlbmRDaGlsZChtKQpqLmFwcGVuZENoaWxkKG4uY3JlYXRlVGV4dE5vZGUo
+IjoiKSkKbT1uLmNyZWF0ZUVsZW1lbnQoInVsIikKbD1xLmIoSC5WTShbInRyYWNlIl0scikpCms9Si5k
+UihtKQprLlYxKDApCmsuRlYoMCxsKQppPWouYXBwZW5kQ2hpbGQobSkKZm9yKG09by5iLGw9bS5sZW5n
+dGgsaD0wO2g8bS5sZW5ndGg7bS5sZW5ndGg9PT1sfHwoMCxILmxrKShtKSwrK2gpe2c9bVtoXQpmPW4u
+Y3JlYXRlRWxlbWVudCgibGkiKQpKLmw1KGYsIiYjeDI3NEY7ICIpCmU9aS5hcHBlbmRDaGlsZChmKQpm
+PW4uY3JlYXRlRWxlbWVudCgic3BhbiIpCmQ9cS5iKEguVk0oWyJmdW5jdGlvbiJdLHIpKQprPUouZFIo
+ZikKay5WMSgwKQprLkZWKDAsZCkKZD1nLmIKaWYoZD09bnVsbClkPSJ1bmtub3duIgpmLmFwcGVuZENo
+aWxkKG4uY3JlYXRlVGV4dE5vZGUoZCkpCmUuYXBwZW5kQ2hpbGQoZikKYz1nLmMKaWYoYyE9bnVsbCl7
+ZS5hcHBlbmRDaGlsZChuLmNyZWF0ZVRleHROb2RlKCIgKCIpKQplLmFwcGVuZENoaWxkKEwuYzQoYyxh
+MCkpCmUuYXBwZW5kQ2hpbGQobi5jcmVhdGVUZXh0Tm9kZSgiKSIpKX1lLmFwcGVuZENoaWxkKG4uY3Jl
+YXRlVGV4dE5vZGUoIjogIikpCmUuYXBwZW5kQ2hpbGQobi5jcmVhdGVUZXh0Tm9kZShnLmEpKX19fSwK
+ZTpmdW5jdGlvbiBlKCl7fSwKVlc6ZnVuY3Rpb24gVlcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRo
+aXMuYz1jfSwKb1o6ZnVuY3Rpb24gb1ooKXt9LApqcjpmdW5jdGlvbiBqcigpe30sCnFsOmZ1bmN0aW9u
+IHFsKCl7fSwKTDpmdW5jdGlvbiBMKCl7fSwKV3g6ZnVuY3Rpb24gV3goYSxiKXt0aGlzLmE9YQp0aGlz
+LmI9Yn0sCkFPOmZ1bmN0aW9uIEFPKGEpe3RoaXMuYT1hfSwKZE46ZnVuY3Rpb24gZE4oYSl7dGhpcy5h
+PWF9LApIbzpmdW5jdGlvbiBIbyhhKXt0aGlzLmE9YX0sCnh6OmZ1bmN0aW9uIHh6KGEsYil7dGhpcy5h
+PWEKdGhpcy5iPWJ9LApJQzpmdW5jdGlvbiBJQygpe30sCkwxOmZ1bmN0aW9uIEwxKCl7fSwKblQ6ZnVu
+Y3Rpb24gblQoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKQlo6ZnVuY3Rpb24gQloo
+YSl7dGhpcy5hPWF9LApHSDpmdW5jdGlvbiBHSCgpe30sCkRUOmZ1bmN0aW9uIERUKCl7fSwKZUg6ZnVu
+Y3Rpb24gZUgoYSl7dGhpcy5hPWF9LAp6RDpmdW5jdGlvbiB6RChhLGIsYyxkLGUpe3ZhciBfPXRoaXMK
+Xy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWV9LApPRTpmdW5jdGlvbiBPRShhKXt0aGlzLmE9YX0s
+ClRXOmZ1bmN0aW9uIFRXKCl7fSwKeHI6ZnVuY3Rpb24geHIoYSl7dGhpcy5hPWF9LApFRTpmdW5jdGlv
+biBFRShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApRTDpmdW5jdGlvbiBRTChhLGIp
+e3RoaXMuYT1hCnRoaXMuYj1ifSwKVlM6ZnVuY3Rpb24gVlMoYSl7dGhpcy5hPWF9LApURDpmdW5jdGlv
+biBURCgpe30sClhBOmZ1bmN0aW9uIFhBKCl7fSwKbUs6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxv
+LG49SC5WTShbXSx1LmZoKQpmb3IodD1KLklUKHUuUi5iKGEpKTt0LkYoKTspe3M9dC5nbCgpCnI9Si5V
+NihzKQpxPUwucDIoSC55KHIucShzLCJ0eXBlIikpKQpwPUgueShyLnEocywibmFtZSIpKQpvPXIucShz
+LCJzdWJ0cmVlIikKbz1vPT1udWxsP251bGw6TC5tSyhvKQpDLk5tLmkobixuZXcgTC5aWihxLHAsbyxI
+Lnkoci5xKHMsInBhdGgiKSksSC55KHIucShzLCJocmVmIikpLEguU2Moci5xKHMsImVkaXRDb3VudCIp
+KSkpfXJldHVybiBufSwKcDI6ZnVuY3Rpb24oYSl7c3dpdGNoKGEpe2Nhc2UiZGlyZWN0b3J5IjpyZXR1
+cm4gQy5ZMgpjYXNlImZpbGUiOnJldHVybiBDLnJmCmRlZmF1bHQ6dGhyb3cgSC5iKFAuUFYoIlVucmVj
+b2duaXplZCBuYXZpZ2F0aW9uIHRyZWUgbm9kZSB0eXBlOiAiK0guZChhKSkpfX0sClpaOmZ1bmN0aW9u
+IFpaKGEsYixjLGQsZSxmKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8u
+Zj1mfSwKeTg6ZnVuY3Rpb24geTgoYSl7dGhpcy5iPWF9LApJVjpmdW5jdGlvbiBJVihhLGIsYyxkKXt2
+YXIgXz10aGlzCl8uZD1hCl8uZT1iCl8uZj1jCl8ucj1kfX0sTT17CllGOmZ1bmN0aW9uKGEsYil7dmFy
+IHQscyxyLHEscCxvLG4KZm9yKHQ9Yi5sZW5ndGgscz0xO3M8dDsrK3Mpe2lmKGJbc109PW51bGx8fGJb
+cy0xXSE9bnVsbCljb250aW51ZQpmb3IoO3Q+PTE7dD1yKXtyPXQtMQppZihiW3JdIT1udWxsKWJyZWFr
+fXE9bmV3IFAuUm4oIiIpCnA9YSsiKCIKcS5hPXAKbz1ILnFDKGIsMCx0LEgudDYoYikuZCkKbj1vLiR0
+aQpuPXArbmV3IEguQTgobyxuLkMoInFVKGFMLkUpIikuYihuZXcgTS5ObygpKSxuLkMoIkE4PGFMLkUs
+cVU+IikpLkgoMCwiLCAiKQpxLmE9bgpxLmE9bisoIik6IHBhcnQgIisocy0xKSsiIHdhcyBudWxsLCBi
+dXQgcGFydCAiK3MrIiB3YXMgbm90LiIpCnRocm93IEguYihQLnhZKHEudygwKSkpfX0sCmxJOmZ1bmN0
+aW9uIGxJKGEpe3RoaXMuYT1hfSwKTWk6ZnVuY3Rpb24gTWkoKXt9LApxNzpmdW5jdGlvbiBxNygpe30s
+Ck5vOmZ1bmN0aW9uIE5vKCl7fX0sWD17CkNMOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPWIu
+eFooYSkKYi5oSyhhKQppZihvIT1udWxsKWE9Si5LVihhLG8ubGVuZ3RoKQp0PXUucwpzPUguVk0oW10s
+dCkKcj1ILlZNKFtdLHQpCnQ9YS5sZW5ndGgKaWYodCE9PTAmJmIucjQoQy54Qi5XKGEsMCkpKXtpZigw
+Pj10KXJldHVybiBILk9IKGEsMCkKQy5ObS5pKHIsYVswXSkKcT0xfWVsc2V7Qy5ObS5pKHIsIiIpCnE9
+MH1mb3IocD1xO3A8dDsrK3ApaWYoYi5yNChDLnhCLlcoYSxwKSkpe0MuTm0uaShzLEMueEIuTmooYSxx
+LHApKQpDLk5tLmkocixhW3BdKQpxPXArMX1pZihxPHQpe0MuTm0uaShzLEMueEIuRyhhLHEpKQpDLk5t
+LmkociwiIil9cmV0dXJuIG5ldyBYLldEKGIsbyxzLHIpfSwKV0Q6ZnVuY3Rpb24gV0QoYSxiLGMsZCl7
+dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9YwpfLmU9ZH0sCnFSOmZ1bmN0aW9uIHFSKGEpe3RoaXMu
+YT1hfSwKSlQ6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBYLmR2KGEpfSwKZHY6ZnVuY3Rpb24gZHYoYSl7
+dGhpcy5hPWF9fSxPPXsKUmg6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGk9bnVs
+bAppZihQLnVvKCkuZ0ZpKCkhPT0iZmlsZSIpcmV0dXJuICQuRWIoKQp0PVAudW8oKQppZighQy54Qi5U
+Yyh0LmdJaSh0KSwiLyIpKXJldHVybiAkLkViKCkKcz1QLlBpKGksMCwwKQpyPVAuelIoaSwwLDApCnE9
+UC5PZShpLDAsMCwhMSkKcD1QLmxlKGksMCwwLGkpCm89UC50RyhpLDAsMCkKbj1QLndCKGkscykKbT1z
+PT09ImZpbGUiCmlmKHE9PW51bGwpdD1yLmxlbmd0aCE9PTB8fG4hPW51bGx8fG0KZWxzZSB0PSExCmlm
+KHQpcT0iIgp0PXE9PW51bGwKbD0hdAprPVAua2EoImEvYiIsMCwzLGkscyxsKQpqPXMubGVuZ3RoPT09
+MAppZihqJiZ0JiYhQy54Qi5uKGssIi8iKSlrPVAud0Yoaywhanx8bCkKZWxzZSBrPVAueGUoaykKaWYo
+bmV3IFAuRG4ocyxyLHQmJkMueEIubihrLCIvLyIpPyIiOnEsbixrLHAsbykudDQoKT09PSJhXFxiIily
+ZXR1cm4gJC5LaygpCnJldHVybiAkLmJEKCl9LAp6TDpmdW5jdGlvbiB6TCgpe319LEU9e09GOmZ1bmN0
+aW9uIE9GKGEsYixjKXt0aGlzLmQ9YQp0aGlzLmU9Ygp0aGlzLmY9Y319LEY9e3J1OmZ1bmN0aW9uIHJ1
+KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5kPWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxEPXsKUlg6ZnVuY3Rp
+b24oKXt2YXIgdCxzLHI9UC51bygpCmlmKEouUk0ociwkLkk2KSlyZXR1cm4gJC5GZgokLkk2PXIKaWYo
+JC5IaygpPT0kLkViKCkpcmV0dXJuICQuRmY9ci5aSSgiLiIpLncoMCkKZWxzZXt0PXIudDQoKQpzPXQu
+bGVuZ3RoLTEKcmV0dXJuICQuRmY9cz09PTA/dDpDLnhCLk5qKHQsMCxzKX19LApucjpmdW5jdGlvbihh
+LGIpe3ZhciB0PW51bGwKcmV0dXJuICQublUoKS5xNygwLGEsYix0LHQsdCx0LHQsdCl9fQp2YXIgdz1b
+QyxILEosUCxXLFUsQixULEwsTSxYLE8sRSxGLERdCmh1bmtIZWxwZXJzLnNldEZ1bmN0aW9uTmFtZXNJ
+Zk5lY2Vzc2FyeSh3KQp2YXIgJD17fQpILmVvLnByb3RvdHlwZT17fQpKLnZCLnByb3RvdHlwZT17CkRO
+OmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEp
+fSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5kKEguTShhKSkrIicifSwKZTc6
+ZnVuY3Rpb24oYSxiKXt1Lm8uYihiKQp0aHJvdyBILmIoUC5scihhLGIuZ1dhKCksYi5nbmQoKSxiLmdW
+bSgpKSl9fQpKLnlFLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCmdp
+TzpmdW5jdGlvbihhKXtyZXR1cm4gYT81MTkwMTg6MjE4MTU5fSwKJGlhMjoxfQpKLllFLnByb3RvdHlw
+ZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG51bGw9PWJ9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiJu
+dWxsIn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gMH0sCmU3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRo
+aXMuU2ooYSx1Lm8uYihiKSl9LAokaWM4OjF9CkouTUYucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEp
+e3JldHVybiAwfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGl2bToxfQpKLmlDLnBy
+b3RvdHlwZT17fQpKLmtkLnByb3RvdHlwZT17fQpKLmM1LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7
+dmFyIHQ9YVskLncoKV0KaWYodD09bnVsbClyZXR1cm4gdGhpcy50KGEpCnJldHVybiJKYXZhU2NyaXB0
+IGZ1bmN0aW9uIGZvciAiK0guZChKLmoodCkpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm57ZnVuYzoxLG9w
+dDpbLCwsLCwsLCwsLCwsLCwsLF19fSwKJGlFSDoxfQpKLmpkLnByb3RvdHlwZT17Cmk6ZnVuY3Rpb24o
+YSxiKXtILnQ2KGEpLmQuYihiKQppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiYWRkIikpCmEu
+cHVzaChiKX0sClc0OmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoISFhLmZpeGVkJGxlbmd0aClILnZoKFAu
+TDQoInJlbW92ZUF0IikpCnQ9YS5sZW5ndGgKaWYoYj49dCl0aHJvdyBILmIoUC54KGIsbnVsbCkpCnJl
+dHVybiBhLnNwbGljZShiLDEpWzBdfSwKVUc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscgpILnQ2KGEp
+LkMoImNYPDE+IikuYihjKQppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiaW5zZXJ0QWxsIikp
+CnQ9YS5sZW5ndGgKUC53QShiLDAsdCwiaW5kZXgiKQpzPWMubGVuZ3RoCnRoaXMuc0EoYSx0K3MpCnI9
+YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEsYikKdGhpcy52ZyhhLGIscixjKX0sCm12OmZ1bmN0aW9u
+KGEpe2lmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJyZW1vdmVMYXN0IikpCmlmKGEubGVuZ3Ro
+PT09MCl0aHJvdyBILmIoSC5IWShhLC0xKSkKcmV0dXJuIGEucG9wKCl9LApGVjpmdW5jdGlvbihhLGIp
+e3ZhciB0CkgudDYoYSkuQygiY1g8MT4iKS5iKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0
+KCJhZGRBbGwiKSkKZm9yKHQ9Si5JVChiKTt0LkYoKTspYS5wdXNoKHQuZ2woKSl9LApLOmZ1bmN0aW9u
+KGEsYil7dmFyIHQscwpILnQ2KGEpLkMoIn4oMSkiKS5iKGIpCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7
+KytzKXtiLiQxKGFbc10pCmlmKGEubGVuZ3RoIT09dCl0aHJvdyBILmIoUC5hNChhKSl9fSwKRTI6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciB0PUgudDYoYSkKcmV0dXJuIG5ldyBILkE4KGEsdC5LcShjKS5DKCIxKDIp
+IikuYihiKSx0LkMoIkA8MT4iKS5LcShjKS5DKCJBODwxLDI+IikpfSwKSDpmdW5jdGlvbihhLGIpe3Zh
+ciB0LHM9bmV3IEFycmF5KGEubGVuZ3RoKQpzLmZpeGVkJGxlbmd0aD1BcnJheQpmb3IodD0wO3Q8YS5s
+ZW5ndGg7Kyt0KXRoaXMuWShzLHQsSC5kKGFbdF0pKQpyZXR1cm4gcy5qb2luKGIpfSwKTjA6ZnVuY3Rp
+b24oYSxiLGMsZCl7dmFyIHQscyxyCmQuYihiKQpILnQ2KGEpLktxKGQpLkMoIjEoMSwyKSIpLmIoYykK
+dD1hLmxlbmd0aApmb3Iocz1iLHI9MDtyPHQ7KytyKXtzPWMuJDIocyxhW3JdKQppZihhLmxlbmd0aCE9
+PXQpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiBzfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49
+YS5sZW5ndGgpcmV0dXJuIEguT0goYSxiKQpyZXR1cm4gYVtiXX0sCkQ2OmZ1bmN0aW9uKGEsYixjKXtp
+ZihiPDB8fGI+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYiwwLGEubGVuZ3RoLCJzdGFydCIsbnVsbCkp
+CmlmKGM8Ynx8Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLGIsYS5sZW5ndGgsImVuZCIsbnVsbCkp
+CmlmKGI9PT1jKXJldHVybiBILlZNKFtdLEgudDYoYSkpCnJldHVybiBILlZNKGEuc2xpY2UoYixjKSxI
+LnQ2KGEpKX0sCmdyWjpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PjApcmV0dXJuIGFbdC0x
+XQp0aHJvdyBILmIoSC5XcCgpKX0sCllXOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyPUgudDYo
+YSkKci5DKCJjWDwxPiIpLmIoZCkKaWYoISFhLmltbXV0YWJsZSRsaXN0KUgudmgoUC5MNCgic2V0UmFu
+Z2UiKSkKUC5qQihiLGMsYS5sZW5ndGgpCnQ9Yy1iCmlmKHQ9PT0wKXJldHVybgpQLmsxKGUsInNraXBD
+b3VudCIpCnIuQygiek08MT4iKS5iKGQpCnI9Si5VNihkKQppZihlK3Q+ci5nQShkKSl0aHJvdyBILmIo
+SC5hcigpKQppZihlPGIpZm9yKHM9dC0xO3M+PTA7LS1zKWFbYitzXT1yLnEoZCxlK3MpCmVsc2UgZm9y
+KHM9MDtzPHQ7KytzKWFbYitzXT1yLnEoZCxlK3MpfSwKdmc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJu
+IHRoaXMuWVcoYSxiLGMsZCwwKX0sClZyOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnQ2KGEpLkMoImEy
+KDEpIikuYihiKQp0PWEubGVuZ3RoCmZvcihzPTA7czx0Oysrcyl7aWYoSC5vVChiLiQxKGFbc10pKSly
+ZXR1cm4hMAppZihhLmxlbmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiExfSwKdGc6ZnVu
+Y3Rpb24oYSxiKXt2YXIgdApmb3IodD0wO3Q8YS5sZW5ndGg7Kyt0KWlmKEouUk0oYVt0XSxiKSlyZXR1
+cm4hMApyZXR1cm4hMX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX0sCmdrejpm
+dW5jdGlvbihhKXtyZXR1cm4gbmV3IEoubTEoYSxhLmxlbmd0aCxILnQ2KGEpLkMoIm0xPDE+IikpfSwK
+Z2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVu
+Z3RofSwKc0E6ZnVuY3Rpb24oYSxiKXtpZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgic2V0IGxl
+bmd0aCIpKQppZihiPDApdGhyb3cgSC5iKFAuVEUoYiwwLG51bGwsIm5ld0xlbmd0aCIsbnVsbCkpCmEu
+bGVuZ3RoPWJ9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj1hLmxlbmd0aHx8YjwwKXRocm93
+IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC50NihhKS5kLmIo
+YykKaWYoISFhLmltbXV0YWJsZSRsaXN0KUgudmgoUC5MNCgiaW5kZXhlZCBzZXQiKSkKaWYoYj49YS5s
+ZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQphW2JdPWN9LAokaWNYOjEsCiRpek06MX0KSi5Q
+by5wcm90b3R5cGU9e30KSi5tMS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9
+LApGOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLHI9cy5hLHE9ci5sZW5ndGgKaWYocy5iIT09cSl0aHJv
+dyBILmIoSC5sayhyKSkKdD1zLmMKaWYodD49cSl7cy5zTShudWxsKQpyZXR1cm4hMX1zLnNNKHJbdF0p
+Oysrcy5jCnJldHVybiEwfSwKc006ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRp
+QW46MX0KSi5xSS5wcm90b3R5cGU9ewp5dTpmdW5jdGlvbihhKXt2YXIgdAppZihhPj0tMjE0NzQ4MzY0
+OCYmYTw9MjE0NzQ4MzY0NylyZXR1cm4gYXwwCmlmKGlzRmluaXRlKGEpKXt0PWE8MD9NYXRoLmNlaWwo
+YSk6TWF0aC5mbG9vcihhKQpyZXR1cm4gdCswfXRocm93IEguYihQLkw0KCIiK2ErIi50b0ludCgpIikp
+fSwKelE6ZnVuY3Rpb24oYSl7aWYoYT4wKXtpZihhIT09MS8wKXJldHVybiBNYXRoLnJvdW5kKGEpfWVs
+c2UgaWYoYT4tMS8wKXJldHVybiAwLU1hdGgucm91bmQoMC1hKQp0aHJvdyBILmIoUC5MNCgiIithKyIu
+cm91bmQoKSIpKX0sCldaOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKaWYoYjwyfHxiPjM2KXRocm93
+IEguYihQLlRFKGIsMiwzNiwicmFkaXgiLG51bGwpKQp0PWEudG9TdHJpbmcoYikKaWYoQy54Qi5tKHQs
+dC5sZW5ndGgtMSkhPT00MSlyZXR1cm4gdApzPS9eKFtcZGEtel0rKSg/OlwuKFtcZGEtel0rKSk/XChl
+XCsoXGQrKVwpJC8uZXhlYyh0KQppZihzPT1udWxsKUgudmgoUC5MNCgiVW5leHBlY3RlZCB0b1N0cmlu
+ZyByZXN1bHQ6ICIrdCkpCnI9cy5sZW5ndGgKaWYoMT49cilyZXR1cm4gSC5PSChzLDEpCnQ9c1sxXQpp
+ZigzPj1yKXJldHVybiBILk9IKHMsMykKcT0rc1szXQpyPXNbMl0KaWYociE9bnVsbCl7dCs9cgpxLT1y
+Lmxlbmd0aH1yZXR1cm4gdCtDLnhCLkl4KCIwIixxKX0sCnc6ZnVuY3Rpb24oYSl7aWYoYT09PTAmJjEv
+YTwwKXJldHVybiItMC4wIgplbHNlIHJldHVybiIiK2F9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxy
+LHEscD1hfDAKaWYoYT09PXApcmV0dXJuIDUzNjg3MDkxMSZwCnQ9TWF0aC5hYnMoYSkKcz1NYXRoLmxv
+Zyh0KS8wLjY5MzE0NzE4MDU1OTk0NTN8MApyPU1hdGgucG93KDIscykKcT10PDE/dC9yOnIvdApyZXR1
+cm4gNTM2ODcwOTExJigocSo5MDA3MTk5MjU0NzQwOTkyfDApKyhxKjM1NDIyNDMxODExNzY1MjF8MCkp
+KjU5OTE5NytzKjEyNTl9LAp6WTpmdW5jdGlvbihhLGIpe3ZhciB0PWElYgppZih0PT09MClyZXR1cm4g
+MAppZih0PjApcmV0dXJuIHQKaWYoYjwwKXJldHVybiB0LWIKZWxzZSByZXR1cm4gdCtifSwKd0c6ZnVu
+Y3Rpb24oYSxiKXt2YXIgdAppZihhPjApdD10aGlzLnAzKGEsYikKZWxzZXt0PWI+MzE/MzE6Ygp0PWE+
+PnQ+Pj4wfXJldHVybiB0fSwKYmY6ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5iKEgudEwoYikp
+CnJldHVybiB0aGlzLnAzKGEsYil9LApwMzpmdW5jdGlvbihhLGIpe3JldHVybiBiPjMxPzA6YT4+PmJ9
+LAokaUNQOjEsCiRpRks6MX0KSi51ci5wcm90b3R5cGU9eyRpS046MX0KSi5WQS5wcm90b3R5cGU9e30K
+Si5Eci5wcm90b3R5cGU9ewptOmZ1bmN0aW9uKGEsYil7aWYoYjwwKXRocm93IEguYihILkhZKGEsYikp
+CmlmKGI+PWEubGVuZ3RoKUgudmgoSC5IWShhLGIpKQpyZXR1cm4gYS5jaGFyQ29kZUF0KGIpfSwKVzpm
+dW5jdGlvbihhLGIpe2lmKGI+PWEubGVuZ3RoKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhLmNo
+YXJDb2RlQXQoYil9LApkZDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC51bihiLGEsMCl9LApoOmZ1
+bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJzdHJpbmciKXRocm93IEguYihQLkwzKGIsbnVsbCxudWxs
+KSkKcmV0dXJuIGErYn0sClRjOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yi5sZW5ndGgscz1hLmxlbmd0aApp
+Zih0PnMpcmV0dXJuITEKcmV0dXJuIGI9PT10aGlzLkcoYSxzLXQpfSwKaTc6ZnVuY3Rpb24oYSxiLGMs
+ZCl7dmFyIHQscwpjPVAuakIoYixjLGEubGVuZ3RoKQp0PWEuc3Vic3RyaW5nKDAsYikKcz1hLnN1YnN0
+cmluZyhjKQpyZXR1cm4gdCtkK3N9LApRaTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYoIUgub2soYykp
+SC52aChILnRMKGMpKQppZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVybiBjLkooKQppZihjPDB8fGM+
+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYywwLGEubGVuZ3RoLG51bGwsbnVsbCkpCnQ9YytiLmxlbmd0
+aAppZih0PmEubGVuZ3RoKXJldHVybiExCnJldHVybiBiPT09YS5zdWJzdHJpbmcoYyx0KX0sCm46ZnVu
+Y3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5RaShhLGIsMCl9LApOajpmdW5jdGlvbihhLGIsYyl7aWYoIUgu
+b2soYikpSC52aChILnRMKGIpKQppZihjPT1udWxsKWM9YS5sZW5ndGgKaWYodHlwZW9mIGIhPT0ibnVt
+YmVyIilyZXR1cm4gYi5KKCkKaWYoYjwwKXRocm93IEguYihQLngoYixudWxsKSkKaWYoYj5jKXRocm93
+IEguYihQLngoYixudWxsKSkKaWYoYz5hLmxlbmd0aCl0aHJvdyBILmIoUC54KGMsbnVsbCkpCnJldHVy
+biBhLnN1YnN0cmluZyhiLGMpfSwKRzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLk5qKGEsYixudWxs
+KX0sCmhjOmZ1bmN0aW9uKGEpe3JldHVybiBhLnRvTG93ZXJDYXNlKCl9LApiUzpmdW5jdGlvbihhKXt2
+YXIgdCxzLHIscT1hLnRyaW0oKSxwPXEubGVuZ3RoCmlmKHA9PT0wKXJldHVybiBxCmlmKHRoaXMuVyhx
+LDApPT09MTMzKXt0PUoubW0ocSwxKQppZih0PT09cClyZXR1cm4iIn1lbHNlIHQ9MApzPXAtMQpyPXRo
+aXMubShxLHMpPT09MTMzP0ouYzEocSxzKTpwCmlmKHQ9PT0wJiZyPT09cClyZXR1cm4gcQpyZXR1cm4g
+cS5zdWJzdHJpbmcodCxyKX0sCkl4OmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZigwPj1iKXJldHVybiIi
+CmlmKGI9PT0xfHxhLmxlbmd0aD09PTApcmV0dXJuIGEKaWYoYiE9PWI+Pj4wKXRocm93IEguYihDLkVx
+KQpmb3IodD1hLHM9IiI7ITA7KXtpZigoYiYxKT09PTEpcz10K3MKYj1iPj4+MQppZihiPT09MClicmVh
+awp0Kz10fXJldHVybiBzfSwKWFU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKGM8MHx8Yz5hLmxlbmd0
+aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1hLmluZGV4T2YoYixjKQpy
+ZXR1cm4gdH0sCk9ZOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuWFUoYSxiLDApfSwKUGs6ZnVuY3Rp
+b24oYSxiLGMpe3ZhciB0LHMKaWYoYz09bnVsbCljPWEubGVuZ3RoCmVsc2UgaWYoYzwwfHxjPmEubGVu
+Z3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWIubGVuZ3RoCnM9YS5s
+ZW5ndGgKaWYoYyt0PnMpYz1zLXQKcmV0dXJuIGEubGFzdEluZGV4T2YoYixjKX0sCmNuOmZ1bmN0aW9u
+KGEsYil7cmV0dXJuIHRoaXMuUGsoYSxiLG51bGwpfSwKSXM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PWEu
+bGVuZ3RoCmlmKGM+dCl0aHJvdyBILmIoUC5URShjLDAsdCxudWxsLG51bGwpKQpyZXR1cm4gSC5tMihh
+LGIsYyl9LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLklzKGEsYiwwKX0sCnc6ZnVuY3Rpb24o
+YSl7cmV0dXJuIGF9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEubGVuZ3RoLHM9MCxy
+PTA7cjx0Oysrcil7cz01MzY4NzA5MTEmcythLmNoYXJDb2RlQXQocikKcz01MzY4NzA5MTEmcysoKDUy
+NDI4NyZzKTw8MTApCnNePXM+PjZ9cz01MzY4NzA5MTEmcysoKDY3MTA4ODYzJnMpPDwzKQpzXj1zPj4x
+MQpyZXR1cm4gNTM2ODcwOTExJnMrKCgxNjM4MyZzKTw8MTUpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
+IGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKaWYoYj49YS5sZW5ndGh8fCExKXRocm93
+IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKJGl2WDoxLAokaXFVOjF9CkgucWoucHJvdG90eXBl
+PXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7cmV0
+dXJuIEMueEIubSh0aGlzLmEsSC5TYyhiKSl9fQpILmJRLnByb3RvdHlwZT17fQpILmFMLnByb3RvdHlw
+ZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzCnJldHVybiBuZXcgSC5hNyh0LHQuZ0EodCksSC5M
+aCh0KS5DKCJhNzxhTC5FPiIpKX0sCkg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscT10aGlzLHA9cS5n
+QShxKQppZihiLmxlbmd0aCE9PTApe2lmKHA9PT0wKXJldHVybiIiCnQ9SC5kKHEuRSgwLDApKQppZihw
+IT09cS5nQShxKSl0aHJvdyBILmIoUC5hNChxKSkKZm9yKHM9dCxyPTE7cjxwOysrcil7cz1zK2IrSC5k
+KHEuRSgwLHIpKQppZihwIT09cS5nQShxKSl0aHJvdyBILmIoUC5hNChxKSl9cmV0dXJuIHMuY2hhckNv
+ZGVBdCgwKT09MD9zOnN9ZWxzZXtmb3Iocj0wLHM9IiI7cjxwOysrcil7cys9SC5kKHEuRSgwLHIpKQpp
+ZihwIT09cS5nQShxKSl0aHJvdyBILmIoUC5hNChxKSl9cmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9z
+OnN9fSwKZXY6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5HRygwLEguTGgodGhpcykuQygiYTIoYUwu
+RSkiKS5iKGIpKX19CkgubkgucHJvdG90eXBlPXsKZ1VEOmZ1bmN0aW9uKCl7dmFyIHQ9Si5IbSh0aGlz
+LmEpLHM9dGhpcy5jCmlmKHM9PW51bGx8fHM+dClyZXR1cm4gdApyZXR1cm4gc30sCmdBczpmdW5jdGlv
+bigpe3ZhciB0PUouSG0odGhpcy5hKSxzPXRoaXMuYgppZihzPnQpcmV0dXJuIHQKcmV0dXJuIHN9LApn
+QTpmdW5jdGlvbihhKXt2YXIgdCxzPUouSG0odGhpcy5hKSxyPXRoaXMuYgppZihyPj1zKXJldHVybiAw
+CnQ9dGhpcy5jCmlmKHQ9PW51bGx8fHQ+PXMpcmV0dXJuIHMtcgppZih0eXBlb2YgdCE9PSJudW1iZXIi
+KXJldHVybiB0LkhOKCkKcmV0dXJuIHQtcn0sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMscj1z
+LmdBcygpK2IKaWYoYj49MCl7dD1zLmdVRCgpCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIEgu
+cFkodCkKdD1yPj10fWVsc2UgdD0hMAppZih0KXRocm93IEguYihQLkNmKGIscywiaW5kZXgiLG51bGws
+bnVsbCkpCnJldHVybiBKLkdBKHMuYSxyKX19CkguYTcucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXty
+ZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcyxyPXMuYSxxPUouVTYocikscD1x
+LmdBKHIpCmlmKHMuYiE9PXApdGhyb3cgSC5iKFAuYTQocikpCnQ9cy5jCmlmKHQ+PXApe3Muc0kobnVs
+bCkKcmV0dXJuITF9cy5zSShxLkUocix0KSk7KytzLmMKcmV0dXJuITB9LApzSTpmdW5jdGlvbihhKXt0
+aGlzLmQ9dGhpcy4kdGkuZC5iKGEpfSwKJGlBbjoxfQpILkE4LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9u
+KGEpe3JldHVybiBKLkhtKHRoaXMuYSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYi4kMShK
+LkdBKHRoaXMuYSxiKSl9fQpILlU1LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3
+IEguU08oSi5JVCh0aGlzLmEpLHRoaXMuYix0aGlzLiR0aS5DKCJTTzwxPiIpKX19CkguU08ucHJvdG90
+eXBlPXsKRjpmdW5jdGlvbigpe3ZhciB0LHMKZm9yKHQ9dGhpcy5hLHM9dGhpcy5iO3QuRigpOylpZihI
+Lm9UKHMuJDEodC5nbCgpKSkpcmV0dXJuITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0
+aGlzLmEuZ2woKX19CkguU1UucHJvdG90eXBlPXt9CkguUmUucHJvdG90eXBlPXsKWTpmdW5jdGlvbihh
+LGIsYyl7SC5MaCh0aGlzKS5DKCJSZS5FIikuYihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlm
+eSBhbiB1bm1vZGlmaWFibGUgbGlzdCIpKX19CkguWEMucHJvdG90eXBlPXt9Ckgud3YucHJvdG90eXBl
+PXsKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuX2hhc2hDb2RlCmlmKHQhPW51bGwpcmV0dXJuIHQK
+dD01MzY4NzA5MTEmNjY0NTk3KkouaGYodGhpcy5hKQp0aGlzLl9oYXNoQ29kZT10CnJldHVybiB0fSwK
+dzpmdW5jdGlvbihhKXtyZXR1cm4nU3ltYm9sKCInK0guZCh0aGlzLmEpKyciKSd9LApETjpmdW5jdGlv
+bihhLGIpe2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBILnd2JiZ0aGlzLmE9
+PWIuYX0sCiRpR0Q6MX0KSC5QRC5wcm90b3R5cGU9e30KSC5XVS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9u
+KGEpe3JldHVybiBQLm5PKHRoaXMpfSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0
+LmQuYihiKQp0LmNoWzFdLmIoYykKcmV0dXJuIEguZGMoKX0sCiRpWjA6MX0KSC5MUC5wcm90b3R5cGU9
+ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKeDQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGEh
+PSJzdHJpbmciKXJldHVybiExCmlmKCJfX3Byb3RvX18iPT09YSlyZXR1cm4hMQpyZXR1cm4gdGhpcy5i
+Lmhhc093blByb3BlcnR5KGEpfSwKcTpmdW5jdGlvbihhLGIpe2lmKCF0aGlzLng0KGIpKXJldHVybiBu
+dWxsCnJldHVybiB0aGlzLnFQKGIpfSwKcVA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYltILnkoYSld
+fSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9SC5MaCh0aGlzKQpwLkMoIn4oMSwyKSIpLmIo
+YikKdD10aGlzLmMKZm9yKHM9dC5sZW5ndGgscD1wLmNoWzFdLHI9MDtyPHM7KytyKXtxPXRbcl0KYi4k
+MihxLHAuYih0aGlzLnFQKHEpKSl9fX0KSC5MSS5wcm90b3R5cGU9ewpnV2E6ZnVuY3Rpb24oKXt2YXIg
+dD10aGlzLmEKcmV0dXJuIHR9LApnbmQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPXRoaXMKaWYocC5j
+PT09MSlyZXR1cm4gQy5oVQp0PXAuZApzPXQubGVuZ3RoLXAuZS5sZW5ndGgtcC5mCmlmKHM9PT0wKXJl
+dHVybiBDLmhVCnI9W10KZm9yKHE9MDtxPHM7KytxKXtpZihxPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0
+LHEpCnIucHVzaCh0W3FdKX1yZXR1cm4gSi56QyhyKX0sCmdWbTpmdW5jdGlvbigpe3ZhciB0LHMscixx
+LHAsbyxuLG0sbD10aGlzCmlmKGwuYyE9PTApcmV0dXJuIEMuQ00KdD1sLmUKcz10Lmxlbmd0aApyPWwu
+ZApxPXIubGVuZ3RoLXMtbC5mCmlmKHM9PT0wKXJldHVybiBDLkNNCnA9bmV3IEguTjUodS5lbykKZm9y
+KG89MDtvPHM7KytvKXtpZihvPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LG8pCm49dFtvXQptPXErbwpp
+ZihtPDB8fG0+PXIubGVuZ3RoKXJldHVybiBILk9IKHIsbSkKcC5ZKDAsbmV3IEgud3YobiksclttXSl9
+cmV0dXJuIG5ldyBILlBEKHAsdS5nRil9LAokaXZROjF9CkguQ2oucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
+b24oYSxiKXt2YXIgdApILnkoYSkKdD10aGlzLmEKdC5iPXQuYisiJCIrSC5kKGEpCkMuTm0uaSh0aGlz
+LmIsYSkKQy5ObS5pKHRoaXMuYyxiKTsrK3QuYX0sCiRTOjEyfQpILmY5LnByb3RvdHlwZT17CnFTOmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9bmV3IFJlZ0V4cChyLmEpLmV4ZWMoYSkKaWYocT09bnVs
+bClyZXR1cm4gbnVsbAp0PU9iamVjdC5jcmVhdGUobnVsbCkKcz1yLmIKaWYocyE9PS0xKXQuYXJndW1l
+bnRzPXFbcysxXQpzPXIuYwppZihzIT09LTEpdC5hcmd1bWVudHNFeHByPXFbcysxXQpzPXIuZAppZihz
+IT09LTEpdC5leHByPXFbcysxXQpzPXIuZQppZihzIT09LTEpdC5tZXRob2Q9cVtzKzFdCnM9ci5mCmlm
+KHMhPT0tMSl0LnJlY2VpdmVyPXFbcysxXQpyZXR1cm4gdH19CkguVzAucHJvdG90eXBlPXsKdzpmdW5j
+dGlvbihhKXt2YXIgdD10aGlzLmIKaWYodD09bnVsbClyZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIr
+SC5kKHRoaXMuYSkKcmV0dXJuIk5vU3VjaE1ldGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIit0
+KyInIG9uIG51bGwifX0KSC5hei5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxy
+PSJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5vdCBmb3VuZDogJyIscT1zLmIKaWYocT09bnVsbCly
+ZXR1cm4iTm9TdWNoTWV0aG9kRXJyb3I6ICIrSC5kKHMuYSkKdD1zLmMKaWYodD09bnVsbClyZXR1cm4g
+citxKyInICgiK0guZChzLmEpKyIpIgpyZXR1cm4gcitxKyInIG9uICciK3QrIicgKCIrSC5kKHMuYSkr
+IikifX0KSC52Vi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5s
+ZW5ndGg9PT0wPyJFcnJvciI6IkVycm9yOiAiK3R9fQpILmJxLnByb3RvdHlwZT17fQpILkFtLnByb3Rv
+dHlwZT17CiQxOmZ1bmN0aW9uKGEpe2lmKHUuYlUuYyhhKSlpZihhLiR0aHJvd25Kc0Vycm9yPT1udWxs
+KWEuJHRocm93bkpzRXJyb3I9dGhpcy5hCnJldHVybiBhfSwKJFM6NH0KSC5YTy5wcm90b3R5cGU9ewp3
+OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5iCmlmKHMhPW51bGwpcmV0dXJuIHMKcz10aGlzLmEKdD1z
+IT09bnVsbCYmdHlwZW9mIHM9PT0ib2JqZWN0Ij9zLnN0YWNrOm51bGwKcmV0dXJuIHRoaXMuYj10PT1u
+dWxsPyIiOnR9LAokaUd6OjF9CkguVHAucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlz
+LmNvbnN0cnVjdG9yLHM9dD09bnVsbD9udWxsOnQubmFtZQpyZXR1cm4iQ2xvc3VyZSAnIitILk5RKHM9
+PW51bGw/InVua25vd24iOnMpKyInIn0sCiRpRUg6MSwKZ1FsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXN9
+LAokQzoiJDEiLAokUjoxLAokRDpudWxsfQpILmxjLnByb3RvdHlwZT17fQpILnp4LnByb3RvdHlwZT17
+Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy4kc3RhdGljX25hbWUKaWYodD09bnVsbClyZXR1cm4iQ2xv
+c3VyZSBvZiB1bmtub3duIHN0YXRpYyBtZXRob2QiCnJldHVybiJDbG9zdXJlICciK0guTlEodCkrIici
+fX0KSC5yVC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMKaWYoYj09bnVsbCly
+ZXR1cm4hMQppZih0PT09YilyZXR1cm4hMAppZighKGIgaW5zdGFuY2VvZiBILnJUKSlyZXR1cm4hMQpy
+ZXR1cm4gdC5hPT09Yi5hJiZ0LmI9PT1iLmImJnQuYz09PWIuY30sCmdpTzpmdW5jdGlvbihhKXt2YXIg
+dCxzPXRoaXMuYwppZihzPT1udWxsKXQ9SC5lUSh0aGlzLmEpCmVsc2UgdD10eXBlb2YgcyE9PSJvYmpl
+Y3QiP0ouaGYocyk6SC5lUShzKQpyZXR1cm4odF5ILmVRKHRoaXMuYikpPj4+MH0sCnc6ZnVuY3Rpb24o
+YSl7dmFyIHQ9dGhpcy5jCmlmKHQ9PW51bGwpdD10aGlzLmEKcmV0dXJuIkNsb3N1cmUgJyIrSC5kKHRo
+aXMuZCkrIicgb2YgIisoIkluc3RhbmNlIG9mICciK0guZChILk0odCkpKyInIil9fQpILkVxLnByb3Rv
+dHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlJ1bnRpbWVFcnJvcjogIitILmQodGhpcy5hKX19Ckgu
+a1kucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLnAo
+dGhpcy5hKX19CkguTjUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX0sCmdW
+OmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBILmk1KHRoaXMsSC5MaCh0aGlzKS5DKCJpNTwxPiIpKX0sCng0
+OmZ1bmN0aW9uKGEpe3ZhciB0LHMKaWYodHlwZW9mIGE9PSJzdHJpbmciKXt0PXRoaXMuYgppZih0PT1u
+dWxsKXJldHVybiExCnJldHVybiB0aGlzLlh1KHQsYSl9ZWxzZXtzPXRoaXMuQ1goYSkKcmV0dXJuIHN9
+fSwKQ1g6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5kCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRo
+aXMuRmgodGhpcy5CdCh0LEouaGYoYSkmMHgzZmZmZmZmKSxhKT49MH0sCnE6ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzLHIscSxwPXRoaXMsbz1udWxsCmlmKHR5cGVvZiBiPT0ic3RyaW5nIil7dD1wLmIKaWYodD09
+bnVsbClyZXR1cm4gbwpzPXAuajIodCxiKQpyPXM9PW51bGw/bzpzLmIKcmV0dXJuIHJ9ZWxzZSBpZih0
+eXBlb2YgYj09Im51bWJlciImJihiJjB4M2ZmZmZmZik9PT1iKXtxPXAuYwppZihxPT1udWxsKXJldHVy
+biBvCnM9cC5qMihxLGIpCnI9cz09bnVsbD9vOnMuYgpyZXR1cm4gcn1lbHNlIHJldHVybiBwLmFhKGIp
+fSwKYWE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPXRoaXMuZAppZihyPT1udWxsKXJldHVybiBudWxsCnQ9
+dGhpcy5CdChyLEouaGYoYSkmMHgzZmZmZmZmKQpzPXRoaXMuRmgodCxhKQppZihzPDApcmV0dXJuIG51
+bGwKcmV0dXJuIHRbc10uYn0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuPXRoaXMs
+bT1ILkxoKG4pCm0uZC5iKGIpCm0uY2hbMV0uYihjKQppZih0eXBlb2YgYj09InN0cmluZyIpe3Q9bi5i
+Cm4uRUgodD09bnVsbD9uLmI9bi56SygpOnQsYixjKX1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYm
+KGImMHgzZmZmZmZmKT09PWIpe3M9bi5jCm4uRUgocz09bnVsbD9uLmM9bi56SygpOnMsYixjKX1lbHNl
+e3I9bi5kCmlmKHI9PW51bGwpcj1uLmQ9bi56SygpCnE9Si5oZihiKSYweDNmZmZmZmYKcD1uLkJ0KHIs
+cSkKaWYocD09bnVsbCluLkVJKHIscSxbbi5IbihiLGMpXSkKZWxzZXtvPW4uRmgocCxiKQppZihvPj0w
+KXBbb10uYj1jCmVsc2UgcC5wdXNoKG4uSG4oYixjKSl9fX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
+LHI9dGhpcwpILkxoKHIpLkMoIn4oMSwyKSIpLmIoYikKdD1yLmUKcz1yLnIKZm9yKDt0IT1udWxsOyl7
+Yi4kMih0LmEsdC5iKQppZihzIT09ci5yKXRocm93IEguYihQLmE0KHIpKQp0PXQuY319LApFSDpmdW5j
+dGlvbihhLGIsYyl7dmFyIHQscz10aGlzLHI9SC5MaChzKQpyLmQuYihiKQpyLmNoWzFdLmIoYykKdD1z
+LmoyKGEsYikKaWYodD09bnVsbClzLkVJKGEsYixzLkhuKGIsYykpCmVsc2UgdC5iPWN9LAprczpmdW5j
+dGlvbigpe3RoaXMucj10aGlzLnIrMSY2NzEwODg2M30sCkhuOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10
+aGlzLHI9SC5MaChzKSxxPW5ldyBILmRiKHIuZC5iKGEpLHIuY2hbMV0uYihiKSkKaWYocy5lPT1udWxs
+KXMuZT1zLmY9cQplbHNle3Q9cy5mCnEuZD10CnMuZj10LmM9cX0rK3MuYQpzLmtzKCkKcmV0dXJuIHF9
+LApGaDpmdW5jdGlvbihhLGIpe3ZhciB0LHMKaWYoYT09bnVsbClyZXR1cm4tMQp0PWEubGVuZ3RoCmZv
+cihzPTA7czx0OysrcylpZihKLlJNKGFbc10uYSxiKSlyZXR1cm4gcwpyZXR1cm4tMX0sCnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIFAubk8odGhpcyl9LApqMjpmdW5jdGlvbihhLGIpe3JldHVybiBhW2JdfSwKQnQ6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYVtiXX0sCkVJOmZ1bmN0aW9uKGEsYixjKXthW2JdPWN9LApybjpm
+dW5jdGlvbihhLGIpe2RlbGV0ZSBhW2JdfSwKWHU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5qMihh
+LGIpIT1udWxsfSwKeks6ZnVuY3Rpb24oKXt2YXIgdD0iPG5vbi1pZGVudGlmaWVyLWtleT4iLHM9T2Jq
+ZWN0LmNyZWF0ZShudWxsKQp0aGlzLkVJKHMsdCxzKQp0aGlzLnJuKHMsdCkKcmV0dXJuIHN9LAokaUZv
+OjF9CkguZGIucHJvdG90eXBlPXt9CkguaTUucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuYS5hfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPW5ldyBILk42KHQsdC5yLHRo
+aXMuJHRpLkMoIk42PDE+IikpCnMuYz10LmUKcmV0dXJuIHN9fQpILk42LnByb3RvdHlwZT17CmdsOmZ1
+bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5hCmlmKHQu
+YiE9PXMucil0aHJvdyBILmIoUC5hNChzKSkKZWxzZXtzPXQuYwppZihzPT1udWxsKXt0LnNxWShudWxs
+KQpyZXR1cm4hMX1lbHNle3Quc3FZKHMuYSkKdC5jPXQuYy5jCnJldHVybiEwfX19LApzcVk6ZnVuY3Rp
+b24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KSC5kQy5wcm90b3R5cGU9ewokMTpm
+dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hKGEpfSwKJFM6NH0KSC53Ti5wcm90b3R5cGU9ewokMjpmdW5j
+dGlvbihhLGIpe3JldHVybiB0aGlzLmEoYSxiKX0sCiRTOjM4fQpILlZYLnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLmEoSC55KGEpKX0sCiRTOjQwfQpILlZSLnByb3RvdHlwZT17Cnc6
+ZnVuY3Rpb24oYSl7cmV0dXJuIlJlZ0V4cC8iK3RoaXMuYSsiLyIrdGhpcy5iLmZsYWdzfSwKZ0hjOmZ1
+bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYwppZihzIT1udWxsKXJldHVybiBzCnM9dC5iCnJldHVybiB0
+LmM9SC52NCh0LmEscy5tdWx0aWxpbmUsIXMuaWdub3JlQ2FzZSxzLnVuaWNvZGUscy5kb3RBbGwsITAp
+fSwKZGQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguS1codGhpcyxiLDApfSwKVVo6ZnVuY3Rpb24o
+YSxiKXt2YXIgdCxzPXRoaXMuZ0hjKCkKcy5sYXN0SW5kZXg9Ygp0PXMuZXhlYyhhKQppZih0PT1udWxs
+KXJldHVybiBudWxsCnJldHVybiBuZXcgSC5FSyh0KX0sCiRpdlg6MSwKJGl3TDoxfQpILkVLLnByb3Rv
+dHlwZT17CnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILlNjKGIpCnQ9dGhpcy5iCmlmKGI+PXQubGVuZ3Ro
+KXJldHVybiBILk9IKHQsYikKcmV0dXJuIHRbYl19LAokaU9kOjEsCiRpaWI6MX0KSC5LVy5wcm90b3R5
+cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19
+CkguUGIucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigp
+e3ZhciB0LHMscixxLHA9dGhpcyxvPXAuYgppZihvPT1udWxsKXJldHVybiExCnQ9cC5jCmlmKHQ8PW8u
+bGVuZ3RoKXtzPXAuYQpyPXMuVVoobyx0KQppZihyIT1udWxsKXtwLmQ9cgpvPXIuYgp0PW8uaW5kZXgK
+cT10K29bMF0ubGVuZ3RoCmlmKHQ9PT1xKXtpZihzLmIudW5pY29kZSl7bz1wLmMKdD1vKzEKcz1wLmIK
+aWYodDxzLmxlbmd0aCl7bz1KLnJZKHMpLm0ocyxvKQppZihvPj01NTI5NiYmbzw9NTYzMTkpe289Qy54
+Qi5tKHMsdCkKbz1vPj01NjMyMCYmbzw9NTczNDN9ZWxzZSBvPSExfWVsc2Ugbz0hMX1lbHNlIG89ITEK
+cT0obz9xKzE6cSkrMX1wLmM9cQpyZXR1cm4hMH19cC5iPXAuZD1udWxsCnJldHVybiExfSwKJGlBbjox
+fQpILnRRLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCmlmKGIhPT0wKUgudmgoUC54
+KGIsbnVsbCkpCnJldHVybiB0aGlzLmN9LAokaU9kOjF9CkgudW4ucHJvdG90eXBlPXsKZ2t6OmZ1bmN0
+aW9uKGEpe3JldHVybiBuZXcgSC5TZCh0aGlzLmEsdGhpcy5iLHRoaXMuYyl9fQpILlNkLnByb3RvdHlw
+ZT17CkY6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcyxxPXIuYyxwPXIuYixvPXAubGVuZ3RoLG49ci5h
+LG09bi5sZW5ndGgKaWYocStvPm0pe3IuZD1udWxsCnJldHVybiExfXQ9bi5pbmRleE9mKHAscSkKaWYo
+dDwwKXtyLmM9bSsxCnIuZD1udWxsCnJldHVybiExfXM9dCtvCnIuZD1uZXcgSC50USh0LHApCnIuYz1z
+PT09ci5jP3MrMTpzCnJldHVybiEwfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKJGlBbjox
+fQpILkVULnByb3RvdHlwZT17JGlFVDoxLCRpQVM6MX0KSC5iMC5wcm90b3R5cGU9ewpnQTpmdW5jdGlv
+bihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVhqOjF9CkguRGcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihh
+LGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIs
+Yyl7SC5JZyhjKQpILm9kKGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGljWDoxLAokaXpNOjF9CkguUGcu
+cHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7SC5TYyhjKQpILm9kKGIsYSxhLmxlbmd0aCkKYVti
+XT1jfSwKJGljWDoxLAokaXpNOjF9CkgueGoucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guU2Mo
+YikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5kRS5wcm90b3R5cGU9ewpxOmZ1bmN0
+aW9uKGEsYil7SC5TYyhiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILlpBLnByb3Rv
+dHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVti
+XX19Ckgud2YucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5n
+dGgpCnJldHVybiBhW2JdfX0KSC5QcS5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQpI
+Lm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILmVFLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9u
+KGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEubGVu
+Z3RoKQpyZXR1cm4gYVtiXX19CkguVjYucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
+bGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBh
+W2JdfSwKJGlWNjoxLAokaW42OjF9CkguUkcucHJvdG90eXBlPXt9CkguVlAucHJvdG90eXBlPXt9Ckgu
+V0IucHJvdG90eXBlPXt9CkguWkcucHJvdG90eXBlPXt9CkguSmMucHJvdG90eXBlPXsKQzpmdW5jdGlv
+bihhKXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSx0aGlzLGEpfSwKS3E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIEgudjUodi50eXBlVW5pdmVyc2UsdGhpcyxhKX19CkguRy5wcm90b3R5cGU9e30KSC51OS5wcm90
+b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9fQpILmh6LnByb3RvdHlwZT17fQpILmlN
+LnByb3RvdHlwZT17fQpQLnRoLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxz
+PXQuYQp0LmE9bnVsbApzLiQwKCl9LAokUzoxOH0KUC5oYS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
+KXt2YXIgdCxzCnRoaXMuYS5hPXUuTS5iKGEpCnQ9dGhpcy5iCnM9dGhpcy5jCnQuZmlyc3RDaGlsZD90
+LnJlbW92ZUNoaWxkKHMpOnQuYXBwZW5kQ2hpbGQocyl9LAokUzoyMX0KUC5Wcy5wcm90b3R5cGU9ewok
+MDpmdW5jdGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5GdC5wcm90b3R5
+cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYS4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6MH0KUC5XMy5w
+cm90b3R5cGU9ewpDWTpmdW5jdGlvbihhLGIpe2lmKHNlbGYuc2V0VGltZW91dCE9bnVsbClzZWxmLnNl
+dFRpbWVvdXQoSC50UihuZXcgUC55SCh0aGlzLGIpLDApLGEpCmVsc2UgdGhyb3cgSC5iKFAuTDQoImBz
+ZXRUaW1lb3V0KClgIG5vdCBmb3VuZC4iKSl9fQpQLnlILnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7
+dGhpcy5iLiQwKCl9LAokQzoiJDAiLAokUjowLAokUzoyfQpQLmloLnByb3RvdHlwZT17CmFNOmZ1bmN0
+aW9uKGEsYil7dmFyIHQscyxyPXRoaXMuJHRpCnIuQygiMS8iKS5iKGIpCnQ9IXRoaXMuYnx8ci5DKCJi
+ODwxPiIpLmMoYikKcz10aGlzLmEKaWYodClzLlhmKGIpCmVsc2Ugcy5YMihyLmQuYihiKSl9LAp3MDpm
+dW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZih0aGlzLmIpdC5aTChhLGIpCmVsc2UgdC5OayhhLGIp
+fX0KUC5XTS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLiQyKDAsYSl9LAok
+UzoyMH0KUC5TWC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYS4kMigxLG5ldyBILmJx
+KGEsdS5sLmIoYikpKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjMzfQpQLkdzLnByb3RvdHlwZT17CiQyOmZ1
+bmN0aW9uKGEsYil7dGhpcy5hKEguU2MoYSksYil9LAokUzoyM30KUC5QZi5wcm90b3R5cGU9ewp3MDpm
+dW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PW51bGwpYT1uZXcgUC5uKCkKdD10aGlzLmEKaWYodC5hIT09
+MCl0aHJvdyBILmIoUC5QVigiRnV0dXJlIGFscmVhZHkgY29tcGxldGVkIikpCnQuTmsoYSxiKX0sCnBt
+OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLncwKGEsbnVsbCl9fQpQLlpmLnByb3RvdHlwZT17CmFNOmZ1
+bmN0aW9uKGEsYil7dmFyIHQKdGhpcy4kdGkuQygiMS8iKS5iKGIpCnQ9dGhpcy5hCmlmKHQuYSE9PTAp
+dGhyb3cgSC5iKFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIpKQp0LlhmKGIpfX0KUC5GZS5w
+cm90b3R5cGU9ewpIUjpmdW5jdGlvbihhKXtpZigodGhpcy5jJjE1KSE9PTYpcmV0dXJuITAKcmV0dXJu
+IHRoaXMuYi5iLmJ2KHUuYWwuYih0aGlzLmQpLGEuYSx1LmNKLHUuSyl9LApLdzpmdW5jdGlvbihhKXt2
+YXIgdD10aGlzLmUscz11Lnoscj11LksscT10aGlzLiR0aS5DKCIyLyIpLHA9dGhpcy5iLmIKaWYodS5X
+LmModCkpcmV0dXJuIHEuYihwLnJwKHQsYS5hLGEuYixzLHIsdS5sKSkKZWxzZSByZXR1cm4gcS5iKHAu
+YnYodS55LmIodCksYS5hLHMscikpfX0KUC52cy5wcm90b3R5cGU9ewpTcTpmdW5jdGlvbihhLGIsYyl7
+dmFyIHQscyxyLHE9dGhpcy4kdGkKcS5LcShjKS5DKCIxLygyKSIpLmIoYSkKdD0kLlgzCmlmKHQhPT1D
+Lk5VKXtjLkMoIkA8MC8+IikuS3EocS5kKS5DKCIxKDIpIikuYihhKQppZihiIT1udWxsKWI9UC5WSChi
+LHQpfXM9bmV3IFAudnMoJC5YMyxjLkMoInZzPDA+IikpCnI9Yj09bnVsbD8xOjMKdGhpcy54ZihuZXcg
+UC5GZShzLHIsYSxiLHEuQygiQDwxPiIpLktxKGMpLkMoIkZlPDEsMj4iKSkpCnJldHVybiBzfSwKVzc6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5TcShhLG51bGwsYil9LApRZDpmdW5jdGlvbihhLGIsYyl7
+dmFyIHQscz10aGlzLiR0aQpzLktxKGMpLkMoIjEvKDIpIikuYihhKQp0PW5ldyBQLnZzKCQuWDMsYy5D
+KCJ2czwwPiIpKQp0aGlzLnhmKG5ldyBQLkZlKHQsKGI9PW51bGw/MTozKXwxNixhLGIscy5DKCJAPDE+
+IikuS3EoYykuQygiRmU8MSwyPiIpKSkKcmV0dXJuIHR9LApPQTpmdW5jdGlvbihhKXt2YXIgdCxzLHIK
+dS5iZi5iKG51bGwpCnQ9dGhpcy4kdGkKcz0kLlgzCnI9bmV3IFAudnMocyx0KQppZihzIT09Qy5OVSlh
+PVAuVkgoYSxzKQp0aGlzLnhmKG5ldyBQLkZlKHIsMixudWxsLGEsdC5DKCJAPDE+IikuS3EodC5kKS5D
+KCJGZTwxLDI+IikpKQpyZXR1cm4gcn0sCnhmOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxyPXMuYQpp
+ZihyPD0xKXthLmE9dS54LmIocy5jKQpzLmM9YX1lbHNle2lmKHI9PT0yKXt0PXUuXy5iKHMuYykKcj10
+LmEKaWYocjw0KXt0LnhmKGEpCnJldHVybn1zLmE9cgpzLmM9dC5jfVAuVGsobnVsbCxudWxsLHMuYix1
+Lk0uYihuZXcgUC5kYShzLGEpKSl9fSwKalE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvPXRoaXMs
+bj17fQpuLmE9YQppZihhPT1udWxsKXJldHVybgp0PW8uYQppZih0PD0xKXtzPXUueC5iKG8uYykKcj1v
+LmM9YQppZihzIT1udWxsKXtmb3IoO3E9ci5hLHEhPW51bGw7cj1xKTtyLmE9c319ZWxzZXtpZih0PT09
+Mil7cD11Ll8uYihvLmMpCnQ9cC5hCmlmKHQ8NCl7cC5qUShhKQpyZXR1cm59by5hPXQKby5jPXAuY31u
+LmE9by5OOChhKQpQLlRrKG51bGwsbnVsbCxvLmIsdS5NLmIobmV3IFAub1EobixvKSkpfX0sCmFoOmZ1
+bmN0aW9uKCl7dmFyIHQ9dS54LmIodGhpcy5jKQp0aGlzLmM9bnVsbApyZXR1cm4gdGhpcy5OOCh0KX0s
+Ck44OmZ1bmN0aW9uKGEpe3ZhciB0LHMscgpmb3IodD1hLHM9bnVsbDt0IT1udWxsO3M9dCx0PXIpe3I9
+dC5hCnQuYT1zfXJldHVybiBzfSwKSEg6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9cy4kdGkKci5D
+KCIxLyIpLmIoYSkKaWYoci5DKCJiODwxPiIpLmMoYSkpaWYoci5jKGEpKVAuQTkoYSxzKQplbHNlIFAu
+azMoYSxzKQplbHNle3Q9cy5haCgpCnIuZC5iKGEpCnMuYT00CnMuYz1hClAuSFoocyx0KX19LApYMjpm
+dW5jdGlvbihhKXt2YXIgdCxzPXRoaXMKcy4kdGkuZC5iKGEpCnQ9cy5haCgpCnMuYT00CnMuYz1hClAu
+SFoocyx0KX0sClpMOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzCnUubC5iKGIpCnQ9cy5haCgpCnMu
+YT04CnMuYz1uZXcgUC5DdyhhLGIpClAuSFoocyx0KX0sClhmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMs
+cz10LiR0aQpzLkMoIjEvIikuYihhKQppZihzLkMoImI4PDE+IikuYyhhKSl7dC5jVShhKQpyZXR1cm59
+dC5hPTEKUC5UayhudWxsLG51bGwsdC5iLHUuTS5iKG5ldyBQLnJIKHQsYSkpKX0sCmNVOmZ1bmN0aW9u
+KGEpe3ZhciB0PXRoaXMscz10LiR0aQpzLkMoImI4PDE+IikuYihhKQppZihzLmMoYSkpe2lmKGEuYT09
+PTgpe3QuYT0xClAuVGsobnVsbCxudWxsLHQuYix1Lk0uYihuZXcgUC5LRih0LGEpKSl9ZWxzZSBQLkE5
+KGEsdCkKcmV0dXJufVAuazMoYSx0KX0sCk5rOmZ1bmN0aW9uKGEsYil7dGhpcy5hPTEKUC5UayhudWxs
+LG51bGwsdGhpcy5iLHUuTS5iKG5ldyBQLlpMKHRoaXMsYSxiKSkpfSwKJGliODoxfQpQLmRhLnByb3Rv
+dHlwZT17CiQwOmZ1bmN0aW9uKCl7UC5IWih0aGlzLmEsdGhpcy5iKX0sCiRTOjB9ClAub1EucHJvdG90
+eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkhaKHRoaXMuYix0aGlzLmEuYSl9LAokUzowfQpQLnBWLnByb3Rv
+dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQp0LmE9MAp0LkhIKGEpfSwKJFM6MTh9ClAu
+VTcucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt1LmwuYihiKQp0aGlzLmEuWkwoYSxiKX0sCiQx
+OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLiQyKGEsbnVsbCl9LAokQzoiJDIiLAokRDpmdW5jdGlvbigp
+e3JldHVybltudWxsXX0sCiRTOjQyfQpQLnZyLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5h
+LlpMKHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KUC5ySC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3Zh
+ciB0PXRoaXMuYQp0LlgyKHQuJHRpLmQuYih0aGlzLmIpKX0sCiRTOjB9ClAuS0YucHJvdG90eXBlPXsK
+JDA6ZnVuY3Rpb24oKXtQLkE5KHRoaXMuYix0aGlzLmEpfSwKJFM6MH0KUC5aTC5wcm90b3R5cGU9ewok
+MDpmdW5jdGlvbigpe3RoaXMuYS5aTCh0aGlzLmIsdGhpcy5jKX0sCiRTOjB9ClAuUlQucHJvdG90eXBl
+PXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzLG09bnVsbAp0cnl7cj1uLmMKbT1y
+LmIuYi56eih1LmZPLmIoci5kKSx1LnopfWNhdGNoKHEpe3Q9SC5SdShxKQpzPUgudHMocSkKaWYobi5k
+KXtyPXUubi5iKG4uYS5hLmMpLmEKcD10CnA9cj09bnVsbD9wPT1udWxsOnI9PT1wCnI9cH1lbHNlIHI9
+ITEKcD1uLmIKaWYocilwLmI9dS5uLmIobi5hLmEuYykKZWxzZSBwLmI9bmV3IFAuQ3codCxzKQpwLmE9
+ITAKcmV0dXJufWlmKHUuYy5jKG0pKXtpZihtIGluc3RhbmNlb2YgUC52cyYmbS5hPj00KXtpZihtLmE9
+PT04KXtyPW4uYgpyLmI9dS5uLmIobS5jKQpyLmE9ITB9cmV0dXJufW89bi5hLmEKcj1uLmIKci5iPW0u
+VzcobmV3IFAualoobyksdS56KQpyLmE9ITF9fSwKJFM6Mn0KUC5qWi5wcm90b3R5cGU9ewokMTpmdW5j
+dGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKJFM6Mzd9ClAucnEucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24o
+KXt2YXIgdCxzLHIscSxwLG8sbixtPXRoaXMKdHJ5e3I9bS5iCnE9ci4kdGkKcD1xLmQKbz1wLmIobS5j
+KQptLmEuYj1yLmIuYi5idihxLkMoIjIvKDEpIikuYihyLmQpLG8scS5DKCIyLyIpLHApfWNhdGNoKG4p
+e3Q9SC5SdShuKQpzPUgudHMobikKcj1tLmEKci5iPW5ldyBQLkN3KHQscykKci5hPSEwfX0sCiRTOjJ9
+ClAuUlcucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcwp0
+cnl7dD11Lm4uYihsLmEuYS5jKQpxPWwuYwppZihILm9UKHEuSFIodCkpJiZxLmUhPW51bGwpe3A9bC5i
+CnAuYj1xLkt3KHQpCnAuYT0hMX19Y2F0Y2gobyl7cz1ILlJ1KG8pCnI9SC50cyhvKQpxPXUubi5iKGwu
+YS5hLmMpCnA9cS5hCm49cwptPWwuYgppZihwPT1udWxsP249PW51bGw6cD09PW4pbS5iPXEKZWxzZSBt
+LmI9bmV3IFAuQ3cocyxyKQptLmE9ITB9fSwKJFM6Mn0KUC5PTS5wcm90b3R5cGU9e30KUC5xaC5wcm90
+b3R5cGU9ewpnQTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcyxxPXt9LHA9bmV3IFAudnMoJC5YMyx1
+LmZKKQpxLmE9MAp0PUguTGgocikKcz10LkMoIn4oMSkiKS5iKG5ldyBQLkI1KHEscikpCnUuTS5iKG5l
+dyBQLlBJKHEscCkpClcuSkUoci5hLHIuYixzLCExLHQuZCkKcmV0dXJuIHB9fQpQLkI1LnByb3RvdHlw
+ZT17CiQxOmZ1bmN0aW9uKGEpe0guTGgodGhpcy5iKS5kLmIoYSk7Kyt0aGlzLmEuYX0sCiRTOmZ1bmN0
+aW9uKCl7cmV0dXJuIEguTGgodGhpcy5iKS5DKCJjOCgxKSIpfX0KUC5QSS5wcm90b3R5cGU9ewokMDpm
+dW5jdGlvbigpe3RoaXMuYi5ISCh0aGlzLmEuYSl9LAokUzowfQpQLk1PLnByb3RvdHlwZT17fQpQLmtU
+LnByb3RvdHlwZT17fQpQLnhJLnByb3RvdHlwZT17fQpQLkN3LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24o
+YSl7cmV0dXJuIEguZCh0aGlzLmEpfSwKJGlYUzoxfQpQLm0wLnByb3RvdHlwZT17JGlKQjoxfQpQLnBL
+LnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLmEscj1zLmEKcz1yPT1udWxsP3Mu
+YT1uZXcgUC5uKCk6cgpyPXRoaXMuYgppZihyPT1udWxsKXRocm93IEguYihzKQp0PUguYihzKQp0LnN0
+YWNrPXIudygwKQp0aHJvdyB0fSwKJFM6MH0KUC5KaS5wcm90b3R5cGU9ewpiSDpmdW5jdGlvbihhKXt2
+YXIgdCxzLHIscT1udWxsCnUuTS5iKGEpCnRyeXtpZihDLk5VPT09JC5YMyl7YS4kMCgpCnJldHVybn1Q
+LlQ4KHEscSx0aGlzLGEsdS5IKX1jYXRjaChyKXt0PUguUnUocikKcz1ILnRzKHIpClAuTDIocSxxLHRo
+aXMsdCx1LmwuYihzKSl9fSwKRGw6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPW51bGwKYy5DKCJ+
+KDApIikuYihhKQpjLmIoYikKdHJ5e2lmKEMuTlU9PT0kLlgzKXthLiQxKGIpCnJldHVybn1QLnl2KHEs
+cSx0aGlzLGEsYix1LkgsYyl9Y2F0Y2gocil7dD1ILlJ1KHIpCnM9SC50cyhyKQpQLkwyKHEscSx0aGlz
+LHQsdS5sLmIocykpfX0sClJUOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLmhqKHRoaXMsYi5DKCIw
+KCkiKS5iKGEpLGIpfSwKR1k6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlZwKHRoaXMsdS5NLmIoYSkp
+fSwKUHk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuT1IodGhpcyxiLkMoIn4oMCkiKS5iKGEpLGIp
+fSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiBudWxsfSwKeno6ZnVuY3Rpb24oYSxiKXtiLkMoIjAoKSIp
+LmIoYSkKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDAoKQpyZXR1cm4gUC5UOChudWxsLG51bGwsdGhp
+cyxhLGIpfSwKYnY6ZnVuY3Rpb24oYSxiLGMsZCl7Yy5DKCJAPDA+IikuS3EoZCkuQygiMSgyKSIpLmIo
+YSkKZC5iKGIpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQxKGIpCnJldHVybiBQLnl2KG51bGwsbnVs
+bCx0aGlzLGEsYixjLGQpfSwKcnA6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe2QuQygiQDwwPiIpLktxKGUp
+LktxKGYpLkMoIjEoMiwzKSIpLmIoYSkKZS5iKGIpCmYuYihjKQppZigkLlgzPT09Qy5OVSlyZXR1cm4g
+YS4kMihiLGMpCnJldHVybiBQLlF4KG51bGwsbnVsbCx0aGlzLGEsYixjLGQsZSxmKX0sCkxqOmZ1bmN0
+aW9uKGEsYixjLGQpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5LcShkKS5DKCIxKDIsMykiKS5iKGEp
+fX0KUC5oai5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuenoodGhpcy5iLHRo
+aXMuYyl9LAokUzpmdW5jdGlvbigpe3JldHVybiB0aGlzLmMuQygiMCgpIil9fQpQLlZwLnByb3RvdHlw
+ZT17CiQwOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5iSCh0aGlzLmIpfSwKJFM6Mn0KUC5PUi5wcm90
+b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmMKcmV0dXJuIHRoaXMuYS5EbCh0aGlzLmIs
+dC5iKGEpLHQpfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jLkMoIn4oMCkiKX19ClAuYjYucHJv
+dG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1uZXcgUC5sbSh0LHQucixILkxoKHQp
+LkMoImxtPDE+IikpCnMuYz10LmUKcmV0dXJuIHN9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5h
+fSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3By
+b3RvX18iKXt0PXRoaXMuYgppZih0PT1udWxsKXJldHVybiExCnJldHVybiB1LkouYih0W2JdKSE9bnVs
+bH1lbHNle3M9dGhpcy5QUihiKQpyZXR1cm4gc319LApQUjpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmQK
+aWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhpcy5ERih0W3RoaXMuTihhKV0sYSk+PTB9LAppOmZ1
+bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMKSC5MaChyKS5kLmIoYikKaWYodHlwZW9mIGI9PSJzdHJp
+bmciJiZiIT09Il9fcHJvdG9fXyIpe3Q9ci5iCnJldHVybiByLmJRKHQ9PW51bGw/ci5iPVAuVDIoKTp0
+LGIpfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpe3M9ci5jCnJl
+dHVybiByLmJRKHM9PW51bGw/ci5jPVAuVDIoKTpzLGIpfWVsc2UgcmV0dXJuIHIuQjcoYil9LApCNzpm
+dW5jdGlvbihhKXt2YXIgdCxzLHIscT10aGlzCkguTGgocSkuZC5iKGEpCnQ9cS5kCmlmKHQ9PW51bGwp
+dD1xLmQ9UC5UMigpCnM9cS5OKGEpCnI9dFtzXQppZihyPT1udWxsKXRbc109W3EueW8oYSldCmVsc2V7
+aWYocS5ERihyLGEpPj0wKXJldHVybiExCnIucHVzaChxLnlvKGEpKX1yZXR1cm4hMH0sClI6ZnVuY3Rp
+b24oYSxiKXt2YXIgdD10aGlzCmlmKHR5cGVvZiBiPT0ic3RyaW5nIiYmYiE9PSJfX3Byb3RvX18iKXJl
+dHVybiB0LkwodC5iLGIpCmVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09
+PWIpcmV0dXJuIHQuTCh0LmMsYikKZWxzZSByZXR1cm4gdC5xZyhiKX0sCnFnOmZ1bmN0aW9uKGEpe3Zh
+ciB0LHMscixxLHA9dGhpcyxvPXAuZAppZihvPT1udWxsKXJldHVybiExCnQ9cC5OKGEpCnM9b1t0XQpy
+PXAuREYocyxhKQppZihyPDApcmV0dXJuITEKcT1zLnNwbGljZShyLDEpWzBdCmlmKDA9PT1zLmxlbmd0
+aClkZWxldGUgb1t0XQpwLkdTKHEpCnJldHVybiEwfSwKYlE6ZnVuY3Rpb24oYSxiKXtILkxoKHRoaXMp
+LmQuYihiKQppZih1LkouYihhW2JdKSE9bnVsbClyZXR1cm4hMQphW2JdPXRoaXMueW8oYikKcmV0dXJu
+ITB9LApMOmZ1bmN0aW9uKGEsYil7dmFyIHQKaWYoYT09bnVsbClyZXR1cm4hMQp0PXUuSi5iKGFbYl0p
+CmlmKHQ9PW51bGwpcmV0dXJuITEKdGhpcy5HUyh0KQpkZWxldGUgYVtiXQpyZXR1cm4hMH0sClM6ZnVu
+Y3Rpb24oKXt0aGlzLnI9MTA3Mzc0MTgyMyZ0aGlzLnIrMX0sCnlvOmZ1bmN0aW9uKGEpe3ZhciB0LHM9
+dGhpcyxyPW5ldyBQLmJuKEguTGgocykuZC5iKGEpKQppZihzLmU9PW51bGwpcy5lPXMuZj1yCmVsc2V7
+dD1zLmYKci5jPXQKcy5mPXQuYj1yfSsrcy5hCnMuUygpCnJldHVybiByfSwKR1M6ZnVuY3Rpb24oYSl7
+dmFyIHQ9dGhpcyxzPWEuYyxyPWEuYgppZihzPT1udWxsKXQuZT1yCmVsc2Ugcy5iPXIKaWYocj09bnVs
+bCl0LmY9cwplbHNlIHIuYz1zOy0tdC5hCnQuUygpfSwKTjpmdW5jdGlvbihhKXtyZXR1cm4gSi5oZihh
+KSYxMDczNzQxODIzfSwKREY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCmlmKGE9PW51bGwpcmV0dXJuLTEK
+dD1hLmxlbmd0aApmb3Iocz0wO3M8dDsrK3MpaWYoSi5STShhW3NdLmEsYikpcmV0dXJuIHMKcmV0dXJu
+LTF9fQpQLmJuLnByb3RvdHlwZT17fQpQLmxtLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJu
+IHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5hCmlmKHQuYiE9PXMucil0aHJvdyBI
+LmIoUC5hNChzKSkKZWxzZXtzPXQuYwppZihzPT1udWxsKXt0LnNqKG51bGwpCnJldHVybiExfWVsc2V7
+dC5zaih0LiR0aS5kLmIocy5hKSkKdC5jPXQuYy5iCnJldHVybiEwfX19LApzajpmdW5jdGlvbihhKXt0
+aGlzLmQ9dGhpcy4kdGkuZC5iKGEpfSwKJGlBbjoxfQpQLm1XLnByb3RvdHlwZT17fQpQLkxVLnByb3Rv
+dHlwZT17JGljWDoxLCRpek06MX0KUC5sRC5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJu
+IG5ldyBILmE3KGEsdGhpcy5nQShhKSxILnpLKGEpLkMoImE3PGxELkU+IikpfSwKRTpmdW5jdGlvbihh
+LGIpe3JldHVybiB0aGlzLnEoYSxiKX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkgueksoYSkuQygi
+fihsRC5FKSIpLmIoYikKdD10aGlzLmdBKGEpCmZvcihzPTA7czx0Oysrcyl7Yi4kMSh0aGlzLnEoYSxz
+KSkKaWYodCE9PXRoaXMuZ0EoYSkpdGhyb3cgSC5iKFAuYTQoYSkpfX0sCkUyOmZ1bmN0aW9uKGEsYixj
+KXt2YXIgdD1ILnpLKGEpCnJldHVybiBuZXcgSC5BOChhLHQuS3EoYykuQygiMShsRC5FKSIpLmIoYiks
+dC5DKCJAPGxELkU+IikuS3EoYykuQygiQTg8MSwyPiIpKX0sCmR1OmZ1bmN0aW9uKGEsYixjLGQpe3Zh
+ciB0CkgueksoYSkuQygibEQuRSIpLmIoZCkKUC5qQihiLGMsdGhpcy5nQShhKSkKZm9yKHQ9Yjt0PGM7
+Kyt0KXRoaXMuWShhLHQsZCl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJdIil9fQpQ
+LmlsLnByb3RvdHlwZT17fQpQLnJhLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10
+aGlzLmEKaWYoIXMuYSl0aGlzLmIuYSs9IiwgIgpzLmE9ITEKcz10aGlzLmIKdD1zLmErPUguZChhKQpz
+LmE9dCsiOiAiCnMuYSs9SC5kKGIpfSwKJFM6MX0KUC5Zay5wcm90b3R5cGU9ewpLOmZ1bmN0aW9uKGEs
+Yil7dmFyIHQscwpILkxoKHRoaXMpLkMoIn4oWWsuSyxZay5WKSIpLmIoYikKZm9yKHQ9Si5JVCh0aGlz
+LmdWKCkpO3QuRigpOyl7cz10LmdsKCkKYi4kMihzLHRoaXMucSgwLHMpKX19LApnQTpmdW5jdGlvbihh
+KXtyZXR1cm4gSi5IbSh0aGlzLmdWKCkpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0s
+CiRpWjA6MX0KUC5LUC5wcm90b3R5cGU9ewpZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMp
+CnQuZC5iKGIpCnQuY2hbMV0uYihjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSB1bm1vZGlm
+aWFibGUgbWFwIikpfX0KUC5Qbi5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMu
+YS5xKDAsYil9LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMpCnRoaXMuYS5ZKDAsdC5k
+LmIoYiksdC5jaFsxXS5iKGMpKX0sCks6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLEguTGgodGhpcyku
+QygifigxLDIpIikuYihiKSl9LApnQTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuZ0Eo
+dCl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBKLmoodGhpcy5hKX0sCiRpWjA6MX0KUC5Hai5wcm90b3R5
+cGU9e30KUC5sZi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKHRoaXMsInsiLCJ9
+Iil9fQpQLlZqLnByb3RvdHlwZT17JGljWDoxLCRpeHU6MX0KUC5Ydi5wcm90b3R5cGU9ewpGVjpmdW5j
+dGlvbihhLGIpe3ZhciB0CmZvcih0PUouSVQoSC5MaCh0aGlzKS5DKCJjWDwxPiIpLmIoYikpO3QuRigp
+Oyl0aGlzLmkoMCx0LmdsKCkpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gUC5XRSh0aGlzLCJ7IiwifSIp
+fSwKSDpmdW5jdGlvbihhLGIpe3ZhciB0LHM9UC5yaih0aGlzLHRoaXMucixILkxoKHRoaXMpLmQpCmlm
+KCFzLkYoKSlyZXR1cm4iIgppZihiPT09IiIpe3Q9IiIKZG8gdCs9SC5kKHMuZCkKd2hpbGUocy5GKCkp
+fWVsc2V7dD1ILmQocy5kKQpmb3IoO3MuRigpOyl0PXQrYitILmQocy5kKX1yZXR1cm4gdC5jaGFyQ29k
+ZUF0KDApPT0wP3Q6dH0sCiRpY1g6MSwKJGl4dToxfQpQLm5ZLnByb3RvdHlwZT17fQpQLldZLnByb3Rv
+dHlwZT17fQpQLlJVLnByb3RvdHlwZT17fQpQLnV3LnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzPXRoaXMuYgppZihzPT1udWxsKXJldHVybiB0aGlzLmMucSgwLGIpCmVsc2UgaWYodHlwZW9m
+IGIhPSJzdHJpbmciKXJldHVybiBudWxsCmVsc2V7dD1zW2JdCnJldHVybiB0eXBlb2YgdD09InVuZGVm
+aW5lZCI/dGhpcy5mYihiKTp0fX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmI9PW51bGw/dGhp
+cy5jLmE6dGhpcy5DZigpLmxlbmd0aH0sCmdWOmZ1bmN0aW9uKCl7aWYodGhpcy5iPT1udWxsKXt2YXIg
+dD10aGlzLmMKcmV0dXJuIG5ldyBILmk1KHQsSC5MaCh0KS5DKCJpNTwxPiIpKX1yZXR1cm4gbmV3IFAu
+aTgodGhpcyl9LApZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9dGhpcwppZihyLmI9PW51bGwpci5j
+LlkoMCxiLGMpCmVsc2UgaWYoci54NChiKSl7dD1yLmIKdFtiXT1jCnM9ci5hCmlmKHM9PW51bGw/dCE9
+bnVsbDpzIT09dClzW2JdPW51bGx9ZWxzZSByLlhLKCkuWSgwLGIsYyl9LAp4NDpmdW5jdGlvbihhKXtp
+Zih0aGlzLmI9PW51bGwpcmV0dXJuIHRoaXMuYy54NChhKQpyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5o
+YXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuYSxhKX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxw
+PXRoaXMKdS5jQS5iKGIpCmlmKHAuYj09bnVsbClyZXR1cm4gcC5jLksoMCxiKQp0PXAuQ2YoKQpmb3Io
+cz0wO3M8dC5sZW5ndGg7KytzKXtyPXRbc10KcT1wLmJbcl0KaWYodHlwZW9mIHE9PSJ1bmRlZmluZWQi
+KXtxPVAuUWUocC5hW3JdKQpwLmJbcl09cX1iLiQyKHIscSkKaWYodCE9PXAuYyl0aHJvdyBILmIoUC5h
+NChwKSl9fSwKQ2Y6ZnVuY3Rpb24oKXt2YXIgdD11LmouYih0aGlzLmMpCmlmKHQ9PW51bGwpdD10aGlz
+LmM9SC5WTShPYmplY3Qua2V5cyh0aGlzLmEpLHUucykKcmV0dXJuIHR9LApYSzpmdW5jdGlvbigpe3Zh
+ciB0LHMscixxLHAsbz10aGlzCmlmKG8uYj09bnVsbClyZXR1cm4gby5jCnQ9UC5GbCh1Lk4sdS56KQpz
+PW8uQ2YoKQpmb3Iocj0wO3E9cy5sZW5ndGgscjxxOysrcil7cD1zW3JdCnQuWSgwLHAsby5xKDAscCkp
+fWlmKHE9PT0wKUMuTm0uaShzLG51bGwpCmVsc2UgQy5ObS5zQShzLDApCm8uYT1vLmI9bnVsbApyZXR1
+cm4gby5jPXR9LApmYjpmdW5jdGlvbihhKXt2YXIgdAppZighT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Q
+cm9wZXJ0eS5jYWxsKHRoaXMuYSxhKSlyZXR1cm4gbnVsbAp0PVAuUWUodGhpcy5hW2FdKQpyZXR1cm4g
+dGhpcy5iW2FdPXR9fQpQLmk4LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpy
+ZXR1cm4gdC5nQSh0KX0sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEKaWYodC5iPT1udWxsKXQ9
+dC5nVigpLkUoMCxiKQplbHNle3Q9dC5DZigpCmlmKGI8MHx8Yj49dC5sZW5ndGgpcmV0dXJuIEguT0go
+dCxiKQp0PXRbYl19cmV0dXJuIHR9LApna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCmlmKHQuYj09
+bnVsbCl7dD10LmdWKCkKdD10Lmdreih0KX1lbHNle3Q9dC5DZigpCnQ9bmV3IEoubTEodCx0Lmxlbmd0
+aCxILnQ2KHQpLkMoIm0xPDE+IikpfXJldHVybiB0fX0KUC5DVi5wcm90b3R5cGU9ewp5cjpmdW5jdGlv
+bihhLGEwLGExKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMsYj0iSW52YWxp
+ZCBiYXNlNjQgZW5jb2RpbmcgbGVuZ3RoICIKYTE9UC5qQihhMCxhMSxhLmxlbmd0aCkKdD0kLlY3KCkK
+Zm9yKHM9YTAscj1zLHE9bnVsbCxwPS0xLG89LTEsbj0wO3M8YTE7cz1tKXttPXMrMQpsPUMueEIuVyhh
+LHMpCmlmKGw9PT0zNyl7az1tKzIKaWYoazw9YTEpe2o9SC5vbyhDLnhCLlcoYSxtKSkKaT1ILm9vKEMu
+eEIuVyhhLG0rMSkpCmg9aioxNitpLShpJjI1NikKaWYoaD09PTM3KWg9LTEKbT1rfWVsc2UgaD0tMX1l
+bHNlIGg9bAppZigwPD1oJiZoPD0xMjcpe2lmKGg8MHx8aD49dC5sZW5ndGgpcmV0dXJuIEguT0godCxo
+KQpnPXRbaF0KaWYoZz49MCl7aD1DLnhCLm0oIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVm
+Z2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8iLGcpCmlmKGg9PT1sKWNvbnRpbnVlCmw9aH1l
+bHNle2lmKGc9PT0tMSl7aWYocDwwKXtmPXE9PW51bGw/bnVsbDpxLmEubGVuZ3RoCmlmKGY9PW51bGwp
+Zj0wCnA9Zisocy1yKQpvPXN9KytuCmlmKGw9PT02MSljb250aW51ZX1sPWh9aWYoZyE9PS0yKXtpZihx
+PT1udWxsKXE9bmV3IFAuUm4oIiIpCnEuYSs9Qy54Qi5OaihhLHIscykKcS5hKz1ILkx3KGwpCnI9bQpj
+b250aW51ZX19dGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IGRhdGEiLGEscykpfWlmKHEhPW51
+bGwpe2Y9cS5hKz1DLnhCLk5qKGEscixhMSkKZT1mLmxlbmd0aAppZihwPj0wKVAueE0oYSxvLGExLHAs
+bixlKQplbHNle2Q9Qy5qbi56WShlLTEsNCkrMQppZihkPT09MSl0aHJvdyBILmIoUC5ycihiLGEsYTEp
+KQpmb3IoO2Q8NDspe2YrPSI9IgpxLmE9ZjsrK2R9fWY9cS5hCnJldHVybiBDLnhCLmk3KGEsYTAsYTEs
+Zi5jaGFyQ29kZUF0KDApPT0wP2Y6Zil9Yz1hMS1hMAppZihwPj0wKVAueE0oYSxvLGExLHAsbixjKQpl
+bHNle2Q9Qy5qbi56WShjLDQpCmlmKGQ9PT0xKXRocm93IEguYihQLnJyKGIsYSxhMSkpCmlmKGQ+MSlh
+PUMueEIuaTcoYSxhMSxhMSxkPT09Mj8iPT0iOiI9Iil9cmV0dXJuIGF9fQpQLlU4LnByb3RvdHlwZT17
+fQpQLlVrLnByb3RvdHlwZT17fQpQLndJLnByb3RvdHlwZT17fQpQLlppLnByb3RvdHlwZT17fQpQLmJ5
+LnByb3RvdHlwZT17CnBXOmZ1bmN0aW9uKGEsYixjKXt2YXIgdAp1LmVwLmIoYykKdD1QLkJTKGIsdGhp
+cy5nSGUoKS5hKQpyZXR1cm4gdH0sCmdIZTpmdW5jdGlvbigpe3JldHVybiBDLkEzfX0KUC5NeC5wcm90
+b3R5cGU9e30KUC51NS5wcm90b3R5cGU9ewpnWkU6ZnVuY3Rpb24oKXtyZXR1cm4gQy5Ra319ClAuRTMu
+cHJvdG90eXBlPXsKV0o6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPVAuakIoMCxudWxsLGEubGVuZ3RoKSxx
+PXItMAppZihxPT09MClyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoMCkKdD1uZXcgVWludDhBcnJheShxKjMp
+CnM9bmV3IFAuUncodCkKaWYocy5HeChhLDAscikhPT1yKXMuTzYoSi5hNihhLHItMSksMCkKcmV0dXJu
+IG5ldyBVaW50OEFycmF5KHQuc3ViYXJyYXkoMCxILnJNKDAscy5iLHQubGVuZ3RoKSkpfX0KUC5Sdy5w
+cm90b3R5cGU9ewpPNjpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcyxyPXMuYyxxPXMuYixwPXErMSxv
+PXIubGVuZ3RoCmlmKChiJjY0NTEyKT09PTU2MzIwKXt0PTY1NTM2KygoYSYxMDIzKTw8MTApfGImMTAy
+MwpzLmI9cAppZihxPj1vKXJldHVybiBILk9IKHIscSkKcltxXT0yNDB8dD4+PjE4CnE9cy5iPXArMQpp
+ZihwPj1vKXJldHVybiBILk9IKHIscCkKcltwXT0xMjh8dD4+PjEyJjYzCnA9cy5iPXErMQppZihxPj1v
+KXJldHVybiBILk9IKHIscSkKcltxXT0xMjh8dD4+PjYmNjMKcy5iPXArMQppZihwPj1vKXJldHVybiBI
+Lk9IKHIscCkKcltwXT0xMjh8dCY2MwpyZXR1cm4hMH1lbHNle3MuYj1wCmlmKHE+PW8pcmV0dXJuIEgu
+T0gocixxKQpyW3FdPTIyNHxhPj4+MTIKcT1zLmI9cCsxCmlmKHA+PW8pcmV0dXJuIEguT0gocixwKQpy
+W3BdPTEyOHxhPj4+NiY2MwpzLmI9cSsxCmlmKHE+PW8pcmV0dXJuIEguT0gocixxKQpyW3FdPTEyOHxh
+JjYzCnJldHVybiExfX0sCkd4OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtPXRoaXMK
+aWYoYiE9PWMmJihDLnhCLm0oYSxjLTEpJjY0NTEyKT09PTU1Mjk2KS0tYwpmb3IodD1tLmMscz10Lmxl
+bmd0aCxyPWI7cjxjOysrcil7cT1DLnhCLlcoYSxyKQppZihxPD0xMjcpe3A9bS5iCmlmKHA+PXMpYnJl
+YWsKbS5iPXArMQp0W3BdPXF9ZWxzZSBpZigocSY2NDUxMik9PT01NTI5Nil7aWYobS5iKzM+PXMpYnJl
+YWsKbz1yKzEKaWYobS5PNihxLEMueEIuVyhhLG8pKSlyPW99ZWxzZSBpZihxPD0yMDQ3KXtwPW0uYgpu
+PXArMQppZihuPj1zKWJyZWFrCm0uYj1uCmlmKHA+PXMpcmV0dXJuIEguT0godCxwKQp0W3BdPTE5Mnxx
+Pj4+NgptLmI9bisxCnRbbl09MTI4fHEmNjN9ZWxzZXtwPW0uYgppZihwKzI+PXMpYnJlYWsKbj1tLmI9
+cCsxCmlmKHA+PXMpcmV0dXJuIEguT0godCxwKQp0W3BdPTIyNHxxPj4+MTIKcD1tLmI9bisxCmlmKG4+
+PXMpcmV0dXJuIEguT0godCxuKQp0W25dPTEyOHxxPj4+NiY2MwptLmI9cCsxCmlmKHA+PXMpcmV0dXJu
+IEguT0godCxwKQp0W3BdPTEyOHxxJjYzfX1yZXR1cm4gcn19ClAuR1kucHJvdG90eXBlPXsKV0o6ZnVu
+Y3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsCnUuTC5iKGEpCnQ9UC5reSghMSxhLDAsbnVsbCkK
+aWYodCE9bnVsbClyZXR1cm4gdApzPVAuakIoMCxudWxsLEouSG0oYSkpCnI9UC5jUChhLDAscykKaWYo
+cj4wKXtxPVAuSE0oYSwwLHIpCmlmKHI9PT1zKXJldHVybiBxCnA9bmV3IFAuUm4ocSkKbz1yCm49ITF9
+ZWxzZXtvPTAKcD1udWxsCm49ITB9aWYocD09bnVsbClwPW5ldyBQLlJuKCIiKQptPW5ldyBQLmJ6KCEx
+LHApCm0uYz1uCm0uTUUoYSxvLHMpCmlmKG0uZT4wKXtILnZoKFAucnIoIlVuZmluaXNoZWQgVVRGLTgg
+b2N0ZXQgc2VxdWVuY2UiLGEscykpCnAuYSs9SC5Mdyg2NTUzMykKbS5mPW0uZT1tLmQ9MH1sPXAuYQpy
+ZXR1cm4gbC5jaGFyQ29kZUF0KDApPT0wP2w6bH19ClAuYnoucHJvdG90eXBlPXsKTUU6ZnVuY3Rpb24o
+YSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoPXRoaXMsZz0iQmFkIFVURi04IGVuY29k
+aW5nIDB4Igp1LkwuYihhKQp0PWguZApzPWguZQpyPWguZgpoLmY9aC5lPWguZD0wCiRsYWJlbDAkMDpm
+b3IocT1KLlU2KGEpLHA9aC5iLG89YjshMDtvPWopeyRsYWJlbDEkMTppZihzPjApe2Rve2lmKG89PT1j
+KWJyZWFrICRsYWJlbDAkMApuPXEucShhLG8pCmlmKHR5cGVvZiBuIT09Im51bWJlciIpcmV0dXJuIG4u
+ek0oKQppZigobiYxOTIpIT09MTI4KXttPVAucnIoZytDLmpuLldaKG4sMTYpLGEsbykKdGhyb3cgSC5i
+KG0pfWVsc2V7dD0odDw8NnxuJjYzKT4+PjA7LS1zOysrb319d2hpbGUocz4wKQptPXItMQppZihtPDB8
+fG0+PTQpcmV0dXJuIEguT0goQy5HYixtKQppZih0PD1DLkdiW21dKXttPVAucnIoIk92ZXJsb25nIGVu
+Y29kaW5nIG9mIDB4IitDLmpuLldaKHQsMTYpLGEsby1yLTEpCnRocm93IEguYihtKX1pZih0PjExMTQx
+MTEpe209UC5ycigiQ2hhcmFjdGVyIG91dHNpZGUgdmFsaWQgVW5pY29kZSByYW5nZTogMHgiK0Muam4u
+V1oodCwxNiksYSxvLXItMSkKdGhyb3cgSC5iKG0pfWlmKCFoLmN8fHQhPT02NTI3OSlwLmErPUguTHco
+dCkKaC5jPSExfWZvcihtPW88YzttOyl7bD1QLmNQKGEsbyxjKQppZihsPjApe2guYz0hMQprPW8rbApw
+LmErPVAuSE0oYSxvLGspCmlmKGs9PT1jKWJyZWFrfWVsc2Ugaz1vCmo9aysxCm49cS5xKGEsaykKaWYo
+dHlwZW9mIG4hPT0ibnVtYmVyIilyZXR1cm4gbi5KKCkKaWYobjwwKXtpPVAucnIoIk5lZ2F0aXZlIFVU
+Ri04IGNvZGUgdW5pdDogLTB4IitDLmpuLldaKC1uLDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfWVsc2V7
+aWYoKG4mMjI0KT09PTE5Mil7dD1uJjMxCnM9MQpyPTEKY29udGludWUgJGxhYmVsMCQwfWlmKChuJjI0
+MCk9PT0yMjQpe3Q9biYxNQpzPTIKcj0yCmNvbnRpbnVlICRsYWJlbDAkMH1pZigobiYyNDgpPT09MjQw
+JiZuPDI0NSl7dD1uJjcKcz0zCnI9Mwpjb250aW51ZSAkbGFiZWwwJDB9aT1QLnJyKGcrQy5qbi5XWihu
+LDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfX1icmVhayAkbGFiZWwwJDB9aWYocz4wKXtoLmQ9dApoLmU9
+cwpoLmY9cn19fQpQLldGLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCnUuZm8u
+YihhKQp0PXRoaXMuYgpzPXRoaXMuYQp0LmErPXMuYQpyPXQuYSs9SC5kKGEuYSkKdC5hPXIrIjogIgp0
+LmErPVAucChiKQpzLmE9IiwgIn0sCiRTOjMyfQpQLmEyLnByb3RvdHlwZT17fQpQLmlQLnByb3RvdHlw
+ZT17CkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9m
+IFAuaVAmJnRoaXMuYT09PWIuYSYmITB9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVy
+bih0XkMuam4ud0codCwzMCkpJjEwNzM3NDE4MjN9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1Q
+LkdxKEgudEoodCkpLHI9UC5oMChILk5TKHQpKSxxPVAuaDAoSC5qQSh0KSkscD1QLmgwKEguS0wodCkp
+LG89UC5oMChILmNoKHQpKSxuPVAuaDAoSC5KZCh0KSksbT1QLlZ4KEgubzEodCkpLGw9cysiLSIrcisi
+LSIrcSsiICIrcCsiOiIrbysiOiIrbisiLiIrbQpyZXR1cm4gbH19ClAuQ1AucHJvdG90eXBlPXt9ClAu
+WFMucHJvdG90eXBlPXt9ClAuQzYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEK
+aWYodCE9bnVsbClyZXR1cm4iQXNzZXJ0aW9uIGZhaWxlZDogIitQLnAodCkKcmV0dXJuIkFzc2VydGlv
+biBmYWlsZWQifX0KUC5uLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlRocm93IG9mIG51
+bGwuIn19ClAudS5wcm90b3R5cGU9ewpnWjpmdW5jdGlvbigpe3JldHVybiJJbnZhbGlkIGFyZ3VtZW50
+IisoIXRoaXMuYT8iKHMpIjoiIil9LApndTpmdW5jdGlvbigpe3JldHVybiIifSwKdzpmdW5jdGlvbihh
+KXt2YXIgdCxzLHIscSxwPXRoaXMsbz1wLmMsbj1vIT1udWxsPyIgKCIrbysiKSI6IiIKbz1wLmQKdD1v
+PT1udWxsPyIiOiI6ICIrSC5kKG8pCnM9cC5nWigpK24rdAppZighcC5hKXJldHVybiBzCnI9cC5ndSgp
+CnE9UC5wKHAuYikKcmV0dXJuIHMrcisiOiAiK3F9fQpQLmJKLnByb3RvdHlwZT17CmdaOmZ1bmN0aW9u
+KCl7cmV0dXJuIlJhbmdlRXJyb3IifSwKZ3U6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcy5lCmlmKHI9
+PW51bGwpe3I9dGhpcy5mCnQ9ciE9bnVsbD8iOiBOb3QgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICIrSC5k
+KHIpOiIifWVsc2V7cz10aGlzLmYKaWYocz09bnVsbCl0PSI6IE5vdCBncmVhdGVyIHRoYW4gb3IgZXF1
+YWwgdG8gIitILmQocikKZWxzZSBpZihzPnIpdD0iOiBOb3QgaW4gcmFuZ2UgIitILmQocikrIi4uIitI
+LmQocykrIiwgaW5jbHVzaXZlIgplbHNlIHQ9czxyPyI6IFZhbGlkIHZhbHVlIHJhbmdlIGlzIGVtcHR5
+IjoiOiBPbmx5IHZhbGlkIHZhbHVlIGlzICIrSC5kKHIpfXJldHVybiB0fX0KUC5lWS5wcm90b3R5cGU9
+ewpnWjpmdW5jdGlvbigpe3JldHVybiJSYW5nZUVycm9yIn0sCmd1OmZ1bmN0aW9uKCl7dmFyIHQscz1I
+LlNjKHRoaXMuYikKaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5KKCkKaWYoczwwKXJldHVy
+biI6IGluZGV4IG11c3Qgbm90IGJlIG5lZ2F0aXZlIgp0PXRoaXMuZgppZih0PT09MClyZXR1cm4iOiBu
+byBpbmRpY2VzIGFyZSB2YWxpZCIKcmV0dXJuIjogaW5kZXggc2hvdWxkIGJlIGxlc3MgdGhhbiAiK0gu
+ZCh0KX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmZ9fQpQLm1wLnByb3RvdHlwZT17Cnc6ZnVu
+Y3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsPXRoaXMsaz17fSxqPW5ldyBQLlJuKCIiKQprLmE9
+IiIKZm9yKHQ9bC5jLHM9dC5sZW5ndGgscj0wLHE9IiIscD0iIjtyPHM7KytyLHA9IiwgIil7bz10W3Jd
+CmouYT1xK3AKcT1qLmErPVAucChvKQprLmE9IiwgIn1sLmQuSygwLG5ldyBQLldGKGssaikpCm49UC5w
+KGwuYSkKbT1qLncoMCkKdD0iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK0gu
+ZChsLmIuYSkrIidcblJlY2VpdmVyOiAiK24rIlxuQXJndW1lbnRzOiBbIittKyJdIgpyZXR1cm4gdH19
+ClAudWIucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iVW5zdXBwb3J0ZWQgb3BlcmF0aW9u
+OiAiK3RoaXMuYX19ClAuZHMucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0
+dXJuIHQhPW51bGw/IlVuaW1wbGVtZW50ZWRFcnJvcjogIit0OiJVbmltcGxlbWVudGVkRXJyb3IifX0K
+UC5sai5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJCYWQgc3RhdGU6ICIrdGhpcy5hfX0K
+UC5VVi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQppZih0PT1udWxsKXJldHVy
+biJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRlcmF0aW9uLiIKcmV0dXJuIkNvbmN1cnJl
+bnQgbW9kaWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb246ICIrUC5wKHQpKyIuIn19ClAuazUucHJvdG90
+eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iT3V0IG9mIE1lbW9yeSJ9LAokaVhTOjF9ClAuS1kucHJv
+dG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iU3RhY2sgT3ZlcmZsb3cifSwKJGlYUzoxfQpQLmMu
+cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQ9PW51bGw/IlJlYWRp
+bmcgc3RhdGljIHZhcmlhYmxlIGR1cmluZyBpdHMgaW5pdGlhbGl6YXRpb24iOiJSZWFkaW5nIHN0YXRp
+YyB2YXJpYWJsZSAnIit0KyInIGR1cmluZyBpdHMgaW5pdGlhbGl6YXRpb24ifX0KUC5DRC5wcm90b3R5
+cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJFeGNlcHRpb246ICIrdGhpcy5hfX0KUC5hRS5wcm90b3R5
+cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoPXRoaXMuYSxnPWgh
+PW51bGwmJiIiIT09aD8iRm9ybWF0RXhjZXB0aW9uOiAiK0guZChoKToiRm9ybWF0RXhjZXB0aW9uIixm
+PXRoaXMuYyxlPXRoaXMuYgppZih0eXBlb2YgZT09InN0cmluZyIpe2lmKGYhPW51bGwpaD1mPDB8fGY+
+ZS5sZW5ndGgKZWxzZSBoPSExCmlmKGgpZj1udWxsCmlmKGY9PW51bGwpe3Q9ZS5sZW5ndGg+Nzg/Qy54
+Qi5OaihlLDAsNzUpKyIuLi4iOmUKcmV0dXJuIGcrIlxuIit0fWZvcihzPTEscj0wLHE9ITEscD0wO3A8
+ZjsrK3Ape289Qy54Qi5XKGUscCkKaWYobz09PTEwKXtpZihyIT09cHx8IXEpKytzCnI9cCsxCnE9ITF9
+ZWxzZSBpZihvPT09MTMpeysrcwpyPXArMQpxPSEwfX1nPXM+MT9nKygiIChhdCBsaW5lICIrcysiLCBj
+aGFyYWN0ZXIgIisoZi1yKzEpKyIpXG4iKTpnKygiIChhdCBjaGFyYWN0ZXIgIisoZisxKSsiKVxuIikK
+bj1lLmxlbmd0aApmb3IocD1mO3A8bjsrK3Ape289Qy54Qi5tKGUscCkKaWYobz09PTEwfHxvPT09MTMp
+e249cApicmVha319aWYobi1yPjc4KWlmKGYtcjw3NSl7bT1yKzc1Cmw9cgprPSIiCmo9Ii4uLiJ9ZWxz
+ZXtpZihuLWY8NzUpe2w9bi03NQptPW4Kaj0iIn1lbHNle2w9Zi0zNgptPWYrMzYKaj0iLi4uIn1rPSIu
+Li4ifWVsc2V7bT1uCmw9cgprPSIiCmo9IiJ9aT1DLnhCLk5qKGUsbCxtKQpyZXR1cm4gZytrK2kraisi
+XG4iK0MueEIuSXgoIiAiLGYtbCtrLmxlbmd0aCkrIl5cbiJ9ZWxzZSByZXR1cm4gZiE9bnVsbD9nKygi
+IChhdCBvZmZzZXQgIitILmQoZikrIikiKTpnfX0KUC5FSC5wcm90b3R5cGU9e30KUC5LTi5wcm90b3R5
+cGU9e30KUC5jWC5wcm90b3R5cGU9ewpldjpmdW5jdGlvbihhLGIpe3ZhciB0PUguTGgodGhpcykKcmV0
+dXJuIG5ldyBILlU1KHRoaXMsdC5DKCJhMihjWC5FKSIpLmIoYiksdC5DKCJVNTxjWC5FPiIpKX0sCmdB
+OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5na3oodGhpcykKZm9yKHQ9MDtzLkYoKTspKyt0CnJldHVy
+biB0fSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiF0aGlzLmdreih0aGlzKS5GKCl9LApncjg6ZnVuY3Rp
+b24oYSl7dmFyIHQscz10aGlzLmdreih0aGlzKQppZighcy5GKCkpdGhyb3cgSC5iKEguV3AoKSkKdD1z
+LmdsKCkKaWYocy5GKCkpdGhyb3cgSC5iKEguZFUoKSkKcmV0dXJuIHR9LApFOmZ1bmN0aW9uKGEsYil7
+dmFyIHQscyxyClAuazEoYiwiaW5kZXgiKQpmb3IodD10aGlzLmdreih0aGlzKSxzPTA7dC5GKCk7KXty
+PXQuZ2woKQppZihiPT09cylyZXR1cm4gcjsrK3N9dGhyb3cgSC5iKFAuQ2YoYix0aGlzLCJpbmRleCIs
+bnVsbCxzKSl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLkVQKHRoaXMsIigiLCIpIil9fQpQLkFuLnBy
+b3RvdHlwZT17fQpQLnpNLnByb3RvdHlwZT17JGljWDoxfQpQLlowLnByb3RvdHlwZT17fQpQLmM4LnBy
+b3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gUC5rLnByb3RvdHlwZS5naU8uY2FsbCh0aGlz
+LHRoaXMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9fQpQLkZLLnByb3RvdHlwZT17fQpQLmsu
+cHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpQLmssJGlrOjEsCkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRo
+aXM9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKHRoaXMpfSwKdzpmdW5jdGlvbihhKXty
+ZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5kKEguTSh0aGlzKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt1
+Lm8uYihiKQp0aHJvdyBILmIoUC5scih0aGlzLGIuZ1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9LAp0b1N0
+cmluZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLncodGhpcyl9fQpQLk9kLnByb3RvdHlwZT17fQpQLmli
+LnByb3RvdHlwZT17JGlPZDoxfQpQLnh1LnByb3RvdHlwZT17fQpQLkd6LnByb3RvdHlwZT17fQpQLnFV
+LnByb3RvdHlwZT17JGl2WDoxfQpQLlJuLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0
+aGlzLmEubGVuZ3RofSwKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuY2hhckNvZGVB
+dCgwKT09MD90OnR9LAokaUJMOjF9ClAuR0QucHJvdG90eXBlPXt9ClAubjEucHJvdG90eXBlPXsKJDI6
+ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1LmYuYihhKQpILnkoYikKdD1KLnJZKGIpLk9ZKGIsIj0i
+KQppZih0PT09LTEpe2lmKGIhPT0iIilhLlkoMCxQLmt1KGIsMCxiLmxlbmd0aCx0aGlzLmEsITApLCIi
+KX1lbHNlIGlmKHQhPT0wKXtzPUMueEIuTmooYiwwLHQpCnI9Qy54Qi5HKGIsdCsxKQpxPXRoaXMuYQph
+LlkoMCxQLmt1KHMsMCxzLmxlbmd0aCxxLCEwKSxQLmt1KHIsMCxyLmxlbmd0aCxxLCEwKSl9cmV0dXJu
+IGF9LAokUzozOX0KUC5jUy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLnJy
+KCJJbGxlZ2FsIElQdjQgYWRkcmVzcywgIithLHRoaXMuYSxiKSl9LAokUzoyOX0KUC5WQy5wcm90b3R5
+cGU9ewokMjpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLnJyKCJJbGxlZ2FsIElQdjYgYWRkcmVzcywg
+IithLHRoaXMuYSxiKSl9LAokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy4kMihhLG51bGwpfSwKJFM6
+MjZ9ClAudHAucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihiLWE+NCl0aGlzLmEu
+JDIoImFuIElQdjYgcGFydCBjYW4gb25seSBjb250YWluIGEgbWF4aW11bSBvZiA0IGhleCBkaWdpdHMi
+LGEpCnQ9UC5RQShDLnhCLk5qKHRoaXMuYixhLGIpLG51bGwsMTYpCmlmKHR5cGVvZiB0IT09Im51bWJl
+ciIpcmV0dXJuIHQuSigpCmlmKHQ8MHx8dD42NTUzNSl0aGlzLmEuJDIoImVhY2ggcGFydCBtdXN0IGJl
+IGluIHRoZSByYW5nZSBvZiBgMHgwLi4weEZGRkZgIixhKQpyZXR1cm4gdH0sCiRTOjE5fQpQLkRuLnBy
+b3RvdHlwZT17CmdrdTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmJ9LApnSmY6ZnVuY3Rpb24oYSl7dmFy
+IHQ9dGhpcy5jCmlmKHQ9PW51bGwpcmV0dXJuIiIKaWYoQy54Qi5uKHQsIlsiKSlyZXR1cm4gQy54Qi5O
+aih0LDEsdC5sZW5ndGgtMSkKcmV0dXJuIHR9LApndHA6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5kCmlm
+KHQ9PW51bGwpcmV0dXJuIFAud0sodGhpcy5hKQpyZXR1cm4gdH0sCmd0UDpmdW5jdGlvbigpe3ZhciB0
+PXRoaXMuZgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKZ0thOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5yCnJl
+dHVybiB0PT1udWxsPyIiOnR9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10
+aGlzCnUuWC5iKG51bGwpCnUuYi5iKGIpCnQ9bC5hCnM9dD09PSJmaWxlIgpyPWwuYgpxPWwuZApwPWwu
+YwppZighKHAhPW51bGwpKXA9ci5sZW5ndGghPT0wfHxxIT1udWxsfHxzPyIiOm51bGwKbz1sLmUKaWYo
+IXMpbj1wIT1udWxsJiZvLmxlbmd0aCE9PTAKZWxzZSBuPSEwCmlmKG4mJiFDLnhCLm4obywiLyIpKW89
+Ii8iK28KaWYoYiE9bnVsbCltPVAubGUobnVsbCwwLDAsYikKZWxzZSBtPWwuZgpyZXR1cm4gbmV3IFAu
+RG4odCxyLHAscSxvLG0sbC5yKX0sCmdGajpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcy54CmlmKHMhPW51
+bGwpcmV0dXJuIHMKdD10aGlzLmUKaWYodC5sZW5ndGghPT0wJiZDLnhCLlcodCwwKT09PTQ3KXQ9Qy54
+Qi5HKHQsMSkKcz10PT09IiI/Qy5kbjpQLkFGKG5ldyBILkE4KEguVk0odC5zcGxpdCgiLyIpLHUucyks
+dS5kTy5iKFAuUEgoKSksdS5kbyksdS5OKQp0aGlzLnNvNihzKQpyZXR1cm4gc30sCmdoWTpmdW5jdGlv
+bigpe3ZhciB0LHM9dGhpcwppZihzLlE9PW51bGwpe3Q9cy5mCnMuc1JIKG5ldyBQLkdqKFAuV1godD09
+bnVsbD8iIjp0KSx1LlQpKX1yZXR1cm4gcy5RfSwKSmg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxw
+LG8KZm9yKHQ9MCxzPTA7Qy54Qi5RaShiLCIuLi8iLHMpOyl7cys9MzsrK3R9cj1DLnhCLmNuKGEsIi8i
+KQp3aGlsZSghMCl7aWYoIShyPjAmJnQ+MCkpYnJlYWsKcT1DLnhCLlBrKGEsIi8iLHItMSkKaWYocTww
+KWJyZWFrCnA9ci1xCm89cCE9PTIKaWYoIW98fHA9PT0zKWlmKEMueEIubShhLHErMSk9PT00NilvPSFv
+fHxDLnhCLm0oYSxxKzIpPT09NDYKZWxzZSBvPSExCmVsc2Ugbz0hMQppZihvKWJyZWFrOy0tdApyPXF9
+cmV0dXJuIEMueEIuaTcoYSxyKzEsbnVsbCxDLnhCLkcoYixzLTMqdCkpfSwKWkk6ZnVuY3Rpb24oYSl7
+cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixt
+LGwsaz10aGlzLGo9bnVsbAppZihhLmdGaSgpLmxlbmd0aCE9PTApe3Q9YS5nRmkoKQppZihhLmdjaigp
+KXtzPWEuZ2t1KCkKcj1hLmdKZihhKQpxPWEuZ3hBKCk/YS5ndHAoYSk6an1lbHNle3E9agpyPXEKcz0i
+In1wPVAueGUoYS5nSWkoYSkpCm89YS5nUUQoKT9hLmd0UCgpOmp9ZWxzZXt0PWsuYQppZihhLmdjaigp
+KXtzPWEuZ2t1KCkKcj1hLmdKZihhKQpxPVAud0IoYS5neEEoKT9hLmd0cChhKTpqLHQpCnA9UC54ZShh
+LmdJaShhKSkKbz1hLmdRRCgpP2EuZ3RQKCk6an1lbHNle3M9ay5iCnI9ay5jCnE9ay5kCmlmKGEuZ0lp
+KGEpPT09IiIpe3A9ay5lCm89YS5nUUQoKT9hLmd0UCgpOmsuZn1lbHNle2lmKGEuZ3RUKCkpcD1QLnhl
+KGEuZ0lpKGEpKQplbHNle249ay5lCmlmKG4ubGVuZ3RoPT09MClpZihyPT1udWxsKXA9dC5sZW5ndGg9
+PT0wP2EuZ0lpKGEpOlAueGUoYS5nSWkoYSkpCmVsc2UgcD1QLnhlKCIvIithLmdJaShhKSkKZWxzZXtt
+PWsuSmgobixhLmdJaShhKSkKbD10Lmxlbmd0aD09PTAKaWYoIWx8fHIhPW51bGx8fEMueEIubihuLCIv
+IikpcD1QLnhlKG0pCmVsc2UgcD1QLndGKG0sIWx8fHIhPW51bGwpfX1vPWEuZ1FEKCk/YS5ndFAoKTpq
+fX19cmV0dXJuIG5ldyBQLkRuKHQscyxyLHEscCxvLGEuZ1o4KCk/YS5nS2EoKTpqKX0sCmdjajpmdW5j
+dGlvbigpe3JldHVybiB0aGlzLmMhPW51bGx9LApneEE6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kIT1u
+dWxsfSwKZ1FEOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZiE9bnVsbH0sCmdaODpmdW5jdGlvbigpe3Jl
+dHVybiB0aGlzLnIhPW51bGx9LApndFQ6ZnVuY3Rpb24oKXtyZXR1cm4gQy54Qi5uKHRoaXMuZSwiLyIp
+fSwKdDQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcyxxPXIuYQppZihxIT09IiImJnEhPT0iZmlsZSIp
+dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSAiK0guZChxKSsi
+IFVSSSIpKQpxPXIuZgppZigocT09bnVsbD8iIjpxKSE9PSIiKXRocm93IEguYihQLkw0KCJDYW5ub3Qg
+ZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQiKSkKcT1y
+LnIKaWYoKHE9PW51bGw/IiI6cSkhPT0iIil0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBm
+aWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgZnJhZ21lbnQgY29tcG9uZW50IikpCnQ9JC53USgpCmlm
+KEgub1QodCkpcT1QLm1uKHIpCmVsc2V7aWYoci5jIT1udWxsJiZyLmdKZihyKSE9PSIiKUgudmgoUC5M
+NCgiQ2Fubm90IGV4dHJhY3QgYSBub24tV2luZG93cyBmaWxlIHBhdGggZnJvbSBhIGZpbGUgVVJJIHdp
+dGggYW4gYXV0aG9yaXR5IikpCnM9ci5nRmooKQpQLmtFKHMsITEpCnE9UC52ZyhDLnhCLm4oci5lLCIv
+Iik/Ii8iOiIiLHMsIi8iKQpxPXEuY2hhckNvZGVBdCgwKT09MD9xOnF9cmV0dXJuIHF9LAp3OmZ1bmN0
+aW9uKGEpe3ZhciB0LHMscixxPXRoaXMscD1xLnkKaWYocD09bnVsbCl7cD1xLmEKdD1wLmxlbmd0aCE9
+PTA/cCsiOiI6IiIKcz1xLmMKcj1zPT1udWxsCmlmKCFyfHxwPT09ImZpbGUiKXtwPXQrIi8vIgp0PXEu
+YgppZih0Lmxlbmd0aCE9PTApcD1wK3QrIkAiCmlmKCFyKXArPXMKdD1xLmQKaWYodCE9bnVsbClwPXAr
+IjoiK0guZCh0KX1lbHNlIHA9dApwKz1xLmUKdD1xLmYKaWYodCE9bnVsbClwPXArIj8iK3QKdD1xLnIK
+aWYodCE9bnVsbClwPXArIiMiK3QKcD1xLnk9cC5jaGFyQ29kZUF0KDApPT0wP3A6cH1yZXR1cm4gcH0s
+CkROOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMKaWYoYj09bnVsbClyZXR1cm4hMQppZihyPT09
+YilyZXR1cm4hMAppZih1LkQuYyhiKSlpZihyLmE9PWIuZ0ZpKCkpaWYoci5jIT1udWxsPT09Yi5nY2oo
+KSlpZihyLmI9PWIuZ2t1KCkpaWYoci5nSmYocik9PWIuZ0pmKGIpKWlmKHIuZ3RwKHIpPT1iLmd0cChi
+KSlpZihyLmU9PT1iLmdJaShiKSl7dD1yLmYKcz10PT1udWxsCmlmKCFzPT09Yi5nUUQoKSl7aWYocyl0
+PSIiCmlmKHQ9PT1iLmd0UCgpKXt0PXIucgpzPXQ9PW51bGwKaWYoIXM9PT1iLmdaOCgpKXtpZihzKXQ9
+IiIKdD10PT09Yi5nS2EoKX1lbHNlIHQ9ITF9ZWxzZSB0PSExfWVsc2UgdD0hMX1lbHNlIHQ9ITEKZWxz
+ZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKcmV0
+dXJuIHR9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy56CnJldHVybiB0PT1udWxsP3RoaXMuej1D
+LnhCLmdpTyh0aGlzLncoMCkpOnR9LApzbzY6ZnVuY3Rpb24oYSl7dGhpcy54PXUuYS5iKGEpfSwKc1JI
+OmZ1bmN0aW9uKGEpe3RoaXMuUT11LmYuYihhKX0sCiRpaUQ6MSwKZ0ZpOmZ1bmN0aW9uKCl7cmV0dXJu
+IHRoaXMuYX0sCmdJaTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lfX0KUC5lMS5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXt0aHJvdyBILmIoUC5ycigiSW52YWxpZCBwb3J0Iix0aGlzLmEsdGhpcy5iKzEp
+KX0sCiRTOjExfQpQLk5ZLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PSJJbGxlZ2FsIHBh
+dGggY2hhcmFjdGVyICIKSC55KGEpCmlmKEouemwoYSwiLyIpKWlmKHRoaXMuYSl0aHJvdyBILmIoUC54
+WSh0K2EpKQplbHNlIHRocm93IEguYihQLkw0KHQrYSkpfSwKJFM6MTF9ClAuUloucHJvdG90eXBlPXsK
+JDE6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuZVAoQy5aSixhLEMueE0sITEpfSwKJFM6NX0KUC5NRS5wcm90
+b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYixzPXRoaXMuYQp0LmErPXMuYQpzLmE9
+IiYiCnM9dC5hKz1ILmQoUC5lUChDLkYzLGEsQy54TSwhMCkpCmlmKGIhPW51bGwmJmIubGVuZ3RoIT09
+MCl7dC5hPXMrIj0iCnQuYSs9SC5kKFAuZVAoQy5GMyxiLEMueE0sITApKX19LAokUzoyMn0KUC55NS5w
+cm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC55KGEpCmlmKGI9PW51bGx8fHR5cGVv
+ZiBiPT0ic3RyaW5nIil0aGlzLmEuJDIoYSxILnkoYikpCmVsc2UgZm9yKHQ9Si5JVCh1LlIuYihiKSks
+cz10aGlzLmE7dC5GKCk7KXMuJDIoYSxILnkodC5nbCgpKSl9LAokUzoxMn0KUC5QRS5wcm90b3R5cGU9
+ewpnbFI6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPXRoaXMsbz1udWxsLG49cC5jCmlmKG4hPW51bGwp
+cmV0dXJuIG4Kbj1wLmIKaWYoMD49bi5sZW5ndGgpcmV0dXJuIEguT0gobiwwKQp0PXAuYQpuPW5bMF0r
+MQpzPUMueEIuWFUodCwiPyIsbikKcj10Lmxlbmd0aAppZihzPj0wKXtxPVAudU8odCxzKzEscixDLlZD
+LCExKQpyPXN9ZWxzZSBxPW8KcmV0dXJuIHAuYz1uZXcgUC5xZSgiZGF0YSIsbyxvLG8sUC51Tyh0LG4s
+cixDLldkLCExKSxxLG8pfSwKdzpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuYgppZigwPj1zLmxlbmd0
+aClyZXR1cm4gSC5PSChzLDApCnQ9dGhpcy5hCnJldHVybiBzWzBdPT09LTE/ImRhdGE6Iit0OnR9fQpQ
+LnEzLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVWludDhBcnJheSg5Nil9LAok
+Uzo0Nn0KUC55SS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZihhPj10
+Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGEpCnQ9dFthXQpKLkNNKHQsMCw5NixiKQpyZXR1cm4gdH0sCiRT
+OjI0fQpQLmM2LnByb3RvdHlwZT17CiQzOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscQpmb3IodD1i
+Lmxlbmd0aCxzPWEubGVuZ3RoLHI9MDtyPHQ7KytyKXtxPUMueEIuVyhiLHIpXjk2CmlmKHE+PXMpcmV0
+dXJuIEguT0goYSxxKQphW3FdPWN9fX0KUC5xZC5wcm90b3R5cGU9ewokMzpmdW5jdGlvbihhLGIsYyl7
+dmFyIHQscyxyLHEKZm9yKHQ9Qy54Qi5XKGIsMCkscz1DLnhCLlcoYiwxKSxyPWEubGVuZ3RoO3Q8PXM7
+Kyt0KXtxPSh0Xjk2KT4+PjAKaWYocT49cilyZXR1cm4gSC5PSChhLHEpCmFbcV09Y319fQpQLlVmLnBy
+b3RvdHlwZT17CmdjajpmdW5jdGlvbigpe3JldHVybiB0aGlzLmM+MH0sCmd4QTpmdW5jdGlvbigpe3Zh
+ciB0LHMKaWYodGhpcy5jPjApe3Q9dGhpcy5kCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQu
+aCgpCnM9dGhpcy5lCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIEgucFkocykKcz10KzE8cwp0
+PXN9ZWxzZSB0PSExCnJldHVybiB0fSwKZ1FEOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5mCmlmKHR5cGVv
+ZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigpCnJldHVybiB0PHRoaXMucn0sCmdaODpmdW5jdGlvbigp
+e3JldHVybiB0aGlzLnI8dGhpcy5hLmxlbmd0aH0sCmdOdzpmdW5jdGlvbigpe3JldHVybiB0aGlzLmI9
+PT00JiZDLnhCLm4odGhpcy5hLCJmaWxlIil9LApndmg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09
+NCYmQy54Qi5uKHRoaXMuYSwiaHR0cCIpfSwKZ3FCOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYj09PTUm
+JkMueEIubih0aGlzLmEsImh0dHBzIil9LApndFQ6ZnVuY3Rpb24oKXtyZXR1cm4gQy54Qi5RaSh0aGlz
+LmEsIi8iLHRoaXMuZSl9LApnRmk6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMscj0icGFja2FnZSIscT1z
+LmIKaWYocTw9MClyZXR1cm4iIgp0PXMueAppZih0IT1udWxsKXJldHVybiB0CmlmKHMuZ3ZoKCkpcT1z
+Lng9Imh0dHAiCmVsc2UgaWYocy5ncUIoKSl7cy54PSJodHRwcyIKcT0iaHR0cHMifWVsc2UgaWYocy5n
+TncoKSl7cy54PSJmaWxlIgpxPSJmaWxlIn1lbHNlIGlmKHE9PT03JiZDLnhCLm4ocy5hLHIpKXtzLng9
+cgpxPXJ9ZWxzZXtxPUMueEIuTmoocy5hLDAscSkKcy54PXF9cmV0dXJuIHF9LApna3U6ZnVuY3Rpb24o
+KXt2YXIgdD10aGlzLmMscz10aGlzLmIrMwpyZXR1cm4gdD5zP0MueEIuTmoodGhpcy5hLHMsdC0xKToi
+In0sCmdKZjpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmMKcmV0dXJuIHQ+MD9DLnhCLk5qKHRoaXMuYSx0
+LHRoaXMuZCk6IiJ9LApndHA6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzCmlmKHMuZ3hBKCkpe3Q9cy5k
+CmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCnJldHVybiBQLlFBKEMueEIuTmoocy5h
+LHQrMSxzLmUpLG51bGwsbnVsbCl9aWYocy5ndmgoKSlyZXR1cm4gODAKaWYocy5ncUIoKSlyZXR1cm4g
+NDQzCnJldHVybiAwfSwKZ0lpOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLk5qKHRoaXMuYSx0aGlzLmUs
+dGhpcy5mKX0sCmd0UDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZixzPXRoaXMucgppZih0eXBlb2YgdCE9
+PSJudW1iZXIiKXJldHVybiB0LkooKQpyZXR1cm4gdDxzP0MueEIuTmoodGhpcy5hLHQrMSxzKToiIn0s
+CmdLYTpmdW5jdGlvbigpe3ZhciB0PXRoaXMucixzPXRoaXMuYQpyZXR1cm4gdDxzLmxlbmd0aD9DLnhC
+Lkcocyx0KzEpOiIifSwKZ0ZqOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRoaXMuZSxxPXRoaXMuZixwPXRo
+aXMuYQppZihDLnhCLlFpKHAsIi8iLHIpKXtpZih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLmgo
+KTsrK3J9aWYocj09cSlyZXR1cm4gQy5kbgp0PUguVk0oW10sdS5zKQpzPXIKd2hpbGUoITApe2lmKHR5
+cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuSigpCmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJu
+IEgucFkocSkKaWYoIShzPHEpKWJyZWFrCmlmKEMueEIubShwLHMpPT09NDcpe0MuTm0uaSh0LEMueEIu
+TmoocCxyLHMpKQpyPXMrMX0rK3N9Qy5ObS5pKHQsQy54Qi5OaihwLHIscSkpCnJldHVybiBQLkFGKHQs
+dS5OKX0sCmdoWTpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJl
+dHVybiB0LkooKQppZih0Pj10aGlzLnIpcmV0dXJuIEMuV08KcmV0dXJuIG5ldyBQLkdqKFAuV1godGhp
+cy5ndFAoKSksdS5UKX0sCmtYOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5kCmlmKHR5cGVvZiBzIT09
+Im51bWJlciIpcmV0dXJuIHMuaCgpCnQ9cysxCnJldHVybiB0K2EubGVuZ3RoPT09dGhpcy5lJiZDLnhC
+LlFpKHRoaXMuYSxhLHQpfSwKTjk6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5yLHI9dC5hCmlmKHM+
+PXIubGVuZ3RoKXJldHVybiB0CnJldHVybiBuZXcgUC5VZihDLnhCLk5qKHIsMCxzKSx0LmIsdC5jLHQu
+ZCx0LmUsdC5mLHMsdC54KX0sCm5tOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGss
+aixpPXRoaXMsaD1udWxsCnUuWC5iKG51bGwpCnUuYi5iKGIpCnQ9aS5nRmkoKQpzPXQ9PT0iZmlsZSIK
+cj1pLmMKcT1yPjA/Qy54Qi5OaihpLmEsaS5iKzMscik6IiIKcD1pLmd4QSgpP2kuZ3RwKGkpOmgKcj1p
+LmMKaWYocj4wKW89Qy54Qi5OaihpLmEscixpLmQpCmVsc2Ugbz1xLmxlbmd0aCE9PTB8fHAhPW51bGx8
+fHM/IiI6aApyPWkuYQpuPWkuZgptPUMueEIuTmoocixpLmUsbikKaWYoIXMpbD1vIT1udWxsJiZtLmxl
+bmd0aCE9PTAKZWxzZSBsPSEwCmlmKGwmJiFDLnhCLm4obSwiLyIpKW09Ii8iK20KaWYoYiE9bnVsbClr
+PVAubGUoaCwwLDAsYikKZWxzZXtsPWkucgppZih0eXBlb2YgbiE9PSJudW1iZXIiKXJldHVybiBuLkoo
+KQprPW48bD9DLnhCLk5qKHIsbisxLGwpOmh9bj1pLnIKaj1uPHIubGVuZ3RoP0MueEIuRyhyLG4rMSk6
+aApyZXR1cm4gbmV3IFAuRG4odCxxLG8scCxtLGssail9LApaSTpmdW5jdGlvbihhKXtyZXR1cm4gdGhp
+cy5tUyhQLmhLKGEpKX0sCm1TOmZ1bmN0aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBQLlVmKXJldHVybiB0
+aGlzLnUxKHRoaXMsYSkKcmV0dXJuIHRoaXMuUmUoKS5tUyhhKX0sCnUxOmZ1bmN0aW9uKGEsYil7dmFy
+IHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGU9Yi5iCmlmKGU+MClyZXR1cm4gYgp0PWIuYwpp
+Zih0PjApe3M9YS5iCmlmKHM8PTApcmV0dXJuIGIKaWYoYS5nTncoKSlyPWIuZSE9Yi5mCmVsc2UgaWYo
+YS5ndmgoKSlyPSFiLmtYKCI4MCIpCmVsc2Ugcj0hYS5ncUIoKXx8IWIua1goIjQ0MyIpCmlmKHIpe3E9
+cysxCnA9Qy54Qi5OaihhLmEsMCxxKStDLnhCLkcoYi5hLGUrMSkKZT1iLmQKaWYodHlwZW9mIGUhPT0i
+bnVtYmVyIilyZXR1cm4gZS5oKCkKbz1iLmUKaWYodHlwZW9mIG8hPT0ibnVtYmVyIilyZXR1cm4gby5o
+KCkKbj1iLmYKaWYodHlwZW9mIG4hPT0ibnVtYmVyIilyZXR1cm4gbi5oKCkKcmV0dXJuIG5ldyBQLlVm
+KHAscyx0K3EsZStxLG8rcSxuK3EsYi5yK3EsYS54KX1lbHNlIHJldHVybiB0aGlzLlJlKCkubVMoYil9
+bT1iLmUKZT1iLmYKaWYobT09ZSl7dD1iLnIKaWYodHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1cm4gZS5K
+KCkKaWYoZTx0KXtzPWEuZgppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkhOKCkKcT1zLWUK
+cmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscykrQy54Qi5HKGIuYSxlKSxhLmIsYS5jLGEuZCxh
+LmUsZStxLHQrcSxhLngpfWU9Yi5hCmlmKHQ8ZS5sZW5ndGgpe3M9YS5yCnJldHVybiBuZXcgUC5VZihD
+LnhCLk5qKGEuYSwwLHMpK0MueEIuRyhlLHQpLGEuYixhLmMsYS5kLGEuZSxhLmYsdCsocy10KSxhLngp
+fXJldHVybiBhLk45KCl9dD1iLmEKaWYoQy54Qi5RaSh0LCIvIixtKSl7cz1hLmUKaWYodHlwZW9mIHMh
+PT0ibnVtYmVyIilyZXR1cm4gcy5ITigpCmlmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIEgucFko
+bSkKcT1zLW0KcD1DLnhCLk5qKGEuYSwwLHMpK0MueEIuRyh0LG0pCmlmKHR5cGVvZiBlIT09Im51bWJl
+ciIpcmV0dXJuIGUuaCgpCnJldHVybiBuZXcgUC5VZihwLGEuYixhLmMsYS5kLHMsZStxLGIucitxLGEu
+eCl9bD1hLmUKaz1hLmYKaWYobD09ayYmYS5jPjApe2Zvcig7Qy54Qi5RaSh0LCIuLi8iLG0pOyl7aWYo
+dHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gbS5oKCkKbSs9M31pZih0eXBlb2YgbCE9PSJudW1iZXIi
+KXJldHVybiBsLkhOKCkKaWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gSC5wWShtKQpxPWwtbSsx
+CnA9Qy54Qi5OaihhLmEsMCxsKSsiLyIrQy54Qi5HKHQsbSkKaWYodHlwZW9mIGUhPT0ibnVtYmVyIily
+ZXR1cm4gZS5oKCkKcmV0dXJuIG5ldyBQLlVmKHAsYS5iLGEuYyxhLmQsbCxlK3EsYi5yK3EsYS54KX1q
+PWEuYQpmb3IoaT1sO0MueEIuUWkoaiwiLi4vIixpKTspe2lmKHR5cGVvZiBpIT09Im51bWJlciIpcmV0
+dXJuIGkuaCgpCmkrPTN9aD0wCndoaWxlKCEwKXtpZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBt
+LmgoKQpnPW0rMwppZih0eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBILnBZKGUpCmlmKCEoZzw9ZSYm
+Qy54Qi5RaSh0LCIuLi8iLG0pKSlicmVhazsrK2gKbT1nfWY9IiIKd2hpbGUoITApe2lmKHR5cGVvZiBr
+IT09Im51bWJlciIpcmV0dXJuIGsub3MoKQppZih0eXBlb2YgaSE9PSJudW1iZXIiKXJldHVybiBILnBZ
+KGkpCmlmKCEoaz5pKSlicmVhazstLWsKaWYoQy54Qi5tKGosayk9PT00Nyl7aWYoaD09PTApe2Y9Ii8i
+CmJyZWFrfS0taApmPSIvIn19aWYoaz09PWkmJmEuYjw9MCYmIUMueEIuUWkoaiwiLyIsbCkpe20tPWgq
+MwpmPSIifXE9ay1tK2YubGVuZ3RoCnJldHVybiBuZXcgUC5VZihDLnhCLk5qKGosMCxrKStmK0MueEIu
+Ryh0LG0pLGEuYixhLmMsYS5kLGwsZStxLGIucitxLGEueCl9LAp0NDpmdW5jdGlvbigpe3ZhciB0LHMs
+cixxLHA9dGhpcwppZihwLmI+PTAmJiFwLmdOdygpKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFj
+dCBhIGZpbGUgcGF0aCBmcm9tIGEgIitILmQocC5nRmkoKSkrIiBVUkkiKSkKdD1wLmYKcz1wLmEKaWYo
+dHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5KKCkKaWYodDxzLmxlbmd0aCl7aWYodDxwLnIpdGhy
+b3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIHF1
+ZXJ5IGNvbXBvbmVudCIpKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGgg
+ZnJvbSBhIFVSSSB3aXRoIGEgZnJhZ21lbnQgY29tcG9uZW50IikpfXI9JC53USgpCmlmKEgub1Qocikp
+dD1QLm1uKHApCmVsc2V7cT1wLmQKaWYodHlwZW9mIHEhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShxKQpp
+ZihwLmM8cSlILnZoKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgbm9uLVdpbmRvd3MgZmlsZSBwYXRoIGZy
+b20gYSBmaWxlIFVSSSB3aXRoIGFuIGF1dGhvcml0eSIpKQp0PUMueEIuTmoocyxwLmUsdCl9cmV0dXJu
+IHR9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy55CnJldHVybiB0PT1udWxsP3RoaXMueT1DLnhC
+LmdpTyh0aGlzLmEpOnR9LApETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJuITEKaWYodGhp
+cz09PWIpcmV0dXJuITAKcmV0dXJuIHUuRC5jKGIpJiZ0aGlzLmE9PT1iLncoMCl9LApSZTpmdW5jdGlv
+bigpe3ZhciB0PXRoaXMscz1udWxsLHI9dC5nRmkoKSxxPXQuZ2t1KCkscD10LmM+MD90LmdKZih0KTpz
+LG89dC5neEEoKT90Lmd0cCh0KTpzLG49dC5hLG09dC5mLGw9Qy54Qi5OaihuLHQuZSxtKSxrPXQucgpp
+Zih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBtLkooKQptPW08az90Lmd0UCgpOnMKcmV0dXJuIG5l
+dyBQLkRuKHIscSxwLG8sbCxtLGs8bi5sZW5ndGg/dC5nS2EoKTpzKX0sCnc6ZnVuY3Rpb24oYSl7cmV0
+dXJuIHRoaXMuYX0sCiRpaUQ6MX0KUC5xZS5wcm90b3R5cGU9e30KVy5xRS5wcm90b3R5cGU9e30KVy5H
+aC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmcoYSl9LAokaUdoOjF9ClcuZlku
+cHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfX0KVy5uQi5wcm90b3R5cGU9
+eyRpbkI6MX0KVy5Bei5wcm90b3R5cGU9eyRpQXo6MX0KVy5RUC5wcm90b3R5cGU9eyRpUVA6MX0KVy5u
+eC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLm9KLnByb3RvdHlw
+ZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19ClcuaWQucHJvdG90eXBlPXt9ClcuUUYu
+cHJvdG90eXBlPXt9ClcuTmgucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEp
+fX0KVy5JQi5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJSZWN0YW5nbGUgKCIrSC5kKGEu
+bGVmdCkrIiwgIitILmQoYS50b3ApKyIpICIrSC5kKGEud2lkdGgpKyIgeCAiK0guZChhLmhlaWdodCl9
+LApETjpmdW5jdGlvbihhLGIpe2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIHUucS5jKGIpJiZhLmxl
+ZnQ9PT1iLmxlZnQmJmEudG9wPT09Yi50b3AmJmEud2lkdGg9PT1iLndpZHRoJiZhLmhlaWdodD09PWIu
+aGVpZ2h0fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBXLnJFKEMuQ0QuZ2lPKGEubGVmdCksQy5DRC5n
+aU8oYS50b3ApLEMuQ0QuZ2lPKGEud2lkdGgpLEMuQ0QuZ2lPKGEuaGVpZ2h0KSl9LAokaXRuOjF9Clcu
+bjcucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy53ei5wcm90b3R5
+cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXt2
+YXIgdApILlNjKGIpCnQ9dGhpcy5hCmlmKGI8MHx8Yj49dC5sZW5ndGgpcmV0dXJuIEguT0godCxiKQpy
+ZXR1cm4gdGhpcy4kdGkuZC5iKHRbYl0pfSwKWTpmdW5jdGlvbihhLGIsYyl7dGhpcy4kdGkuZC5iKGMp
+CnRocm93IEguYihQLkw0KCJDYW5ub3QgbW9kaWZ5IGxpc3QiKSl9fQpXLmN2LnByb3RvdHlwZT17CmdR
+ZzpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuaTcoYSl9LApnRDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3
+IFcuSTQoYSl9LApzRDpmdW5jdGlvbihhLGIpe3ZhciB0CnUuWC5iKGIpCnQ9dGhpcy5nRChhKQp0LlYx
+KDApCnQuRlYoMCxiKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubG9jYWxOYW1lfSwKdG46ZnVuY3Rp
+b24oYSl7dmFyIHQ9ISFhLnNjcm9sbEludG9WaWV3SWZOZWVkZWQKaWYodClhLnNjcm9sbEludG9WaWV3
+SWZOZWVkZWQoKQplbHNlIGEuc2Nyb2xsSW50b1ZpZXcoKX0sCnI2OmZ1bmN0aW9uKGEsYixjLGQpe3Zh
+ciB0LHMscixxCmlmKGM9PW51bGwpe2lmKGQ9PW51bGwpe3Q9JC5sdAppZih0PT1udWxsKXt0PUguVk0o
+W10sdS5rKQpzPW5ldyBXLnZEKHQpCkMuTm0uaSh0LFcuVHcobnVsbCkpCkMuTm0uaSh0LFcuQmwoKSkK
+JC5sdD1zCmQ9c31lbHNlIGQ9dH10PSQuRVUKaWYodD09bnVsbCl7dD1uZXcgVy5LbyhkKQokLkVVPXQK
+Yz10fWVsc2V7dC5hPWQKYz10fX1lbHNlIGlmKGQhPW51bGwpdGhyb3cgSC5iKFAueFkoInZhbGlkYXRv
+ciBjYW4gb25seSBiZSBwYXNzZWQgaWYgdHJlZVNhbml0aXplciBpcyBudWxsIikpCmlmKCQueG89PW51
+bGwpe3Q9ZG9jdW1lbnQKcz10LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudCgiIikKJC54
+bz1zCiQuQk89cy5jcmVhdGVSYW5nZSgpCnM9JC54by5jcmVhdGVFbGVtZW50KCJiYXNlIikKdS5jUi5i
+KHMpCnMuaHJlZj10LmJhc2VVUkkKJC54by5oZWFkLmFwcGVuZENoaWxkKHMpfXQ9JC54bwppZih0LmJv
+ZHk9PW51bGwpe3M9dC5jcmVhdGVFbGVtZW50KCJib2R5IikKdC5ib2R5PXUuWS5iKHMpfXQ9JC54bwpp
+Zih1LlkuYyhhKSlyPXQuYm9keQplbHNle3I9dC5jcmVhdGVFbGVtZW50KGEudGFnTmFtZSkKJC54by5i
+b2R5LmFwcGVuZENoaWxkKHIpfWlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5S
+YW5nZS5wcm90b3R5cGUmJiFDLk5tLnRnKEMuU3EsYS50YWdOYW1lKSl7JC5CTy5zZWxlY3ROb2RlQ29u
+dGVudHMocikKcT0kLkJPLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChiKX1lbHNle3IuaW5uZXJIVE1M
+PWIKcT0kLnhvLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpmb3IoO3Q9ci5maXJzdENoaWxkLHQhPW51
+bGw7KXEuYXBwZW5kQ2hpbGQodCl9dD0kLnhvLmJvZHkKaWYocj09bnVsbD90IT1udWxsOnIhPT10KUou
+THQocikKYy5QbihxKQpkb2N1bWVudC5hZG9wdE5vZGUocSkKcmV0dXJuIHF9LApBSDpmdW5jdGlvbihh
+LGIsYyl7cmV0dXJuIHRoaXMucjYoYSxiLGMsbnVsbCl9LApzaGY6ZnVuY3Rpb24oYSxiKXt0aGlzLllD
+KGEsYil9LApwazpmdW5jdGlvbihhLGIsYyl7YS50ZXh0Q29udGVudD1udWxsCmEuYXBwZW5kQ2hpbGQo
+dGhpcy5yNihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnBrKGEsYixu
+dWxsKX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuQ3EoYSwiY2xpY2siLCExLHUuUSl9LAok
+aWN2OjEsCmduczpmdW5jdGlvbihhKXtyZXR1cm4gYS50YWdOYW1lfX0KVy5Ddi5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXtyZXR1cm4gdS5oLmModS5BLmIoYSkpfSwKJFM6MjV9ClcuZWEucHJvdG90eXBl
+PXskaWVhOjF9ClcuRDAucHJvdG90eXBlPXsKT246ZnVuY3Rpb24oYSxiLGMsZCl7dS5VLmIoYykKaWYo
+YyE9bnVsbCl0aGlzLnYoYSxiLGMsZCl9LApCOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gdGhpcy5Pbihh
+LGIsYyxudWxsKX0sCnY6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIGEuYWRkRXZlbnRMaXN0ZW5lcihi
+LEgudFIodS5VLmIoYyksMSksZCl9LAokaUQwOjF9ClcuVDUucHJvdG90eXBlPXskaVQ1OjF9ClcuaDQu
+cHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5ici5wcm90b3R5cGU9
+ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLlZiLnByb3RvdHlwZT17fQpXLk83LnBy
+b3RvdHlwZT17CmVvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBhLm9wZW4oYixjLCEwKX0sCiRpTzc6
+MX0KVy5iVS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYS5zZXRSZXF1ZXN0SGVhZGVy
+KEgueShhKSxILnkoYikpfSwKJFM6MTB9ClcuaEgucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFy
+IHQscyxyLHEscAp1LnAuYihhKQp0PXRoaXMuYQpzPXQuc3RhdHVzCmlmKHR5cGVvZiBzIT09Im51bWJl
+ciIpcmV0dXJuIHMudEIoKQpyPXM+PTIwMCYmczwzMDAKcT1zPjMwNyYmczw0MDAKcz1yfHxzPT09MHx8
+cz09PTMwNHx8cQpwPXRoaXMuYgppZihzKXAuYU0oMCx0KQplbHNlIHAucG0oYSl9LAokUzoyN30KVy53
+YS5wcm90b3R5cGU9e30KVy5TZy5wcm90b3R5cGU9eyRpU2c6MX0KVy51OC5wcm90b3R5cGU9ewpnRHI6
+ZnVuY3Rpb24oYSl7aWYoIm9yaWdpbiIgaW4gYSlyZXR1cm4gYS5vcmlnaW4KcmV0dXJuIEguZChhLnBy
+b3RvY29sKSsiLy8iK0guZChhLmhvc3QpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gU3RyaW5nKGEpfSwK
+JGl1ODoxfQpXLkFqLnByb3RvdHlwZT17JGlBajoxfQpXLmU3LnByb3RvdHlwZT17CmdyODpmdW5jdGlv
+bihhKXt2YXIgdD10aGlzLmEscz10LmNoaWxkTm9kZXMubGVuZ3RoCmlmKHM9PT0wKXRocm93IEguYihQ
+LlBWKCJObyBlbGVtZW50cyIpKQppZihzPjEpdGhyb3cgSC5iKFAuUFYoIk1vcmUgdGhhbiBvbmUgZWxl
+bWVudCIpKQpyZXR1cm4gdC5maXJzdENoaWxkfSwKRlY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1
+LmVoLmIoYikKdD1iLmEKcz10aGlzLmEKaWYodCE9PXMpZm9yKHI9dC5jaGlsZE5vZGVzLmxlbmd0aCxx
+PTA7cTxyOysrcSlzLmFwcGVuZENoaWxkKHQuZmlyc3RDaGlsZCkKcmV0dXJufSwKWTpmdW5jdGlvbihh
+LGIsYyl7dmFyIHQscwp1LkEuYihjKQp0PXRoaXMuYQpzPXQuY2hpbGROb2RlcwppZihiPDB8fGI+PXMu
+bGVuZ3RoKXJldHVybiBILk9IKHMsYikKdC5yZXBsYWNlQ2hpbGQoYyxzW2JdKX0sCmdrejpmdW5jdGlv
+bihhKXt2YXIgdD10aGlzLmEuY2hpbGROb2RlcwpyZXR1cm4gbmV3IFcuVzkodCx0Lmxlbmd0aCxILnpL
+KHQpLkMoIlc5PEdtLkU+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5jaGlsZE5vZGVz
+Lmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILlNjKGIpCnQ9dGhpcy5hLmNoaWxkTm9kZXMK
+aWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGIpCnJldHVybiB0W2JdfX0KVy51SC5wcm90
+b3R5cGU9ewp3ZzpmdW5jdGlvbihhKXt2YXIgdD1hLnBhcmVudE5vZGUKaWYodCE9bnVsbCl0LnJlbW92
+ZUNoaWxkKGEpfSwKRDQ6ZnVuY3Rpb24oYSl7dmFyIHQKZm9yKDt0PWEuZmlyc3RDaGlsZCx0IT1udWxs
+OylhLnJlbW92ZUNoaWxkKHQpfSwKdzpmdW5jdGlvbihhKXt2YXIgdD1hLm5vZGVWYWx1ZQpyZXR1cm4g
+dD09bnVsbD90aGlzLlUoYSk6dH0sCiRpdUg6MX0KVy5CSC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihh
+KXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj4+MCE9PWJ8fGI+
+PWEubGVuZ3RoKXRocm93IEguYihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwK
+WTpmdW5jdGlvbihhLGIsYyl7dS5BLmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxl
+bWVudCBvZiBpbW11dGFibGUgTGlzdC4iKSl9LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxl
+bmd0aClyZXR1cm4gSC5PSChhLGIpCnJldHVybiBhW2JdfSwKJGlYajoxLAokaWNYOjEsCiRpek06MX0K
+Vy5TTi5wcm90b3R5cGU9e30KVy5ldy5wcm90b3R5cGU9eyRpZXc6MX0KVy5scC5wcm90b3R5cGU9ewpn
+QTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLlRiLnByb3RvdHlwZT17CnI2OmZ1bmN0aW9u
+KGEsYixjLGQpe3ZhciB0LHMKaWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93LlJh
+bmdlLnByb3RvdHlwZSlyZXR1cm4gdGhpcy5EVyhhLGIsYyxkKQp0PVcuVTkoIjx0YWJsZT4iK0guZChi
+KSsiPC90YWJsZT4iLGMsZCkKcz1kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkKcy50b1N0
+cmluZwp0LnRvU3RyaW5nCm5ldyBXLmU3KHMpLkZWKDAsbmV3IFcuZTcodCkpCnJldHVybiBzfX0KVy5J
+di5wcm90b3R5cGU9ewpyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscQppZigiY3JlYXRlQ29u
+dGV4dHVhbEZyYWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEs
+YixjLGQpCnQ9ZG9jdW1lbnQKcz10LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQp0PUMuSWUucjYodC5j
+cmVhdGVFbGVtZW50KCJ0YWJsZSIpLGIsYyxkKQp0LnRvU3RyaW5nCnQ9bmV3IFcuZTcodCkKcj10Lmdy
+OCh0KQpyLnRvU3RyaW5nCnQ9bmV3IFcuZTcocikKcT10LmdyOCh0KQpzLnRvU3RyaW5nCnEudG9TdHJp
+bmcKbmV3IFcuZTcocykuRlYoMCxuZXcgVy5lNyhxKSkKcmV0dXJuIHN9fQpXLkJULnByb3RvdHlwZT17
+CnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscgppZigiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50
+IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnQ9ZG9jdW1l
+bnQKcz10LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQp0PUMuSWUucjYodC5jcmVhdGVFbGVtZW50KCJ0
+YWJsZSIpLGIsYyxkKQp0LnRvU3RyaW5nCnQ9bmV3IFcuZTcodCkKcj10LmdyOCh0KQpzLnRvU3RyaW5n
+CnIudG9TdHJpbmcKbmV3IFcuZTcocykuRlYoMCxuZXcgVy5lNyhyKSkKcmV0dXJuIHN9fQpXLnlZLnBy
+b3RvdHlwZT17CnBrOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzCmEudGV4dENvbnRlbnQ9bnVsbAp0PWEu
+Y29udGVudAp0LnRvU3RyaW5nCkouYlQodCkKcz10aGlzLnI2KGEsYixudWxsLGMpCmEuY29udGVudC5h
+cHBlbmRDaGlsZChzKX0sCllDOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucGsoYSxiLG51bGwpfSwK
+JGl5WToxfQpXLnc2LnByb3RvdHlwZT17fQpXLks1LnByb3RvdHlwZT17CmdtVzpmdW5jdGlvbihhKXty
+ZXR1cm4gYS5sb2NhdGlvbn0sCiRpSzU6MSwKJGl2NjoxfQpXLkNtLnByb3RvdHlwZT17JGlDbToxfQpX
+LkNRLnByb3RvdHlwZT17JGlDUToxfQpXLnc0LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IlJlY3RhbmdsZSAoIitILmQoYS5sZWZ0KSsiLCAiK0guZChhLnRvcCkrIikgIitILmQoYS53aWR0aCkr
+IiB4ICIrSC5kKGEuaGVpZ2h0KX0sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpy
+ZXR1cm4gdS5xLmMoYikmJmEubGVmdD09PWIubGVmdCYmYS50b3A9PT1iLnRvcCYmYS53aWR0aD09PWIu
+d2lkdGgmJmEuaGVpZ2h0PT09Yi5oZWlnaHR9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIFcuckUoQy5D
+RC5naU8oYS5sZWZ0KSxDLkNELmdpTyhhLnRvcCksQy5DRC5naU8oYS53aWR0aCksQy5DRC5naU8oYS5o
+ZWlnaHQpKX19ClcucmgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwK
+cTpmdW5jdGlvbihhLGIpe0guU2MoYikKaWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIo
+UC5DZihiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe3Uu
+QS5iKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgYXNzaWduIGVsZW1lbnQgb2YgaW1tdXRhYmxlIExp
+c3QuIikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49YS5sZW5ndGgpcmV0dXJuIEguT0goYSxi
+KQpyZXR1cm4gYVtiXX0sCiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuY2YucHJvdG90eXBlPXsKSzpm
+dW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAKdS5FLmIoYikKZm9yKHQ9dGhpcy5nVigpLHM9dC5sZW5n
+dGgscj10aGlzLmEscT0wO3E8dC5sZW5ndGg7dC5sZW5ndGg9PT1zfHwoMCxILmxrKSh0KSwrK3Epe3A9
+dFtxXQpiLiQyKHAsci5nZXRBdHRyaWJ1dGUocCkpfX0sCmdWOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEs
+cD10aGlzLmEuYXR0cmlidXRlcyxvPUguVk0oW10sdS5zKQpmb3IodD1wLmxlbmd0aCxzPXUuaDkscj0w
+O3I8dDsrK3Ipe2lmKHI+PXAubGVuZ3RoKXJldHVybiBILk9IKHAscikKcT1zLmIocFtyXSkKaWYocS5u
+YW1lc3BhY2VVUkk9PW51bGwpQy5ObS5pKG8scS5uYW1lKX1yZXR1cm4gb319ClcuaTcucHJvdG90eXBl
+PXsKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEuZ2V0QXR0cmlidXRlKEgueShiKSl9LApZOmZ1
+bmN0aW9uKGEsYixjKXt0aGlzLmEuc2V0QXR0cmlidXRlKGIsYyl9LApnQTpmdW5jdGlvbihhKXtyZXR1
+cm4gdGhpcy5nVigpLmxlbmd0aH19ClcuU3kucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe3JldHVy
+biB0aGlzLmEuYS5nZXRBdHRyaWJ1dGUoImRhdGEtIit0aGlzLk8oSC55KGIpKSl9LApZOmZ1bmN0aW9u
+KGEsYixjKXt0aGlzLmEuYS5zZXRBdHRyaWJ1dGUoImRhdGEtIit0aGlzLk8oYiksYyl9LApLOmZ1bmN0
+aW9uKGEsYil7dGhpcy5hLksoMCxuZXcgVy5LUyh0aGlzLHUuRS5iKGIpKSl9LApnVjpmdW5jdGlvbigp
+e3ZhciB0PUguVk0oW10sdS5zKQp0aGlzLmEuSygwLG5ldyBXLkEzKHRoaXMsdCkpCnJldHVybiB0fSwK
+Z0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGh9LAprOmZ1bmN0aW9uKGEpe3ZhciB0
+LHMscj1ILlZNKGEuc3BsaXQoIi0iKSx1LnMpCmZvcih0PTE7dDxyLmxlbmd0aDsrK3Qpe3M9clt0XQpp
+ZihzLmxlbmd0aD4wKUMuTm0uWShyLHQsc1swXS50b1VwcGVyQ2FzZSgpK0ouS1YocywxKSl9cmV0dXJu
+IEMuTm0uSChyLCIiKX0sCk86ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscApmb3IodD1hLmxlbmd0aCxz
+PTAscj0iIjtzPHQ7KytzKXtxPWFbc10KcD1xLnRvTG93ZXJDYXNlKCkKcj0ocSE9PXAmJnM+MD9yKyIt
+IjpyKStwfXJldHVybiByLmNoYXJDb2RlQXQoMCk9PTA/cjpyfX0KVy5LUy5wcm90b3R5cGU9ewokMjpm
+dW5jdGlvbihhLGIpe2lmKEouclkoYSkubihhLCJkYXRhLSIpKXRoaXMuYi4kMih0aGlzLmEuayhDLnhC
+LkcoYSw1KSksYil9LAokUzoxMH0KVy5BMy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe2lmKEou
+clkoYSkubihhLCJkYXRhLSIpKUMuTm0uaSh0aGlzLmIsdGhpcy5hLmsoQy54Qi5HKGEsNSkpKX0sCiRT
+OjEwfQpXLkk0LnByb3RvdHlwZT17ClA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPVAuTHModS5OKQpm
+b3IodD10aGlzLmEuY2xhc3NOYW1lLnNwbGl0KCIgIikscz10Lmxlbmd0aCxyPTA7cjxzOysrcil7cT1K
+LlQwKHRbcl0pCmlmKHEubGVuZ3RoIT09MClwLmkoMCxxKX1yZXR1cm4gcH0sClg6ZnVuY3Rpb24oYSl7
+dGhpcy5hLmNsYXNzTmFtZT11LkMuYihhKS5IKDAsIiAiKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0
+aGlzLmEuY2xhc3NMaXN0Lmxlbmd0aH0sClYxOmZ1bmN0aW9uKGEpe3RoaXMuYS5jbGFzc05hbWU9IiJ9
+LAp0ZzpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYS5jbGFzc0xpc3QuY29udGFpbnMoYikKcmV0dXJu
+IHR9LAppOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5hLmNsYXNzTGlzdCxzPXQuY29udGFpbnMoYikK
+dC5hZGQoYikKcmV0dXJuIXN9LApSOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5hLmNsYXNzTGlzdCxz
+PXQuY29udGFpbnMoYikKdC5yZW1vdmUoYikKcmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe1cuVE4o
+dGhpcy5hLHUuWC5iKGIpKX19ClcuRmsucHJvdG90eXBlPXt9ClcuUk8ucHJvdG90eXBlPXt9ClcuQ3Eu
+cHJvdG90eXBlPXt9ClcueEMucHJvdG90eXBlPXt9Clcudk4ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7cmV0dXJuIHRoaXMuYS4kMSh1LkIuYihhKSl9LAokUzoyOH0KVy5KUS5wcm90b3R5cGU9ewpDWTpm
+dW5jdGlvbihhKXt2YXIgdAppZigkLm9yLmE9PT0wKXtmb3IodD0wO3Q8MjYyOysrdCkkLm9yLlkoMCxD
+LmNtW3RdLFcucFMoKSkKZm9yKHQ9MDt0PDEyOysrdCkkLm9yLlkoMCxDLkJJW3RdLFcuVjQoKSl9fSwK
+aTA6ZnVuY3Rpb24oYSl7cmV0dXJuICQuQU4oKS50ZygwLFcuclMoYSkpfSwKRWI6ZnVuY3Rpb24oYSxi
+LGMpe3ZhciB0PSQub3IucSgwLEguZChXLnJTKGEpKSsiOjoiK2IpCmlmKHQ9PW51bGwpdD0kLm9yLnEo
+MCwiKjo6IitiKQppZih0PT1udWxsKXJldHVybiExCnJldHVybiBILnhkKHQuJDQoYSxiLGMsdGhpcykp
+fSwKJGlrRjoxfQpXLkdtLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuVzko
+YSx0aGlzLmdBKGEpLEgueksoYSkuQygiVzk8R20uRT4iKSl9fQpXLnZELnByb3RvdHlwZT17CmkwOmZ1
+bmN0aW9uKGEpe3JldHVybiBDLk5tLlZyKHRoaXMuYSxuZXcgVy5VdihhKSl9LApFYjpmdW5jdGlvbihh
+LGIsYyl7cmV0dXJuIEMuTm0uVnIodGhpcy5hLG5ldyBXLkVnKGEsYixjKSl9LAokaWtGOjF9ClcuVXYu
+cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUuZS5iKGEpLmkwKHRoaXMuYSl9LAokUzox
+N30KVy5FZy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5lLmIoYSkuRWIodGhpcy5h
+LHRoaXMuYix0aGlzLmMpfSwKJFM6MTd9ClcubTYucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiLGMs
+ZCl7dmFyIHQscyxyCnRoaXMuYS5GVigwLGMpCnQ9Yi5ldigwLG5ldyBXLkVvKCkpCnM9Yi5ldigwLG5l
+dyBXLldrKCkpCnRoaXMuYi5GVigwLHQpCnI9dGhpcy5jCnIuRlYoMCxDLmRuKQpyLkZWKDAscyl9LApp
+MDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLnRnKDAsVy5yUyhhKSl9LApFYjpmdW5jdGlvbihhLGIs
+Yyl7dmFyIHQ9dGhpcyxzPVcuclMoYSkscj10LmMKaWYoci50ZygwLEguZChzKSsiOjoiK2IpKXJldHVy
+biB0LmQuRHQoYykKZWxzZSBpZihyLnRnKDAsIio6OiIrYikpcmV0dXJuIHQuZC5EdChjKQplbHNle3I9
+dC5iCmlmKHIudGcoMCxILmQocykrIjo6IitiKSlyZXR1cm4hMAplbHNlIGlmKHIudGcoMCwiKjo6Iiti
+KSlyZXR1cm4hMAplbHNlIGlmKHIudGcoMCxILmQocykrIjo6KiIpKXJldHVybiEwCmVsc2UgaWYoci50
+ZygwLCIqOjoqIikpcmV0dXJuITB9cmV0dXJuITF9LAokaWtGOjF9ClcuRW8ucHJvdG90eXBlPXsKJDE6
+ZnVuY3Rpb24oYSl7cmV0dXJuIUMuTm0udGcoQy5CSSxILnkoYSkpfSwKJFM6OH0KVy5Xay5wcm90b3R5
+cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gQy5ObS50ZyhDLkJJLEgueShhKSl9LAokUzo4fQpXLmN0
+LnByb3RvdHlwZT17CkViOmZ1bmN0aW9uKGEsYixjKXtpZih0aGlzLmpGKGEsYixjKSlyZXR1cm4hMApp
+ZihiPT09InRlbXBsYXRlIiYmYz09PSIiKXJldHVybiEwCmlmKGEuZ2V0QXR0cmlidXRlKCJ0ZW1wbGF0
+ZSIpPT09IiIpcmV0dXJuIHRoaXMuZS50ZygwLGIpCnJldHVybiExfX0KVy5JQS5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXtyZXR1cm4iVEVNUExBVEU6OiIrSC5kKEgueShhKSl9LAokUzo1fQpXLk93LnBy
+b3RvdHlwZT17CmkwOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKHUuZXcuYyhhKSlyZXR1cm4hMQp0PXUuZzcu
+YyhhKQppZih0JiZXLnJTKGEpPT09ImZvcmVpZ25PYmplY3QiKXJldHVybiExCmlmKHQpcmV0dXJuITAK
+cmV0dXJuITF9LApFYjpmdW5jdGlvbihhLGIsYyl7aWYoYj09PSJpcyJ8fEMueEIubihiLCJvbiIpKXJl
+dHVybiExCnJldHVybiB0aGlzLmkwKGEpfSwKJGlrRjoxfQpXLlc5LnByb3RvdHlwZT17CkY6ZnVuY3Rp
+b24oKXt2YXIgdD10aGlzLHM9dC5jKzEscj10LmIKaWYoczxyKXt0LnNwKEoudzIodC5hLHMpKQp0LmM9
+cwpyZXR1cm4hMH10LnNwKG51bGwpCnQuYz1yCnJldHVybiExfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4g
+dGhpcy5kfSwKc3A6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0sCiRpQW46MX0KVy5k
+Vy5wcm90b3R5cGU9ewpnbVc6ZnVuY3Rpb24oYSl7cmV0dXJuIFcuelgodGhpcy5hLmxvY2F0aW9uKX0s
+CiRpRDA6MSwKJGl2NjoxfQpXLkZiLnByb3RvdHlwZT17fQpXLmtGLnByb3RvdHlwZT17fQpXLm1rLnBy
+b3RvdHlwZT17JGl5MDoxfQpXLktvLnByb3RvdHlwZT17ClBuOmZ1bmN0aW9uKGEpe25ldyBXLmZtKHRo
+aXMpLiQyKGEsbnVsbCl9LApFUDpmdW5jdGlvbihhLGIpe2lmKGI9PW51bGwpSi5MdChhKQplbHNlIGIu
+cmVtb3ZlQ2hpbGQoYSl9LApJNDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz0hMCxuPW51bGws
+bT1udWxsCnRyeXtuPUouaWcoYSkKbT1uLmEuZ2V0QXR0cmlidXRlKCJpcyIpCnUuaC5iKGEpCnQ9ZnVu
+Y3Rpb24oYyl7aWYoIShjLmF0dHJpYnV0ZXMgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXApKXJldHVybiB0
+cnVlCnZhciBsPWMuY2hpbGROb2RlcwppZihjLmxhc3RDaGlsZCYmYy5sYXN0Q2hpbGQhPT1sW2wubGVu
+Z3RoLTFdKXJldHVybiB0cnVlCmlmKGMuY2hpbGRyZW4paWYoIShjLmNoaWxkcmVuIGluc3RhbmNlb2Yg
+SFRNTENvbGxlY3Rpb258fGMuY2hpbGRyZW4gaW5zdGFuY2VvZiBOb2RlTGlzdCkpcmV0dXJuIHRydWUK
+dmFyIGs9MAppZihjLmNoaWxkcmVuKWs9Yy5jaGlsZHJlbi5sZW5ndGgKZm9yKHZhciBqPTA7ajxrO2or
+Kyl7dmFyIGk9Yy5jaGlsZHJlbltqXQppZihpLmlkPT0nYXR0cmlidXRlcyd8fGkubmFtZT09J2F0dHJp
+YnV0ZXMnfHxpLmlkPT0nbGFzdENoaWxkJ3x8aS5uYW1lPT0nbGFzdENoaWxkJ3x8aS5pZD09J2NoaWxk
+cmVuJ3x8aS5uYW1lPT0nY2hpbGRyZW4nKXJldHVybiB0cnVlfXJldHVybiBmYWxzZX0oYSkKbz1ILm9U
+KHQpPyEwOiEoYS5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKX1jYXRjaChxKXtILlJ1
+KHEpfXM9ImVsZW1lbnQgdW5wcmludGFibGUiCnRyeXtzPUouaihhKX1jYXRjaChxKXtILlJ1KHEpfXRy
+eXtyPVcuclMoYSkKdGhpcy5rUih1LmguYihhKSxiLG8scyxyLHUuRy5iKG4pLEgueShtKSl9Y2F0Y2go
+cSl7aWYoSC5SdShxKSBpbnN0YW5jZW9mIFAudSl0aHJvdyBxCmVsc2V7dGhpcy5FUChhLGIpCndpbmRv
+dwpwPSJSZW1vdmluZyBjb3JydXB0ZWQgZWxlbWVudCAiK0guZChzKQppZih0eXBlb2YgY29uc29sZSE9
+InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihwKX19fSwKa1I6ZnVuY3Rpb24oYSxiLGMsZCxl
+LGYsZyl7dmFyIHQscyxyLHEscCxvLG49dGhpcwppZihjKXtuLkVQKGEsYikKd2luZG93CnQ9IlJlbW92
+aW5nIGVsZW1lbnQgZHVlIHRvIGNvcnJ1cHRlZCBhdHRyaWJ1dGVzIG9uIDwiK2QrIj4iCmlmKHR5cGVv
+ZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHQpCnJldHVybn1pZighbi5h
+LmkwKGEpKXtuLkVQKGEsYikKd2luZG93CnQ9IlJlbW92aW5nIGRpc2FsbG93ZWQgZWxlbWVudCA8IitI
+LmQoZSkrIj4gZnJvbSAiK0guZChiKQppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93
+LmNvbnNvbGUud2Fybih0KQpyZXR1cm59aWYoZyE9bnVsbClpZighbi5hLkViKGEsImlzIixnKSl7bi5F
+UChhLGIpCndpbmRvdwp0PSJSZW1vdmluZyBkaXNhbGxvd2VkIHR5cGUgZXh0ZW5zaW9uIDwiK0guZChl
+KSsnIGlzPSInK2crJyI+JwppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNv
+bGUud2Fybih0KQpyZXR1cm59dD1mLmdWKCkKcz1ILlZNKHQuc2xpY2UoMCksSC50Nih0KS5DKCJqZDwx
+PiIpKQpmb3Iocj1mLmdWKCkubGVuZ3RoLTEsdD1mLmE7cj49MDstLXIpe2lmKHI+PXMubGVuZ3RoKXJl
+dHVybiBILk9IKHMscikKcT1zW3JdCnA9bi5hCm89Si5jSChxKQpILnkocSkKaWYoIXAuRWIoYSxvLHQu
+Z2V0QXR0cmlidXRlKHEpKSl7d2luZG93CnA9IlJlbW92aW5nIGRpc2FsbG93ZWQgYXR0cmlidXRlIDwi
+K0guZChlKSsiICIrcSsnPSInK0guZCh0LmdldEF0dHJpYnV0ZShxKSkrJyI+JwppZih0eXBlb2YgY29u
+c29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUud2FybihwKQp0LnJlbW92ZUF0dHJpYnV0ZShx
+KX19aWYodS5hVy5jKGEpKW4uUG4oYS5jb250ZW50KX0sCiRpb246MX0KVy5mbS5wcm90b3R5cGU9ewok
+MjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9dGhpcy5hCnN3aXRjaChhLm5vZGVUeXBlKXtjYXNl
+IDE6cC5JNChhLGIpCmJyZWFrCmNhc2UgODpjYXNlIDExOmNhc2UgMzpjYXNlIDQ6YnJlYWsKZGVmYXVs
+dDpwLkVQKGEsYil9dD1hLmxhc3RDaGlsZApmb3IocD11LkE7bnVsbCE9dDspe3M9bnVsbAp0cnl7cz10
+LnByZXZpb3VzU2libGluZ31jYXRjaChyKXtILlJ1KHIpCnE9cC5iKHQpCmEucmVtb3ZlQ2hpbGQocSkK
+dD1udWxsCnM9YS5sYXN0Q2hpbGR9aWYodCE9bnVsbCl0aGlzLiQyKHQsYSkKdD1wLmIocyl9fSwKJFM6
+MzF9ClcuTGUucHJvdG90eXBlPXt9ClcuSzcucHJvdG90eXBlPXt9ClcuckIucHJvdG90eXBlPXt9Clcu
+WFcucHJvdG90eXBlPXt9Clcub2EucHJvdG90eXBlPXt9ClAuaUoucHJvdG90eXBlPXsKVkg6ZnVuY3Rp
+b24oYSl7dmFyIHQscz10aGlzLmEscj1zLmxlbmd0aApmb3IodD0wO3Q8cjsrK3QpaWYoc1t0XT09PWEp
+cmV0dXJuIHQKQy5ObS5pKHMsYSkKQy5ObS5pKHRoaXMuYixudWxsKQpyZXR1cm4gcn0sClB2OmZ1bmN0
+aW9uKGEpe3ZhciB0LHMscixxPXRoaXMscD17fQppZihhPT1udWxsKXJldHVybiBhCmlmKEgubChhKSly
+ZXR1cm4gYQppZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJzdHJpbmci
+KXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBuZXcgRGF0ZShhLmEpCmlmKHUuZnYu
+YyhhKSl0aHJvdyBILmIoUC5TWSgic3RydWN0dXJlZCBjbG9uZSBvZiBSZWdFeHAiKSkKaWYodS5jOC5j
+KGEpKXJldHVybiBhCmlmKHUuZC5jKGEpKXJldHVybiBhCmlmKHUuSS5jKGEpKXJldHVybiBhCnQ9dS5k
+RC5jKGEpfHwhMQppZih0KXJldHVybiBhCmlmKHUuRy5jKGEpKXtzPXEuVkgoYSkKdD1xLmIKaWYocz49
+dC5sZW5ndGgpcmV0dXJuIEguT0godCxzKQpyPXAuYT10W3NdCmlmKHIhPW51bGwpcmV0dXJuIHIKcj17
+fQpwLmE9cgpDLk5tLlkodCxzLHIpCmEuSygwLG5ldyBQLmxSKHAscSkpCnJldHVybiBwLmF9aWYodS5q
+LmMoYSkpe3M9cS5WSChhKQpwPXEuYgppZihzPj1wLmxlbmd0aClyZXR1cm4gSC5PSChwLHMpCnI9cFtz
+XQppZihyIT1udWxsKXJldHVybiByCnJldHVybiBxLmVrKGEscyl9aWYodS5lSC5jKGEpKXtzPXEuVkgo
+YSkKdD1xLmIKaWYocz49dC5sZW5ndGgpcmV0dXJuIEguT0godCxzKQpyPXAuYj10W3NdCmlmKHIhPW51
+bGwpcmV0dXJuIHIKcj17fQpwLmI9cgpDLk5tLlkodCxzLHIpCnEuaW0oYSxuZXcgUC5qZyhwLHEpKQpy
+ZXR1cm4gcC5ifXRocm93IEguYihQLlNZKCJzdHJ1Y3R1cmVkIGNsb25lIG9mIG90aGVyIHR5cGUiKSl9
+LAplazpmdW5jdGlvbihhLGIpe3ZhciB0LHM9Si5VNihhKSxyPXMuZ0EoYSkscT1uZXcgQXJyYXkocikK
+Qy5ObS5ZKHRoaXMuYixiLHEpCmZvcih0PTA7dDxyOysrdClDLk5tLlkocSx0LHRoaXMuUHYocy5xKGEs
+dCkpKQpyZXR1cm4gcX19ClAubFIucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuYVth
+XT10aGlzLmIuUHYoYil9LAokUzoxfQpQLmpnLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dGhp
+cy5hLmJbYV09dGhpcy5iLlB2KGIpfSwKJFM6MX0KUC5CZi5wcm90b3R5cGU9ewppbTpmdW5jdGlvbihh
+LGIpe3ZhciB0LHMscixxCnUuYjguYihiKQpmb3IodD1PYmplY3Qua2V5cyhhKSxzPXQubGVuZ3RoLHI9
+MDtyPHM7KytyKXtxPXRbcl0KYi4kMihxLGFbcV0pfX19ClAuQXMucHJvdG90eXBlPXsKVDpmdW5jdGlv
+bihhKXt2YXIgdApILnkoYSkKdD0kLmhHKCkuYgppZih0eXBlb2YgYSE9InN0cmluZyIpSC52aChILnRM
+KGEpKQppZih0LnRlc3QoYSkpcmV0dXJuIGEKdGhyb3cgSC5iKFAuTDMoYSwidmFsdWUiLCJOb3QgYSB2
+YWxpZCBjbGFzcyB0b2tlbiIpKX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuUCgpLkgoMCwiICIp
+fSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuUCgpCnJldHVybiBQLnJqKHQsdC5yLEguTGgodCku
+ZCl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5QKCkuYX0sCnRnOmZ1bmN0aW9uKGEsYil7dGhp
+cy5UKGIpCnJldHVybiB0aGlzLlAoKS50ZygwLGIpfSwKaTpmdW5jdGlvbihhLGIpe3RoaXMuVChiKQpy
+ZXR1cm4gSC54ZCh0aGlzLk9TKG5ldyBQLkdFKGIpKSl9LApSOmZ1bmN0aW9uKGEsYil7dmFyIHQscwp0
+aGlzLlQoYikKdD10aGlzLlAoKQpzPXQuUigwLGIpCnRoaXMuWCh0KQpyZXR1cm4gc30sCkZWOmZ1bmN0
+aW9uKGEsYil7dGhpcy5PUyhuZXcgUC5ONyh0aGlzLHUuWC5iKGIpKSl9LApWMTpmdW5jdGlvbihhKXt0
+aGlzLk9TKG5ldyBQLnVRKCkpfSwKT1M6ZnVuY3Rpb24oYSl7dmFyIHQscwp1LmNoLmIoYSkKdD10aGlz
+LlAoKQpzPWEuJDEodCkKdGhpcy5YKHQpCnJldHVybiBzfX0KUC5HRS5wcm90b3R5cGU9ewokMTpmdW5j
+dGlvbihhKXtyZXR1cm4gdS5DLmIoYSkuaSgwLHRoaXMuYSl9LAokUzo0NX0KUC5ONy5wcm90b3R5cGU9
+ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmIscz1ILnQ2KHQpCnJldHVybiB1LkMuYihhKS5GVigw
+LG5ldyBILkE4KHQscy5DKCJxVSgxKSIpLmIodGhpcy5hLmd1TSgpKSxzLkMoIkE4PDEscVU+IikpKX0s
+CiRTOjE0fQpQLnVRLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3UuQy5iKGEpCmlmKGEuYT4wKXth
+LmI9YS5jPWEuZD1hLmU9YS5mPW51bGwKYS5hPTAKYS5TKCl9cmV0dXJuIG51bGx9LAokUzoxNH0KUC5o
+Ri5wcm90b3R5cGU9eyRpaEY6MX0KUC5QQy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1
+LlouYihhKQp0PWZ1bmN0aW9uKGIsYyxkKXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gYihjLGQsdGhp
+cyxBcnJheS5wcm90b3R5cGUuc2xpY2UuYXBwbHkoYXJndW1lbnRzKSl9fShQLlI0LGEsITEpClAuRG0o
+dCwkLncoKSxhKQpyZXR1cm4gdH0sCiRTOjR9ClAuWW0ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
+cmV0dXJuIG5ldyB0aGlzLmEoYSl9LAokUzo0fQpQLk56LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
+e3JldHVybiBuZXcgUC5yNyhhKX0sCiRTOjM0fQpQLm5wLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEp
+e3JldHVybiBuZXcgUC5UeihhLHUuYW0pfSwKJFM6MzV9ClAuVXQucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
+b24oYSl7cmV0dXJuIG5ldyBQLkU0KGEpfSwKJFM6MzZ9ClAuRTQucHJvdG90eXBlPXsKcTpmdW5jdGlv
+bihhLGIpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEguYihQ
+LnhZKCJwcm9wZXJ0eSBpcyBub3QgYSBTdHJpbmcgb3IgbnVtIikpCnJldHVybiBQLkw3KHRoaXMuYVti
+XSl9LApZOmZ1bmN0aW9uKGEsYixjKXtpZih0eXBlb2YgYiE9InN0cmluZyImJnR5cGVvZiBiIT0ibnVt
+YmVyIil0aHJvdyBILmIoUC54WSgicHJvcGVydHkgaXMgbm90IGEgU3RyaW5nIG9yIG51bSIpKQp0aGlz
+LmFbYl09UC53WShjKX0sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4g
+YiBpbnN0YW5jZW9mIFAuRTQmJnRoaXMuYT09PWIuYX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQscwp0cnl7
+dD1TdHJpbmcodGhpcy5hKQpyZXR1cm4gdH1jYXRjaChzKXtILlJ1KHMpCnQ9dGhpcy54YigwKQpyZXR1
+cm4gdH19LApWNzpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcy5hCmlmKGI9PW51bGwpdD1udWxsCmVs
+c2V7dD1ILnQ2KGIpCnQ9UC5DSChuZXcgSC5BOChiLHQuQygiQCgxKSIpLmIoUC5pRygpKSx0LkMoIkE4
+PDEsQD4iKSksITAsdS56KX1yZXR1cm4gUC5MNyhzW2FdLmFwcGx5KHMsdCkpfSwKZ2lPOmZ1bmN0aW9u
+KGEpe3JldHVybiAwfX0KUC5yNy5wcm90b3R5cGU9e30KUC5Uei5wcm90b3R5cGU9ewpjUDpmdW5jdGlv
+bihhKXt2YXIgdD10aGlzLHM9YTwwfHxhPj10LmdBKHQpCmlmKHMpdGhyb3cgSC5iKFAuVEUoYSwwLHQu
+Z0EodCksbnVsbCxudWxsKSl9LApxOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGI9PSJudW1iZXIiJiZi
+PT09Qy5qbi55dShiKSl0aGlzLmNQKEguU2MoYikpCnJldHVybiB0aGlzLiR0aS5kLmIodGhpcy5Vcigw
+LGIpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CnRoaXMuJHRpLmQuYihjKQp0PUMuam4ueXUoYikK
+aWYoYj09PXQpdGhpcy5jUChiKQp0aGlzLmU0KDAsYixjKX0sCmdBOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
+aXMuYS5sZW5ndGgKaWYodHlwZW9mIHQ9PT0ibnVtYmVyIiYmdD4+PjA9PT10KXJldHVybiB0CnRocm93
+IEguYihQLlBWKCJCYWQgSnNBcnJheSBsZW5ndGgiKSl9LAokaWNYOjEsCiRpek06MX0KUC5jby5wcm90
+b3R5cGU9e30KUC5uZC5wcm90b3R5cGU9eyRpbmQ6MX0KUC5LZS5wcm90b3R5cGU9ewpQOmZ1bmN0aW9u
+KCl7dmFyIHQscyxyLHEscD10aGlzLmEuZ2V0QXR0cmlidXRlKCJjbGFzcyIpLG89UC5Mcyh1Lk4pCmlm
+KHA9PW51bGwpcmV0dXJuIG8KZm9yKHQ9cC5zcGxpdCgiICIpLHM9dC5sZW5ndGgscj0wO3I8czsrK3Ip
+e3E9Si5UMCh0W3JdKQppZihxLmxlbmd0aCE9PTApby5pKDAscSl9cmV0dXJuIG99LApYOmZ1bmN0aW9u
+KGEpe3RoaXMuYS5zZXRBdHRyaWJ1dGUoImNsYXNzIixhLkgoMCwiICIpKX19ClAuZDUucHJvdG90eXBl
+PXsKZ0Q6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLktlKGEpfSwKc2hmOmZ1bmN0aW9uKGEsYil7dGhp
+cy5ZQyhhLGIpfSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvCmlmKGQ9PW51bGwp
+e3Q9SC5WTShbXSx1LmspCmQ9bmV3IFcudkQodCkKQy5ObS5pKHQsVy5UdyhudWxsKSkKQy5ObS5pKHQs
+Vy5CbCgpKQpDLk5tLmkodCxuZXcgVy5PdygpKX1jPW5ldyBXLktvKGQpCnM9JzxzdmcgdmVyc2lvbj0i
+MS4xIj4nK0guZChiKSsiPC9zdmc+Igp0PWRvY3VtZW50CnI9dC5ib2R5CnE9KHImJkMuUlkpLkFIKHIs
+cyxjKQpwPXQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnEudG9TdHJpbmcKdD1uZXcgVy5lNyhxKQpv
+PXQuZ3I4KHQpCmZvcig7dD1vLmZpcnN0Q2hpbGQsdCE9bnVsbDspcC5hcHBlbmRDaGlsZCh0KQpyZXR1
+cm4gcH0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuQ3EoYSwiY2xpY2siLCExLHUuUSl9LAok
+aWQ1OjF9ClAubjYucHJvdG90eXBlPXskaWNYOjEsJGl6TToxLCRpQVM6MX0KVS5kMi5wcm90b3R5cGU9
+e30KVS5TZS5wcm90b3R5cGU9e30KVS51Ri5wcm90b3R5cGU9e30KVS5NbC5wcm90b3R5cGU9e30KVS55
+RC5wcm90b3R5cGU9e30KVS53Yi5wcm90b3R5cGU9e30KQi5qOC5wcm90b3R5cGU9e30KQi5xcC5wcm90
+b3R5cGU9e30KVC5HVi5wcm90b3R5cGU9e30KTC5lLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Zh
+ciB0LHMscixxLHAsbwp1LkIuYihhKQp0PXdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZQpzPUwuRzYod2lu
+ZG93LmxvY2F0aW9uLmhyZWYpCnI9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKTC5HZSgpCmlmKHQh
+PT0iLyImJnQhPT1KLlQwKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5yb290IikudGV4dENvbnRlbnQp
+KUwuRzcodCxzLHIsITAsbmV3IEwuVlcodCxzLHIpKQpxPUoucUYoZG9jdW1lbnQucXVlcnlTZWxlY3Rv
+cigiLmFwcGx5LW1pZ3JhdGlvbiIpKQpwPXEuJHRpCm89cC5DKCJ+KDEpIikuYihuZXcgTC5vWigpKQp1
+Lk0uYihudWxsKQpXLkpFKHEuYSxxLmIsbywhMSxwLmQpfSwKJFM6MTN9CkwuVlcucHJvdG90eXBlPXsK
+JDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX0sCiRTOjB9Ckwub1oucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5WLmIoYSkKTC50eSgiL2FwcGx5LW1pZ3JhdGlvbiIpLlc3KG5l
+dyBMLmpyKCksdS5QKS5PQShuZXcgTC5xbCgpKX0sCiRTOjZ9CkwuanIucHJvdG90eXBlPXsKJDE6ZnVu
+Y3Rpb24oYSl7dmFyIHQKdS5yLmIoYSkKdD1kb2N1bWVudC5ib2R5CnQuY2xhc3NMaXN0LnJlbW92ZSgi
+cHJvcG9zZWQiKQp0LmNsYXNzTGlzdC5hZGQoImFwcGxpZWQiKX0sCiRTOjd9CkwucWwucHJvdG90eXBl
+PXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFKKCJhcHBseSBtaWdyYXRpb24gZXJyb3I6ICIrSC5kKGEpLGIp
+CndpbmRvdy5hbGVydCgiQ291bGQgbm90IGFwcGx5IG1pZ3JhdGlvbiAoIitILmQoYSkrIikuIil9LAok
+QzoiJDIiLAokUjoyLAokUzoxfQpMLkwucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
+CnUuQi5iKGEpCnQ9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnM9TC5HNih3aW5kb3cubG9jYXRpb24u
+aHJlZikKcj1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQppZih0Lmxlbmd0aD4xKUwuRzcodCxzLHIs
+ITEsbnVsbCkKZWxzZXtMLkJFKHQsbmV3IEIucXAoIiIsIiIsIiIsQy54RCksITApCkwuQlgoIiZuYnNw
+OyIsbnVsbCl9fSwKJFM6MTN9CkwuV3gucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
+LHE9ImNvbGxhcHNlZCIKdS5WLmIoYSkKdD10aGlzLmEKcz1KLlJFKHQpCnI9dGhpcy5iCmlmKCFzLmdE
+KHQpLnRnKDAscSkpe3MuZ0QodCkuaSgwLHEpCkouZFIocikuaSgwLHEpfWVsc2V7cy5nRCh0KS5SKDAs
+cSkKSi5kUihyKS5SKDAscSl9fSwKJFM6Nn0KTC5BTy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2
+YXIgdD1KLnFGKHUuaC5iKGEpKSxzPXQuJHRpLHI9cy5DKCJ+KDEpIikuYihuZXcgTC5kTih0aGlzLmEp
+KQp1Lk0uYihudWxsKQpXLkpFKHQuYSx0LmIsciwhMSxzLmQpfSwKJFM6M30KTC5kTi5wcm90b3R5cGU9
+ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LlYuYihhKQp0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoInRh
+YmxlW2RhdGEtcGF0aF0iKQp0LnRvU3RyaW5nCkwudDIoYSx0aGlzLmEsdC5nZXRBdHRyaWJ1dGUoImRh
+dGEtIituZXcgVy5TeShuZXcgVy5pNyh0KSkuTygicGF0aCIpKSl9LAokUzo2fQpMLkhvLnByb3RvdHlw
+ZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscgp1LmguYihhKQp0PUoucUYoYSkKcz10LiR0aQpyPXMu
+QygifigxKSIpLmIobmV3IEwueHooYSx0aGlzLmEpKQp1Lk0uYihudWxsKQpXLkpFKHQuYSx0LmIsciwh
+MSxzLmQpfSwKJFM6M30KTC54ei5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LlYuYihh
+KQp0PXRoaXMuYQpMLmhYKHRoaXMuYixQLlFBKHQuZ2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3ko
+bmV3IFcuaTcodCkpLk8oIm9mZnNldCIpKSxudWxsLG51bGwpKX0sCiRTOjZ9CkwuSUMucHJvdG90eXBl
+PXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9Si5xRih1LmguYihhKSkscz10LiR0aQpzLkMoIn4oMSkiKS5i
+KEwuSDAoKSkKdS5NLmIobnVsbCkKVy5KRSh0LmEsdC5iLEwuSDAoKSwhMSxzLmQpfSwKJFM6M30KTC5M
+MS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1LnIuYihhKQp0PWEuc3RhdHVzCmlmKHQ9
+PT0yMDApcmV0dXJuIGEKZWxzZSB0aHJvdyBILmIoIlJlcXVlc3QgZmFpbGVkOyBzdGF0dXMgb2YgIitI
+LmQodCkpfSwKJFM6NDF9CkwublQucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYS5h
+LHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KTC5CWi5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIo
+dGhpcy5hLmEsbnVsbCxudWxsKX0sCiRTOjB9CkwuR0gucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
+dS5oLmIoYSkKJC56QigpLnRvU3RyaW5nCnUudi5iKCQub3coKS5xKDAsImhsanMiKSkuVjcoImhpZ2hs
+aWdodEJsb2NrIixbYV0pfSwKJFM6M30KTC5EVC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIg
+dAp1LnIuYihhKQp0PWEuc3RhdHVzCmlmKHQ9PT0yMDApe0wuVDEoVS55dShDLkN0LnBXKDAsYS5yZXNw
+b25zZVRleHQsbnVsbCkpKQpMLnlYKCIuZWRpdC1wYW5lbCAucGFuZWwtY29udGVudCIsITEpfWVsc2Ug
+d2luZG93LmFsZXJ0KCJSZXF1ZXN0IGZhaWxlZDsgc3RhdHVzIG9mICIrSC5kKHQpKX0sCiRTOjd9Ckwu
+ZUgucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFKKCJsb2FkUmVnaW9uRXhwbGFuYXRpb246
+ICIrSC5kKGEpLGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90IGxvYWQgIitILmQodGhpcy5hKSsiICgi
+K0guZChhKSsiKS4iKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjF9CkwuekQucHJvdG90eXBlPXsKJDE6ZnVu
+Y3Rpb24oYSl7dmFyIHQscyxyPXRoaXMKdS5yLmIoYSkKdD1hLnN0YXR1cwppZih0PT09MjAwKXtzPXIu
+YQpMLkJFKHMsQi5ZZih1LmIuYihDLkN0LnBXKDAsYS5yZXNwb25zZVRleHQsbnVsbCkpKSxyLmIpCnQ9
+ci5jCkwuZkcodCxyLmQpCkwuQlgoQy54Qi50ZyhzLCI/Iik/Qy54Qi5OaihzLDAsQy54Qi5PWShzLCI/
+IikpOnMsdCkKdD1yLmUKaWYodCE9bnVsbCl0LiQwKCl9ZWxzZSB3aW5kb3cuYWxlcnQoIlJlcXVlc3Qg
+ZmFpbGVkOyBzdGF0dXMgb2YgIitILmQodCkpfSwKJFM6N30KTC5PRS5wcm90b3R5cGU9ewokMjpmdW5j
+dGlvbihhLGIpe0wucUooImxvYWRGaWxlOiAiK0guZChhKSxiKQp3aW5kb3cuYWxlcnQoIkNvdWxkIG5v
+dCBsb2FkICIrdGhpcy5hKyIgKCIrSC5kKGEpKyIpLiIpfSwKJEM6IiQyIiwKJFI6MiwKJFM6MX0KTC5U
+Vy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIKdS5yLmIoYSkKdD1hLnN0YXR1cwpp
+Zih0PT09MjAwKXtzPUMuQ3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKQpyPWRvY3VtZW50LnF1ZXJ5
+U2VsZWN0b3IoIi5uYXYtdHJlZSIpCkoubDUociwiIikKTC50WChyLEwubUsocykpfWVsc2Ugd2luZG93
+LmFsZXJ0KCJSZXF1ZXN0IGZhaWxlZDsgc3RhdHVzIG9mICIrSC5kKHQpKX0sCiRTOjd9CkwueHIucHJv
+dG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtMLnFKKCJsb2FkTmF2aWdhdGlvblRyZWU6ICIrSC5kKGEp
+LGIpCndpbmRvdy5hbGVydCgiQ291bGQgbm90IGxvYWQgIit0aGlzLmErIiAoIitILmQoYSkrIikuIil9
+LAokQzoiJDIiLAokUjoyLAokUzoxfQpMLkVFLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0
+LHMKdS5WLmIoYSkKdD10aGlzLmEKcz10aGlzLmIKTC5hZih3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUs
+dCxzLCEwLG5ldyBMLlFMKHQscykpCkwuaFgodGhpcy5jLHQpfSwKJFM6Nn0KTC5RTC5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe0wuRnIod2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLHRoaXMuYSx0aGlzLmIp
+fSwKJFM6MH0KTC5WUy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzPSJzZWxlY3RlZC1m
+aWxlIgp1LmguYihhKQphLnRvU3RyaW5nCnQ9Si5SRShhKQppZihhLmdldEF0dHJpYnV0ZSgiZGF0YS0i
+K25ldyBXLlN5KG5ldyBXLmk3KGEpKS5PKCJuYW1lIikpPT09dGhpcy5hLmEpdC5nRChhKS5pKDAscykK
+ZWxzZSB0LmdEKGEpLlIoMCxzKX0sCiRTOjN9CkwuVEQucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
+cmV0dXJuIEwudDIodS5WLmIoYSksITAsbnVsbCl9LAokUzoxNn0KTC5YQS5wcm90b3R5cGU9ewpFYjpm
+dW5jdGlvbihhLGIsYyl7cmV0dXJuITB9LAppMDpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCiRpa0Y6MX0K
+TC5aWi5wcm90b3R5cGU9e30KTC55OC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
+LmJ9fQpNLmxJLnByb3RvdHlwZT17CldPOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1udWxsCk0uWUYoImFi
+c29sdXRlIixILlZNKFtiLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSx1LnMpKQp0PXRoaXMu
+YQp0PXQuWXIoYik+MCYmIXQuaEsoYikKaWYodClyZXR1cm4gYgp0PUQuUlgoKQpyZXR1cm4gdGhpcy5x
+NygwLHQsYixzLHMscyxzLHMscyl9LAp0TTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9WC5DTChhLHRoaXMu
+YSkKci5JVigpCnQ9ci5kCnM9dC5sZW5ndGgKaWYocz09PTApe3Q9ci5iCnJldHVybiB0PT1udWxsPyIu
+Ijp0fWlmKHM9PT0xKXt0PXIuYgpyZXR1cm4gdD09bnVsbD8iLiI6dH1pZigwPj1zKXJldHVybiBILk9I
+KHQsLTEpCnQucG9wKCkKQy5ObS5tdihyLmUpCnIuSVYoKQpyZXR1cm4gci53KDApfSwKcTc6ZnVuY3Rp
+b24oYSxiLGMsZCxlLGYsZyxoLGkpe3ZhciB0PUguVk0oW2IsYyxkLGUsZixnLGgsaV0sdS5zKQpNLllG
+KCJqb2luIix0KQpyZXR1cm4gdGhpcy5JUChuZXcgSC5VNSh0LHUuYkIuYihuZXcgTS5NaSgpKSx1LmNj
+KSl9LApJUDpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwKdS5YLmIoYSkKZm9yKHQ9YS4k
+dGkscz10LkMoImEyKGNYLkUpIikuYihuZXcgTS5xNygpKSxyPWEuZ2t6KGEpLHQ9bmV3IEguU08ocixz
+LHQuQygiU088Y1guRT4iKSkscz10aGlzLmEscT0hMSxwPSExLG89IiI7dC5GKCk7KXtuPXIuZ2woKQpp
+ZihzLmhLKG4pJiZwKXttPVguQ0wobixzKQpsPW8uY2hhckNvZGVBdCgwKT09MD9vOm8Kbz1DLnhCLk5q
+KGwsMCxzLlNwKGwsITApKQptLmI9bwppZihzLmRzKG8pKUMuTm0uWShtLmUsMCxzLmdtSSgpKQpvPW0u
+dygwKX1lbHNlIGlmKHMuWXIobik+MCl7cD0hcy5oSyhuKQpvPUguZChuKX1lbHNle2lmKCEobi5sZW5n
+dGg+MCYmcy5VZChuWzBdKSkpaWYocSlvKz1zLmdtSSgpCm8rPUguZChuKX1xPXMuZHMobil9cmV0dXJu
+IG8uY2hhckNvZGVBdCgwKT09MD9vOm99LApvNTpmdW5jdGlvbihhKXt2YXIgdAppZighdGhpcy55Myhh
+KSlyZXR1cm4gYQp0PVguQ0woYSx0aGlzLmEpCnQuclIoKQpyZXR1cm4gdC53KDApfSwKeTM6ZnVuY3Rp
+b24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGsKYS50b1N0cmluZwp0PXRoaXMuYQpzPXQuWXIoYSkK
+aWYocyE9PTApe2lmKHQ9PT0kLktrKCkpZm9yKHI9MDtyPHM7KytyKWlmKEMueEIuVyhhLHIpPT09NDcp
+cmV0dXJuITAKcT1zCnA9NDd9ZWxzZXtxPTAKcD1udWxsfWZvcihvPW5ldyBILnFqKGEpLmEsbj1vLmxl
+bmd0aCxyPXEsbT1udWxsO3I8bjsrK3IsbT1wLHA9bCl7bD1DLnhCLm0obyxyKQppZih0LnI0KGwpKXtp
+Zih0PT09JC5LaygpJiZsPT09NDcpcmV0dXJuITAKaWYocCE9bnVsbCYmdC5yNChwKSlyZXR1cm4hMApp
+ZihwPT09NDYpaz1tPT1udWxsfHxtPT09NDZ8fHQucjQobSkKZWxzZSBrPSExCmlmKGspcmV0dXJuITB9
+fWlmKHA9PW51bGwpcmV0dXJuITAKaWYodC5yNChwKSlyZXR1cm4hMAppZihwPT09NDYpdD1tPT1udWxs
+fHx0LnI0KG0pfHxtPT09NDYKZWxzZSB0PSExCmlmKHQpcmV0dXJuITAKcmV0dXJuITF9LApIUDpmdW5j
+dGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz10aGlzLG49J1VuYWJsZSB0byBmaW5kIGEgcGF0aCB0byAi
+JwpiPW8uV08oMCxiKQp0PW8uYQppZih0LllyKGIpPD0wJiZ0LllyKGEpPjApcmV0dXJuIG8ubzUoYSkK
+aWYodC5ZcihhKTw9MHx8dC5oSyhhKSlhPW8uV08oMCxhKQppZih0LllyKGEpPD0wJiZ0LllyKGIpPjAp
+dGhyb3cgSC5iKFguSlQobitILmQoYSkrJyIgZnJvbSAiJytILmQoYikrJyIuJykpCnM9WC5DTChiLHQp
+CnMuclIoKQpyPVguQ0woYSx0KQpyLnJSKCkKcT1zLmQKaWYocS5sZW5ndGg+MCYmSi5STShxWzBdLCIu
+IikpcmV0dXJuIHIudygwKQpxPXMuYgpwPXIuYgppZihxIT1wKXE9cT09bnVsbHx8cD09bnVsbHx8IXQu
+TmMocSxwKQplbHNlIHE9ITEKaWYocSlyZXR1cm4gci53KDApCndoaWxlKCEwKXtxPXMuZAppZihxLmxl
+bmd0aD4wKXtwPXIuZApxPXAubGVuZ3RoPjAmJnQuTmMocVswXSxwWzBdKX1lbHNlIHE9ITEKaWYoIXEp
+YnJlYWsKQy5ObS5XNChzLmQsMCkKQy5ObS5XNChzLmUsMSkKQy5ObS5XNChyLmQsMCkKQy5ObS5XNChy
+LmUsMSl9cT1zLmQKaWYocS5sZW5ndGg+MCYmSi5STShxWzBdLCIuLiIpKXRocm93IEguYihYLkpUKG4r
+SC5kKGEpKyciIGZyb20gIicrSC5kKGIpKyciLicpKQpxPXUuTgpDLk5tLlVHKHIuZCwwLFAuTzgocy5k
+Lmxlbmd0aCwiLi4iLHEpKQpDLk5tLlkoci5lLDAsIiIpCkMuTm0uVUcoci5lLDEsUC5POChzLmQubGVu
+Z3RoLHQuZ21JKCkscSkpCnQ9ci5kCnE9dC5sZW5ndGgKaWYocT09PTApcmV0dXJuIi4iCmlmKHE+MSYm
+Si5STShDLk5tLmdyWih0KSwiLiIpKXt0PXIuZAppZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LC0x
+KQp0LnBvcCgpCnQ9ci5lCkMuTm0ubXYodCkKQy5ObS5tdih0KQpDLk5tLmkodCwiIil9ci5iPSIiCnIu
+SVYoKQpyZXR1cm4gci53KDApfX0KTS5NaS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4g
+SC55KGEpIT1udWxsfSwKJFM6OH0KTS5xNy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4g
+SC55KGEpIT09IiJ9LAokUzo4fQpNLk5vLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe0gueShhKQpy
+ZXR1cm4gYT09bnVsbD8ibnVsbCI6JyInK2ErJyInfSwKJFM6NX0KQi5MdS5wcm90b3R5cGU9ewp4Wjpm
+dW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuWXIoYSkKaWYocz4wKXJldHVybiBKLmxkKGEsMCxzKQppZih0
+aGlzLmhLKGEpKXtpZigwPj1hLmxlbmd0aClyZXR1cm4gSC5PSChhLDApCnQ9YVswXX1lbHNlIHQ9bnVs
+bApyZXR1cm4gdH0sCk5jOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PWJ9fQpYLldELnByb3RvdHlwZT17
+CklWOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRoaXMKd2hpbGUoITApe3Q9ci5kCmlmKCEodC5sZW5ndGgh
+PT0wJiZKLlJNKEMuTm0uZ3JaKHQpLCIiKSkpYnJlYWsKdD1yLmQKaWYoMD49dC5sZW5ndGgpcmV0dXJu
+IEguT0godCwtMSkKdC5wb3AoKQpDLk5tLm12KHIuZSl9dD1yLmUKcz10Lmxlbmd0aAppZihzPjApQy5O
+bS5ZKHQscy0xLCIiKX0sCnJSOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4sbT10aGlzLGw9SC5W
+TShbXSx1LnMpCmZvcih0PW0uZCxzPXQubGVuZ3RoLHI9MCxxPTA7cTx0Lmxlbmd0aDt0Lmxlbmd0aD09
+PXN8fCgwLEgubGspKHQpLCsrcSl7cD10W3FdCm89Si5pYShwKQppZighKG8uRE4ocCwiLiIpfHxvLkRO
+KHAsIiIpKSlpZihvLkROKHAsIi4uIikpaWYobC5sZW5ndGg+MClsLnBvcCgpCmVsc2UgKytyCmVsc2Ug
+Qy5ObS5pKGwscCl9aWYobS5iPT1udWxsKUMuTm0uVUcobCwwLFAuTzgociwiLi4iLHUuTikpCmlmKGwu
+bGVuZ3RoPT09MCYmbS5iPT1udWxsKUMuTm0uaShsLCIuIikKbj1QLmRIKGwubGVuZ3RoLG5ldyBYLnFS
+KG0pLCEwLHUuTikKdD1tLmIKdD10IT1udWxsJiZsLmxlbmd0aD4wJiZtLmEuZHModCk/bS5hLmdtSSgp
+OiIiCkgudDYobikuZC5iKHQpCmlmKCEhbi5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJpbnNlcnQiKSkK
+bi5zcGxpY2UoMCwwLHQpCm0uc25KKGwpCm0uc1BoKG4pCnQ9bS5iCmlmKHQhPW51bGwmJm0uYT09PSQu
+S2soKSl7dC50b1N0cmluZwptLmI9SC55cyh0LCIvIiwiXFwiKX1tLklWKCl9LAp3OmZ1bmN0aW9uKGEp
+e3ZhciB0LHMscj10aGlzLHE9ci5iCnE9cSE9bnVsbD9xOiIiCmZvcih0PTA7dDxyLmQubGVuZ3RoOysr
+dCl7cz1yLmUKaWYodD49cy5sZW5ndGgpcmV0dXJuIEguT0gocyx0KQpzPXErSC5kKHNbdF0pCnE9ci5k
+CmlmKHQ+PXEubGVuZ3RoKXJldHVybiBILk9IKHEsdCkKcT1zK0guZChxW3RdKX1xKz1ILmQoQy5ObS5n
+clooci5lKSkKcmV0dXJuIHEuY2hhckNvZGVBdCgwKT09MD9xOnF9LApzbko6ZnVuY3Rpb24oYSl7dGhp
+cy5kPXUuYS5iKGEpfSwKc1BoOmZ1bmN0aW9uKGEpe3RoaXMuZT11LmEuYihhKX19ClgucVIucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hLmdtSSgpfSwKJFM6NDN9ClguZHYucHJv
+dG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iUGF0aEV4Y2VwdGlvbjogIit0aGlzLmF9fQpPLnpM
+LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ29jKHRoaXMpfX0KRS5PRi5wcm90
+b3R5cGU9ewpVZDpmdW5jdGlvbihhKXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihh
+KXtyZXR1cm4gYT09PTQ3fSwKZHM6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5sZW5ndGgKcmV0dXJuIHQhPT0w
+JiZDLnhCLm0oYSx0LTEpIT09NDd9LApTcDpmdW5jdGlvbihhLGIpe2lmKGEubGVuZ3RoIT09MCYmQy54
+Qi5XKGEsMCk9PT00NylyZXR1cm4gMQpyZXR1cm4gMH0sCllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlz
+LlNwKGEsITEpfSwKaEs6ZnVuY3Rpb24oYSl7cmV0dXJuITF9LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4i
+cG9zaXgifSwKZ21JOmZ1bmN0aW9uKCl7cmV0dXJuIi8ifX0KRi5ydS5wcm90b3R5cGU9ewpVZDpmdW5j
+dGlvbihhKXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3
+fSwKZHM6ZnVuY3Rpb24oYSl7dmFyIHQ9YS5sZW5ndGgKaWYodD09PTApcmV0dXJuITEKaWYoQy54Qi5t
+KGEsdC0xKSE9PTQ3KXJldHVybiEwCnJldHVybiBDLnhCLlRjKGEsIjovLyIpJiZ0aGlzLllyKGEpPT09
+dH0sClNwOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscD1hLmxlbmd0aAppZihwPT09MClyZXR1cm4g
+MAppZihDLnhCLlcoYSwwKT09PTQ3KXJldHVybiAxCmZvcih0PTA7dDxwOysrdCl7cz1DLnhCLlcoYSx0
+KQppZihzPT09NDcpcmV0dXJuIDAKaWYocz09PTU4KXtpZih0PT09MClyZXR1cm4gMApyPUMueEIuWFUo
+YSwiLyIsQy54Qi5RaShhLCIvLyIsdCsxKT90KzM6dCkKaWYocjw9MClyZXR1cm4gcAppZighYnx8cDxy
+KzMpcmV0dXJuIHIKaWYoIUMueEIubihhLCJmaWxlOi8vIikpcmV0dXJuIHIKaWYoIUIuWXUoYSxyKzEp
+KXJldHVybiByCnE9ciszCnJldHVybiBwPT09cT9xOnIrNH19cmV0dXJuIDB9LApZcjpmdW5jdGlvbihh
+KXtyZXR1cm4gdGhpcy5TcChhLCExKX0sCmhLOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aCE9PTAm
+JkMueEIuVyhhLDApPT09NDd9LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4idXJsIn0sCmdtSTpmdW5jdGlv
+bigpe3JldHVybiIvIn19CkwuSVYucHJvdG90eXBlPXsKVWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEMueEIu
+dGcoYSwiLyIpfSwKcjQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGE9PT00N3x8YT09PTkyfSwKZHM6ZnVuY3Rp
+b24oYSl7dmFyIHQ9YS5sZW5ndGgKaWYodD09PTApcmV0dXJuITEKdD1DLnhCLm0oYSx0LTEpCnJldHVy
+biEodD09PTQ3fHx0PT09OTIpfSwKU3A6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9YS5sZW5ndGgKaWYo
+cj09PTApcmV0dXJuIDAKdD1DLnhCLlcoYSwwKQppZih0PT09NDcpcmV0dXJuIDEKaWYodD09PTkyKXtp
+ZihyPDJ8fEMueEIuVyhhLDEpIT09OTIpcmV0dXJuIDEKcz1DLnhCLlhVKGEsIlxcIiwyKQppZihzPjAp
+e3M9Qy54Qi5YVShhLCJcXCIscysxKQppZihzPjApcmV0dXJuIHN9cmV0dXJuIHJ9aWYocjwzKXJldHVy
+biAwCmlmKCFCLk9TKHQpKXJldHVybiAwCmlmKEMueEIuVyhhLDEpIT09NTgpcmV0dXJuIDAKcj1DLnhC
+LlcoYSwyKQppZighKHI9PT00N3x8cj09PTkyKSlyZXR1cm4gMApyZXR1cm4gM30sCllyOmZ1bmN0aW9u
+KGEpe3JldHVybiB0aGlzLlNwKGEsITEpfSwKaEs6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuWXIoYSk9
+PT0xfSwKT3Q6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPT09YilyZXR1cm4hMAppZihhPT09NDcpcmV0
+dXJuIGI9PT05MgppZihhPT09OTIpcmV0dXJuIGI9PT00NwppZigoYV5iKSE9PTMyKXJldHVybiExCnQ9
+YXwzMgpyZXR1cm4gdD49OTcmJnQ8PTEyMn0sCk5jOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmlmKGE9
+PWIpcmV0dXJuITAKdD1hLmxlbmd0aAppZih0IT09Yi5sZW5ndGgpcmV0dXJuITEKZm9yKHM9Si5yWShi
+KSxyPTA7cjx0OysrcilpZighdGhpcy5PdChDLnhCLlcoYSxyKSxzLlcoYixyKSkpcmV0dXJuITEKcmV0
+dXJuITB9LApnb2M6ZnVuY3Rpb24oKXtyZXR1cm4id2luZG93cyJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1
+cm4iXFwifX07KGZ1bmN0aW9uIGFsaWFzZXMoKXt2YXIgdD1KLnZCLnByb3RvdHlwZQp0LlU9dC53CnQu
+U2o9dC5lNwp0PUouTUYucHJvdG90eXBlCnQudD10LncKdD1QLmNYLnByb3RvdHlwZQp0LkdHPXQuZXYK
+dD1QLmsucHJvdG90eXBlCnQueGI9dC53CnQ9Vy5jdi5wcm90b3R5cGUKdC5EVz10LnI2CnQ9Vy5tNi5w
+cm90b3R5cGUKdC5qRj10LkViCnQ9UC5FNC5wcm90b3R5cGUKdC5Vcj10LnEKdC5lND10Lll9KSgpOyhm
+dW5jdGlvbiBpbnN0YWxsVGVhck9mZnMoKXt2YXIgdD1odW5rSGVscGVycy5fc3RhdGljXzEscz1odW5r
+SGVscGVycy5fc3RhdGljXzAscj1odW5rSGVscGVycy5pbnN0YWxsSW5zdGFuY2VUZWFyT2ZmLHE9aHVu
+a0hlbHBlcnMuaW5zdGFsbFN0YXRpY1RlYXJPZmYscD1odW5rSGVscGVycy5faW5zdGFuY2VfMXUKdChQ
+LCJFWCIsIlpWIiw5KQp0KFAsInl0Iiwib0EiLDkpCnQoUCwicVciLCJCeiIsOSkKcyhQLCJVSSIsImVO
+IiwyKQpyKFAuUGYucHJvdG90eXBlLCJnWUoiLDAsMSxudWxsLFsiJDIiLCIkMSJdLFsidzAiLCJwbSJd
+LDQ0LDApCnQoUCwiUEgiLCJNdCIsNSkKcShXLCJwUyIsNCxudWxsLFsiJDQiXSxbInlXIl0sMTUsMCkK
+cShXLCJWNCIsNCxudWxsLFsiJDQiXSxbIlFXIl0sMTUsMCkKcChQLkFzLnByb3RvdHlwZSwiZ3VNIiwi
+VCIsNSkKdChQLCJpRyIsIndZIiw0KQp0KFAsIncwIiwiTDciLDMwKQp0KEwsIkgwIiwidW0iLDE2KX0p
+KCk7KGZ1bmN0aW9uIGluaGVyaXRhbmNlKCl7dmFyIHQ9aHVua0hlbHBlcnMubWl4aW4scz1odW5rSGVs
+cGVycy5pbmhlcml0LHI9aHVua0hlbHBlcnMuaW5oZXJpdE1hbnkKcyhQLmssbnVsbCkKcihQLmssW0gu
+ZW8sSi52QixKLm0xLFAublksUC5jWCxILmE3LFAuQW4sSC5TVSxILlJlLEgud3YsUC5QbixILldVLEgu
+TEksSC5UcCxILmY5LFAuWFMsSC5icSxILlhPLFAuWWssSC5kYixILk42LEguVlIsSC5FSyxILlBiLEgu
+dFEsSC5TZCxILkpjLEguRyxQLlczLFAuaWgsUC5QZixQLkZlLFAudnMsUC5PTSxQLnFoLFAuTU8sUC5r
+VCxQLnhJLFAuQ3csUC5tMCxQLlh2LFAuYm4sUC5sbSxQLmxELFAuS1AsUC5sZixQLldZLFAuVWssUC5S
+dyxQLmJ6LFAuYTIsUC5pUCxQLkZLLFAuazUsUC5LWSxQLkNELFAuYUUsUC5FSCxQLnpNLFAuWjAsUC5j
+OCxQLk9kLFAuaWIsUC5HeixQLnFVLFAuUm4sUC5HRCxQLkRuLFAuUEUsUC5VZixXLmlkLFcuRmssVy5K
+USxXLkdtLFcudkQsVy5tNixXLk93LFcuVzksVy5kVyxXLkZiLFcua0YsVy5tayxXLktvLFAuaUosUC5F
+NCxQLm42LFUuZDIsVS5TZSxVLnVGLFUuTWwsVS55RCxVLndiLEIuajgsQi5xcCxULkdWLEwuWEEsTC5a
+WixMLnk4LE0ubEksTy56TCxYLldELFguZHZdKQpyKEoudkIsW0oueUUsSi5ZRSxKLk1GLEouamQsSi5x
+SSxKLkRyLEguRVQsVy5EMCxXLkF6LFcuTGUsVy5OaCxXLklCLFcubjcsVy5lYSxXLmJyLFcuU2csVy51
+OCxXLks3LFcuWFcsUC5oRl0pCnIoSi5NRixbSi5pQyxKLmtkLEouYzVdKQpzKEouUG8sSi5qZCkKcihK
+LnFJLFtKLnVyLEouVkFdKQpzKFAuTFUsUC5uWSkKcihQLkxVLFtILlhDLFcud3osVy5lN10pCnMoSC5x
+aixILlhDKQpyKFAuY1gsW0guYlEsSC5VNSxQLm1XLEgudW5dKQpyKEguYlEsW0guYUwsSC5pNSxQLnh1
+XSkKcihILmFMLFtILm5ILEguQTgsUC5pOF0pCnMoSC5TTyxQLkFuKQpzKFAuUlUsUC5QbikKcyhQLkdq
+LFAuUlUpCnMoSC5QRCxQLkdqKQpzKEguTFAsSC5XVSkKcihILlRwLFtILkNqLEguQW0sSC5sYyxILmRD
+LEgud04sSC5WWCxQLnRoLFAuaGEsUC5WcyxQLkZ0LFAueUgsUC5XTSxQLlNYLFAuR3MsUC5kYSxQLm9R
+LFAucFYsUC5VNyxQLnZyLFAuckgsUC5LRixQLlpMLFAuUlQsUC5qWixQLnJxLFAuUlcsUC5CNSxQLlBJ
+LFAucEssUC5oaixQLlZwLFAuT1IsUC5yYSxQLldGLFAubjEsUC5jUyxQLlZDLFAudHAsUC5lMSxQLk5Z
+LFAuUlosUC5NRSxQLnk1LFAucTMsUC55SSxQLmM2LFAucWQsVy5DdixXLmJVLFcuaEgsVy5LUyxXLkEz
+LFcudk4sVy5VdixXLkVnLFcuRW8sVy5XayxXLklBLFcuZm0sUC5sUixQLmpnLFAuR0UsUC5ONyxQLnVR
+LFAuUEMsUC5ZbSxQLk56LFAubnAsUC5VdCxMLmUsTC5WVyxMLm9aLEwuanIsTC5xbCxMLkwsTC5XeCxM
+LkFPLEwuZE4sTC5IbyxMLnh6LEwuSUMsTC5MMSxMLm5ULEwuQlosTC5HSCxMLkRULEwuZUgsTC56RCxM
+Lk9FLEwuVFcsTC54cixMLkVFLEwuUUwsTC5WUyxMLlRELE0uTWksTS5xNyxNLk5vLFgucVJdKQpyKFAu
+WFMsW0guVzAsSC5heixILnZWLEguRXEsUC5DNixILnU5LFAubixQLnUsUC5tcCxQLnViLFAuZHMsUC5s
+aixQLlVWLFAuY10pCnIoSC5sYyxbSC56eCxILnJUXSkKcyhILmtZLFAuQzYpCnMoUC5pbCxQLllrKQpy
+KFAuaWwsW0guTjUsUC51dyxXLmNmLFcuU3ldKQpzKEguS1csUC5tVykKcyhILmIwLEguRVQpCnIoSC5i
+MCxbSC5SRyxILldCXSkKcyhILlZQLEguUkcpCnMoSC5EZyxILlZQKQpzKEguWkcsSC5XQikKcyhILlBn
+LEguWkcpCnIoSC5QZyxbSC54aixILmRFLEguWkEsSC53ZixILlBxLEguZUUsSC5WNl0pCnIoSC51OSxb
+SC5oeixILmlNXSkKcyhQLlpmLFAuUGYpCnMoUC5KaSxQLm0wKQpzKFAuYjYsUC5YdikKcyhQLlZqLFAu
+V1kpCnIoUC5VayxbUC5DVixQLlppLFAuYnldKQpzKFAud0ksUC5rVCkKcihQLndJLFtQLlU4LFAuTXgs
+UC5FMyxQLkdZXSkKcyhQLnU1LFAuWmkpCnIoUC5GSyxbUC5DUCxQLktOXSkKcihQLnUsW1AuYkosUC5l
+WV0pCnMoUC5xZSxQLkRuKQpyKFcuRDAsW1cudUgsVy53YSxXLks1LFcuQ21dKQpyKFcudUgsW1cuY3Ys
+Vy5ueCxXLlFGLFcuQ1FdKQpyKFcuY3YsW1cucUUsUC5kNV0pCnIoVy5xRSxbVy5HaCxXLmZZLFcubkIs
+Vy5RUCxXLmg0LFcuU04sVy5scCxXLlRiLFcuSXYsVy5CVCxXLnlZXSkKcyhXLm9KLFcuTGUpCnMoVy5U
+NSxXLkF6KQpzKFcuVmIsVy5RRikKcyhXLk83LFcud2EpCnIoVy5lYSxbVy53NixXLmV3XSkKcyhXLkFq
+LFcudzYpCnMoVy5yQixXLks3KQpzKFcuQkgsVy5yQikKcyhXLnc0LFcuSUIpCnMoVy5vYSxXLlhXKQpz
+KFcucmgsVy5vYSkKcyhXLmk3LFcuY2YpCnMoUC5BcyxQLlZqKQpyKFAuQXMsW1cuSTQsUC5LZV0pCnMo
+Vy5STyxQLnFoKQpzKFcuQ3EsVy5STykKcyhXLnhDLFAuTU8pCnMoVy5jdCxXLm02KQpzKFAuQmYsUC5p
+SikKcihQLkU0LFtQLnI3LFAuY29dKQpzKFAuVHosUC5jbykKcyhQLm5kLFAuZDUpCnMoQi5MdSxPLnpM
+KQpyKEIuTHUsW0UuT0YsRi5ydSxMLklWXSkKdChILlhDLEguUmUpCnQoSC5SRyxQLmxEKQp0KEguVlAs
+SC5TVSkKdChILldCLFAubEQpCnQoSC5aRyxILlNVKQp0KFAublksUC5sRCkKdChQLldZLFAubGYpCnQo
+UC5SVSxQLktQKQp0KFcuTGUsVy5pZCkKdChXLks3LFAubEQpCnQoVy5yQixXLkdtKQp0KFcuWFcsUC5s
+RCkKdChXLm9hLFcuR20pCnQoUC5jbyxQLmxEKX0pKCkKdmFyIHY9e3R5cGVVbml2ZXJzZTp7ZUM6bmV3
+IE1hcCgpLHRSOnt9LGVUOnt9LHRQVjp7fSxzRUE6W119LG1hbmdsZWRHbG9iYWxOYW1lczp7S046Imlu
+dCIsQ1A6ImRvdWJsZSIsRks6Im51bSIscVU6IlN0cmluZyIsYTI6ImJvb2wiLGM4OiJOdWxsIix6TToi
+TGlzdCJ9LG1hbmdsZWROYW1lczp7fSxnZXRUeXBlRnJvbU5hbWU6Z2V0R2xvYmFsRnJvbU5hbWUsbWV0
+YWRhdGE6W10sdHlwZXM6WyJjOCgpIiwiYzgoQCxAKSIsIn4oKSIsImM4KGN2KSIsIkAoQCkiLCJxVShx
+VSkiLCJjOChBaikiLCJjOChPNykiLCJhMihxVSkiLCJ+KH4oKSkiLCJjOChxVSxxVSkiLCJjOChxVSki
+LCJjOChxVSxAKSIsImM4KGVhKSIsIn4oeHU8cVU+KSIsImEyKGN2LHFVLHFVLEpRKSIsIn4oQWopIiwi
+YTIoa0YpIiwiYzgoQCkiLCJLTihLTixLTikiLCJ+KEApIiwiYzgofigpKSIsIn4ocVUscVUpIiwiYzgo
+S04sQCkiLCJuNihALEApIiwiYTIodUgpIiwifihxVVtAXSkiLCJjOChldykiLCJAKGVhKSIsIn4ocVUs
+S04pIiwiayhAKSIsIn4odUgsdUgpIiwiYzgoR0QsQCkiLCJjOChALEd6KSIsInI3KEApIiwiVHo8QD4o
+QCkiLCJFNChAKSIsInZzPEA+KEApIiwiQChALHFVKSIsIlowPHFVLHFVPihaMDxxVSxxVT4scVUpIiwi
+QChxVSkiLCJPNyhPNykiLCJjOChAW0d6XSkiLCJxVShLTikiLCJ+KGtbR3pdKSIsImEyKHh1PHFVPiki
+LCJuNihLTikiXSxpbnRlcmNlcHRvcnNCeVRhZzpudWxsLGxlYWZUYWdzOm51bGx9CkgueGIodi50eXBl
+VW5pdmVyc2UsSlNPTi5wYXJzZSgneyJjNSI6Ik1GIiwiaUMiOiJNRiIsImtkIjoiTUYiLCJyeCI6ImVh
+IiwiZTUiOiJlYSIsIlkwIjoiZDUiLCJXdCI6ImQ1IiwidjAiOiJldyIsIk1yIjoicUUiLCJlTCI6InFF
+IiwiSTAiOiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwieWMiOiJBaiIsInk0IjoidzYiLCJhUCI6IkNt
+IiwieGMiOiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwiZGYiOiJFVCIsInlFIjp7ImEyIjpbXX0sIllF
+Ijp7ImM4IjpbXX0sIk1GIjp7InZtIjpbXSwiRUgiOltdfSwiamQiOnsiek0iOlsiMSJdLCJjWCI6WyIx
+Il19LCJQbyI6eyJqZCI6WyIxIl0sInpNIjpbIjEiXSwiY1giOlsiMSJdfSwibTEiOnsiQW4iOlsiMSJd
+fSwicUkiOnsiQ1AiOltdLCJGSyI6W119LCJ1ciI6eyJLTiI6W10sIkNQIjpbXSwiRksiOltdfSwiVkEi
+OnsiQ1AiOltdLCJGSyI6W119LCJEciI6eyJxVSI6W10sInZYIjpbXX0sInFqIjp7IlJlIjpbIktOIl0s
+ImxEIjpbIktOIl0sInpNIjpbIktOIl0sImNYIjpbIktOIl0sImxELkUiOiJLTiIsIlJlLkUiOiJLTiJ9
+LCJiUSI6eyJjWCI6WyIxIl19LCJhTCI6eyJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImNYIjpb
+IjEiXSwiYUwuRSI6IjEiLCJjWC5FIjoiMSJ9LCJhNyI6eyJBbiI6WyIxIl19LCJBOCI6eyJhTCI6WyIy
+Il0sImNYIjpbIjIiXSwiYUwuRSI6IjIiLCJjWC5FIjoiMiJ9LCJVNSI6eyJjWCI6WyIxIl0sImNYLkUi
+OiIxIn0sIlNPIjp7IkFuIjpbIjEiXX0sIlhDIjp7IlJlIjpbIjEiXSwibEQiOlsiMSJdLCJ6TSI6WyIx
+Il0sImNYIjpbIjEiXX0sInd2Ijp7IkdEIjpbXX0sIlBEIjp7IkdqIjpbIjEiLCIyIl0sIlJVIjpbIjEi
+LCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJXVSI6eyJa
+MCI6WyIxIiwiMiJdfSwiTFAiOnsiV1UiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIkxJIjp7InZR
+IjpbXX0sIlcwIjp7IlhTIjpbXX0sImF6Ijp7IlhTIjpbXX0sInZWIjp7IlhTIjpbXX0sIlhPIjp7Ikd6
+IjpbXX0sIlRwIjp7IkVIIjpbXX0sImxjIjp7IkVIIjpbXX0sInp4Ijp7IkVIIjpbXX0sInJUIjp7IkVI
+IjpbXX0sIkVxIjp7IlhTIjpbXX0sImtZIjp7IlhTIjpbXX0sIk41Ijp7IkZvIjpbIjEiLCIyIl0sIllr
+IjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl0sIllrLksiOiIxIiwiWWsuViI6IjIifSwiaTUiOnsiY1gi
+OlsiMSJdLCJjWC5FIjoiMSJ9LCJONiI6eyJBbiI6WyIxIl19LCJWUiI6eyJ3TCI6W10sInZYIjpbXX0s
+IkVLIjp7ImliIjpbXSwiT2QiOltdfSwiS1ciOnsiY1giOlsiaWIiXSwiY1guRSI6ImliIn0sIlBiIjp7
+IkFuIjpbImliIl19LCJ0USI6eyJPZCI6W119LCJ1biI6eyJjWCI6WyJPZCJdLCJjWC5FIjoiT2QifSwi
+U2QiOnsiQW4iOlsiT2QiXX0sIkVUIjp7IkFTIjpbXX0sImIwIjp7IlhqIjpbIkAiXSwiRVQiOltdLCJB
+UyI6W119LCJEZyI6eyJsRCI6WyJDUCJdLCJYaiI6WyJAIl0sInpNIjpbIkNQIl0sIkVUIjpbXSwiU1Ui
+OlsiQ1AiXSwiQVMiOltdLCJjWCI6WyJDUCJdLCJsRC5FIjoiQ1AifSwiUGciOnsibEQiOlsiS04iXSwi
+ek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04i
+XX0sInhqIjp7ImxEIjpbIktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJTVSI6WyJL
+TiJdLCJBUyI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJkRSI6eyJsRCI6WyJLTiJdLCJ6TSI6
+WyJLTiJdLCJYaiI6WyJAIl0sIkVUIjpbXSwiU1UiOlsiS04iXSwiQVMiOltdLCJjWCI6WyJLTiJdLCJs
+RC5FIjoiS04ifSwiWkEiOnsibEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10s
+IlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0sIndmIjp7ImxEIjpbIktO
+Il0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJTVSI6WyJLTiJdLCJBUyI6W10sImNYIjpb
+IktOIl0sImxELkUiOiJLTiJ9LCJQcSI6eyJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJYaiI6WyJAIl0s
+IkVUIjpbXSwiU1UiOlsiS04iXSwiQVMiOltdLCJjWCI6WyJLTiJdLCJsRC5FIjoiS04ifSwiZUUiOnsi
+bEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sIlNVIjpbIktOIl0sIkFTIjpb
+XSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0sIlY2Ijp7Im42IjpbXSwibEQiOlsiS04iXSwiek0iOlsi
+S04iXSwiWGoiOlsiQCJdLCJFVCI6W10sIlNVIjpbIktOIl0sIkFTIjpbXSwiY1giOlsiS04iXSwibEQu
+RSI6IktOIn0sInU5Ijp7IlhTIjpbXX0sImh6Ijp7IlhTIjpbXX0sImlNIjp7IlhTIjpbXX0sIlpmIjp7
+IlBmIjpbIjEiXX0sInZzIjp7ImI4IjpbIjEiXX0sIkN3Ijp7IlhTIjpbXX0sIm0wIjp7IkpCIjpbXX0s
+IkppIjp7IkpCIjpbXX0sImI2Ijp7Ilh2IjpbIjEiXSwieHUiOlsiMSJdLCJjWCI6WyIxIl19LCJsbSI6
+eyJBbiI6WyIxIl19LCJtVyI6eyJjWCI6WyIxIl19LCJMVSI6eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwi
+Y1giOlsiMSJdfSwiaWwiOnsiWWsiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIllrIjp7IlowIjpb
+IjEiLCIyIl19LCJQbiI6eyJaMCI6WyIxIiwiMiJdfSwiR2oiOnsiUlUiOlsiMSIsIjIiXSwiUG4iOlsi
+MSIsIjIiXSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIlZqIjp7ImxmIjpbIjEiXSwieHUi
+OlsiMSJdLCJjWCI6WyIxIl19LCJYdiI6eyJ4dSI6WyIxIl0sImNYIjpbIjEiXX0sInV3Ijp7IllrIjpb
+InFVIiwiQCJdLCJaMCI6WyJxVSIsIkAiXSwiWWsuSyI6InFVIiwiWWsuViI6IkAifSwiaTgiOnsiYUwi
+OlsicVUiXSwiY1giOlsicVUiXSwiYUwuRSI6InFVIiwiY1guRSI6InFVIn0sIkNWIjp7IlVrIjpbInpN
+PEtOPiIsInFVIl0sIlVrLlMiOiJ6TTxLTj4ifSwiVTgiOnsid0kiOlsiek08S04+IiwicVUiXX0sIlpp
+Ijp7IlVrIjpbInFVIiwiek08S04+Il19LCJieSI6eyJVayI6WyJrIiwicVUiXSwiVWsuUyI6ImsifSwi
+TXgiOnsid0kiOlsicVUiLCJrIl19LCJ1NSI6eyJVayI6WyJxVSIsInpNPEtOPiJdLCJVay5TIjoicVUi
+fSwiRTMiOnsid0kiOlsicVUiLCJ6TTxLTj4iXX0sIkdZIjp7IndJIjpbInpNPEtOPiIsInFVIl19LCJD
+UCI6eyJGSyI6W119LCJDNiI6eyJYUyI6W119LCJuIjp7IlhTIjpbXX0sInUiOnsiWFMiOltdfSwiYkoi
+OnsiWFMiOltdfSwiZVkiOnsiWFMiOltdfSwibXAiOnsiWFMiOltdfSwidWIiOnsiWFMiOltdfSwiZHMi
+OnsiWFMiOltdfSwibGoiOnsiWFMiOltdfSwiVVYiOnsiWFMiOltdfSwiazUiOnsiWFMiOltdfSwiS1ki
+OnsiWFMiOltdfSwiYyI6eyJYUyI6W119LCJLTiI6eyJGSyI6W119LCJ6TSI6eyJjWCI6WyIxIl19LCJp
+YiI6eyJPZCI6W119LCJ4dSI6eyJjWCI6WyIxIl19LCJxVSI6eyJ2WCI6W119LCJSbiI6eyJCTCI6W119
+LCJEbiI6eyJpRCI6W119LCJVZiI6eyJpRCI6W119LCJxZSI6eyJpRCI6W119LCJxRSI6eyJjdiI6W10s
+InVIIjpbXSwiRDAiOltdfSwiR2giOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sImZZIjp7ImN2Ijpb
+XSwidUgiOltdLCJEMCI6W119LCJuQiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiUVAiOnsiY3Yi
+OltdLCJ1SCI6W10sIkQwIjpbXX0sIm54Ijp7InVIIjpbXSwiRDAiOltdfSwiUUYiOnsidUgiOltdLCJE
+MCI6W119LCJJQiI6eyJ0biI6WyJGSyJdfSwid3oiOnsibEQiOlsiMSJdLCJ6TSI6WyIxIl0sImNYIjpb
+IjEiXSwibEQuRSI6IjEifSwiY3YiOnsidUgiOltdLCJEMCI6W119LCJUNSI6eyJBeiI6W119LCJoNCI6
+eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiVmIiOnsidUgiOltdLCJEMCI6W119LCJPNyI6eyJEMCI6
+W119LCJ3YSI6eyJEMCI6W119LCJBaiI6eyJlYSI6W119LCJlNyI6eyJsRCI6WyJ1SCJdLCJ6TSI6WyJ1
+SCJdLCJjWCI6WyJ1SCJdLCJsRC5FIjoidUgifSwidUgiOnsiRDAiOltdfSwiQkgiOnsiR20iOlsidUgi
 XSwibEQiOlsidUgiXSwiek0iOlsidUgiXSwiWGoiOlsidUgiXSwiY1giOlsidUgiXSwibEQuRSI6InVI
-IiwiR20uRSI6InVIIn0sImNmIjp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdfSwiaTci
-OnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFVIl0sIllrLksiOiJxVSIsIllrLlYiOiJxVSJ9
-LCJTeSI6eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXSwiWWsuSyI6InFVIiwiWWsuViI6
-InFVIn0sIkk0Ijp7ImxmIjpbInFVIl0sInh1IjpbInFVIl0sImNYIjpbInFVIl19LCJSTyI6eyJxaCI6
-WyIxIl19LCJDcSI6eyJSTyI6WyIxIl0sInFoIjpbIjEiXX0sInhDIjp7Ik1PIjpbIjEiXX0sIkpRIjp7
-ImtGIjpbXX0sInZEIjp7ImtGIjpbXX0sIm02Ijp7ImtGIjpbXX0sImN0Ijp7ImtGIjpbXX0sIk93Ijp7
-ImtGIjpbXX0sIlc5Ijp7IkFuIjpbIjEiXX0sImRXIjp7InY2IjpbXSwiRDAiOltdfSwibWsiOnsieTAi
-OltdfSwiS28iOnsib24iOltdfSwiQXMiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiY1giOlsicVUi
-XX0sInI3Ijp7IkU0IjpbXX0sIlR6Ijp7ImxEIjpbIjEiXSwiek0iOlsiMSJdLCJFNCI6W10sImNYIjpb
-IjEiXSwibEQuRSI6IjEifSwibmQiOnsiZDUiOltdLCJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiS2Ui
-OnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiY1giOlsicVUiXX0sImQ1Ijp7ImN2IjpbXSwidUgiOltd
-LCJEMCI6W119LCJuNiI6eyJ6TSI6WyJLTiJdLCJBUyI6W10sImNYIjpbIktOIl19LCJYQSI6eyJrRiI6
-W119LCJPRiI6eyJMdSI6W119LCJydSI6eyJMdSI6W119LCJJViI6eyJMdSI6W119fScpKQpILkZGKHYu
-dHlwZVVuaXZlcnNlLEpTT04ucGFyc2UoJ3siYlEiOjEsIlhDIjoxLCJNTyI6MSwia1QiOjIsIm1XIjox
-LCJMVSI6MSwiaWwiOjIsIlZqIjoxLCJuWSI6MSwiV1kiOjEsImNvIjoxfScpKQp2YXIgdT0oZnVuY3Rp
-b24gcnRpaSgpe3ZhciB0PUguTjAKcmV0dXJue2k6dCgiR2giKSxuOnQoIkN3IiksY1I6dCgibkIiKSxk
-OnQoIkF6IiksWTp0KCJRUCIpLGdGOnQoIlBEPEdELEA+IiksaDp0KCJjdiIpLGJVOnQoIlhTIiksQjp0
-KCJlYSIpLGFTOnQoIkQwIiksYzg6dCgiVDUiKSxaOnQoIkVIIiksYzp0KCJiODxAPiIpLHI6dCgiTzci
-KSxJOnQoIlNnIiksbzp0KCJ2USIpLGVoOnQoImNYPHVIPiIpLFg6dCgiY1g8cVU+IiksUjp0KCJjWDxA
-PiIpLGZBOnQoImpkPFNlPiIpLHU6dCgiamQ8ajg+IiksYlA6dCgiamQ8dUY+IiksZmg6dCgiamQ8Wlo+
-Iiksazp0KCJqZDxrRj4iKSxzOnQoImpkPHFVPiIpLGhoOnQoImpkPHlEPiIpLGFKOnQoImpkPHdiPiIp
-LG06dCgiamQ8QD4iKSx0OnQoImpkPEtOPiIpLGVIOnQoInZtIiksZzp0KCJjNSIpLGFVOnQoIlhqPEA+
-IiksYW06dCgiVHo8QD4iKSxlbzp0KCJONTxHRCxAPiIpLHY6dCgiRTQiKSxkejp0KCJoRiIpLGE6dCgi
-ek08cVU+Iiksajp0KCJ6TTxAPiIpLEw6dCgiek08S04+IiksRjp0KCJ1OCIpLGY6dCgiWjA8cVUscVU+
-IiksYjp0KCJaMDxxVSxAPiIpLEc6dCgiWjA8QCxAPiIpLGR2OnQoIkE4PHFVLHFVPiIpLGRvOnQoIkE4
-PHFVLEA+IiksVjp0KCJBaiIpLGREOnQoIkVUIiksYm06dCgiVjYiKSxBOnQoInVIIiksZTp0KCJrRiIp
-LFA6dCgiYzgiKSxLOnQoImsiKSxwOnQoImV3IikscTp0KCJ0bjxGSz4iKSxmdjp0KCJ3TCIpLGF2OnQo
-IkpjIiksZXc6dCgibmQiKSxDOnQoInh1PHFVPiIpLGw6dCgiR3oiKSxOOnQoInFVIiksZEc6dCgicVUo
-cVUpIiksZzc6dCgiZDUiKSxmbzp0KCJHRCIpLGFXOnQoInlZIiksdzp0KCJBUyIpLGdjOnQoIm42Iiks
-YWs6dCgia2QiKSxUOnQoIkdqPHFVLHFVPiIpLEQ6dCgiaUQiKSxjYzp0KCJVNTxxVT4iKSxnNDp0KCJL
-NSIpLGNpOnQoInY2IiksZzI6dCgiQ20iKSxiajp0KCJaZjxPNz4iKSxoOTp0KCJDUSIpLGFjOnQoImU3
-IiksUTp0KCJDcTxBaj4iKSxTOnQoInd6PGN2PiIpLHg6dCgiRmU8QCxAPiIpLGFvOnQoInZzPE83PiIp
-LF86dCgidnM8QD4iKSxmSjp0KCJ2czxLTj4iKSxPOnQoIkpRIiksSjp0KCJibiIpLGNKOnQoImEyIiks
-YWw6dCgiYTIoaykiKSxiQjp0KCJhMihxVSkiKSxiZjp0KCJhMihAKSIpLHo6dCgiQCIpLGZPOnQoIkAo
-KSIpLFU6dCgiQChlYSkiKSx5OnQoIkAoaykiKSxlcDp0KCJAKGssaykiKSxXOnQoIkAoayxHeikiKSxj
-aDp0KCJAKHh1PHFVPikiKSxkTzp0KCJAKHFVKSIpLGI4OnQoIkAoQCxAKSIpLGVnOnQoIktOIiksSDp0
-KCJ+IiksTTp0KCJ+KCkiKSxhbjp0KCJ+KGV3KSIpLEU6dCgifihxVSxxVSkiKSxjQTp0KCJ+KHFVLEAp
-Iil9fSkoKTsoZnVuY3Rpb24gY29uc3RhbnRzKCl7dmFyIHQ9aHVua0hlbHBlcnMubWFrZUNvbnN0TGlz
-dApDLlJZPVcuUVAucHJvdG90eXBlCkMuQlo9Vy5WYi5wcm90b3R5cGUKQy5EdD1XLk83LnByb3RvdHlw
-ZQpDLk9rPUoudkIucHJvdG90eXBlCkMuTm09Si5qZC5wcm90b3R5cGUKQy5qbj1KLnVyLnByb3RvdHlw
-ZQpDLmpOPUouWUUucHJvdG90eXBlCkMuQ0Q9Si5xSS5wcm90b3R5cGUKQy54Qj1KLkRyLnByb3RvdHlw
-ZQpDLkRHPUouYzUucHJvdG90eXBlCkMuRXg9Vy51OC5wcm90b3R5cGUKQy5MdD1XLlNOLnByb3RvdHlw
-ZQpDLlpRPUouaUMucHJvdG90eXBlCkMuSWU9Vy5UYi5wcm90b3R5cGUKQy52Qj1KLmtkLnByb3RvdHlw
-ZQpDLm9sPVcuSzUucHJvdG90eXBlCkMueTg9bmV3IFAuVTgoKQpDLmg5PW5ldyBQLkNWKCkKQy5PND1m
-dW5jdGlvbiBnZXRUYWdGYWxsYmFjayhvKSB7CiAgdmFyIHMgPSBPYmplY3QucHJvdG90eXBlLnRvU3Ry
-aW5nLmNhbGwobyk7CiAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7Cn0KQy5ZcT1m
-dW5jdGlvbigpIHsKICB2YXIgdG9TdHJpbmdGdW5jdGlvbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJp
-bmc7CiAgZnVuY3Rpb24gZ2V0VGFnKG8pIHsKICAgIHZhciBzID0gdG9TdHJpbmdGdW5jdGlvbi5jYWxs
-KG8pOwogICAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7CiAgfQogIGZ1bmN0aW9u
-IGdldFVua25vd25UYWcob2JqZWN0LCB0YWcpIHsKICAgIGlmICgvXkhUTUxbQS1aXS4qRWxlbWVudCQv
-LnRlc3QodGFnKSkgewogICAgICB2YXIgbmFtZSA9IHRvU3RyaW5nRnVuY3Rpb24uY2FsbChvYmplY3Qp
-OwogICAgICBpZiAobmFtZSA9PSAiW29iamVjdCBPYmplY3RdIikgcmV0dXJuIG51bGw7CiAgICAgIHJl
-dHVybiAiSFRNTEVsZW1lbnQiOwogICAgfQogIH0KICBmdW5jdGlvbiBnZXRVbmtub3duVGFnR2VuZXJp
-Y0Jyb3dzZXIob2JqZWN0LCB0YWcpIHsKICAgIGlmIChzZWxmLkhUTUxFbGVtZW50ICYmIG9iamVjdCBp
-bnN0YW5jZW9mIEhUTUxFbGVtZW50KSByZXR1cm4gIkhUTUxFbGVtZW50IjsKICAgIHJldHVybiBnZXRV
-bmtub3duVGFnKG9iamVjdCwgdGFnKTsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnKHRhZykg
-ewogICAgaWYgKHR5cGVvZiB3aW5kb3cgPT0gInVuZGVmaW5lZCIpIHJldHVybiBudWxsOwogICAgaWYg
-KHR5cGVvZiB3aW5kb3dbdGFnXSA9PSAidW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICB2YXIgY29u
-c3RydWN0b3IgPSB3aW5kb3dbdGFnXTsKICAgIGlmICh0eXBlb2YgY29uc3RydWN0b3IgIT0gImZ1bmN0
-aW9uIikgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gY29uc3RydWN0b3IucHJvdG90eXBlOwogIH0KICBm
-dW5jdGlvbiBkaXNjcmltaW5hdG9yKHRhZykgeyByZXR1cm4gbnVsbDsgfQogIHZhciBpc0Jyb3dzZXIg
-PSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiOwogIHJldHVybiB7CiAgICBnZXRUYWc6IGdldFRh
-ZywKICAgIGdldFVua25vd25UYWc6IGlzQnJvd3NlciA/IGdldFVua25vd25UYWdHZW5lcmljQnJvd3Nl
-ciA6IGdldFVua25vd25UYWcsCiAgICBwcm90b3R5cGVGb3JUYWc6IHByb3RvdHlwZUZvclRhZywKICAg
-IGRpc2NyaW1pbmF0b3I6IGRpc2NyaW1pbmF0b3IgfTsKfQpDLndiPWZ1bmN0aW9uKGdldFRhZ0ZhbGxi
-YWNrKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKGhvb2tzKSB7CiAgICBpZiAodHlwZW9mIG5hdmlnYXRvciAh
-PSAib2JqZWN0IikgcmV0dXJuIGhvb2tzOwogICAgdmFyIHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudDsK
-ICAgIGlmICh1YS5pbmRleE9mKCJEdW1wUmVuZGVyVHJlZSIpID49IDApIHJldHVybiBob29rczsKICAg
-IGlmICh1YS5pbmRleE9mKCJDaHJvbWUiKSA+PSAwKSB7CiAgICAgIGZ1bmN0aW9uIGNvbmZpcm0ocCkg
-ewogICAgICAgIHJldHVybiB0eXBlb2Ygd2luZG93ID09ICJvYmplY3QiICYmIHdpbmRvd1twXSAmJiB3
-aW5kb3dbcF0ubmFtZSA9PSBwOwogICAgICB9CiAgICAgIGlmIChjb25maXJtKCJXaW5kb3ciKSAmJiBj
-b25maXJtKCJIVE1MRWxlbWVudCIpKSByZXR1cm4gaG9va3M7CiAgICB9CiAgICBob29rcy5nZXRUYWcg
-PSBnZXRUYWdGYWxsYmFjazsKICB9Owp9CkMuS1U9ZnVuY3Rpb24oaG9va3MpIHsKICBpZiAodHlwZW9m
-IGRhcnRFeHBlcmltZW50YWxGaXh1cEdldFRhZyAhPSAiZnVuY3Rpb24iKSByZXR1cm4gaG9va3M7CiAg
-aG9va3MuZ2V0VGFnID0gZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFnKGhvb2tzLmdldFRhZyk7Cn0K
-Qy5mUT1mdW5jdGlvbihob29rcykgewogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHBy
-b3RvdHlwZUZvclRhZyA9IGhvb2tzLnByb3RvdHlwZUZvclRhZzsKICBmdW5jdGlvbiBnZXRUYWdGaXhl
-ZChvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgaWYgKHRhZyA9PSAiRG9jdW1lbnQiKSB7
-CiAgICAgIGlmICghIW8ueG1sVmVyc2lvbikgcmV0dXJuICIhRG9jdW1lbnQiOwogICAgICByZXR1cm4g
-IiFIVE1MRG9jdW1lbnQiOwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAgZnVuY3Rpb24gcHJvdG90
-eXBlRm9yVGFnRml4ZWQodGFnKSB7CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHJldHVybiBudWxs
-OwogICAgcmV0dXJuIHByb3RvdHlwZUZvclRhZyh0YWcpOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRU
-YWdGaXhlZDsKICBob29rcy5wcm90b3R5cGVGb3JUYWcgPSBwcm90b3R5cGVGb3JUYWdGaXhlZDsKfQpD
-LmRrPWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0g
-Im9iamVjdCIgPyBuYXZpZ2F0b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVzZXJBZ2VudC5pbmRleE9m
-KCJGaXJlZm94IikgPT0gLTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFn
-OwogIHZhciBxdWlja01hcCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAgICAi
-RGF0YVRyYW5zZmVyIjogIkNsaXBib2FyZCIsCiAgICAiR2VvR2VvbG9jYXRpb24iOiAiR2VvbG9jYXRp
-b24iLAogICAgIkxvY2F0aW9uIjogIiFMb2NhdGlvbiIsCiAgICAiV29ya2VyTWVzc2FnZUV2ZW50Ijog
-Ik1lc3NhZ2VFdmVudCIsCiAgICAiWE1MRG9jdW1lbnQiOiAiIURvY3VtZW50In07CiAgZnVuY3Rpb24g
-Z2V0VGFnRmlyZWZveChvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgcmV0dXJuIHF1aWNr
-TWFwW3RhZ10gfHwgdGFnOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdGaXJlZm94Owp9CkMueGk9
-ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIgdXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2Jq
-ZWN0IiA/IG5hdmlnYXRvci51c2VyQWdlbnQgOiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4T2YoIlRy
-aWRlbnQvIikgPT0gLTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwog
-IHZhciBxdWlja01hcCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAgICAiRGF0
-YVRyYW5zZmVyIjogIkNsaXBib2FyZCIsCiAgICAiSFRNTERERWxlbWVudCI6ICJIVE1MRWxlbWVudCIs
-CiAgICAiSFRNTERURWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiSFRNTFBocmFzZUVsZW1lbnQi
-OiAiSFRNTEVsZW1lbnQiLAogICAgIlBvc2l0aW9uIjogIkdlb3Bvc2l0aW9uIgogIH07CiAgZnVuY3Rp
-b24gZ2V0VGFnSUUobykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIHZhciBuZXdUYWcgPSBx
-dWlja01hcFt0YWddOwogICAgaWYgKG5ld1RhZykgcmV0dXJuIG5ld1RhZzsKICAgIGlmICh0YWcgPT0g
-Ik9iamVjdCIpIHsKICAgICAgaWYgKHdpbmRvdy5EYXRhVmlldyAmJiAobyBpbnN0YW5jZW9mIHdpbmRv
-dy5EYXRhVmlldykpIHJldHVybiAiRGF0YVZpZXciOwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAg
-ZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnSUUodGFnKSB7CiAgICB2YXIgY29uc3RydWN0b3IgPSB3aW5k
-b3dbdGFnXTsKICAgIGlmIChjb25zdHJ1Y3RvciA9PSBudWxsKSByZXR1cm4gbnVsbDsKICAgIHJldHVy
-biBjb25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0lFOwogIGhv
-b2tzLnByb3RvdHlwZUZvclRhZyA9IHByb3RvdHlwZUZvclRhZ0lFOwp9CkMuaTc9ZnVuY3Rpb24oaG9v
-a3MpIHsgcmV0dXJuIGhvb2tzOyB9CgpDLkN0PW5ldyBQLmJ5KCkKQy5FcT1uZXcgUC5rNSgpCkMueE09
-bmV3IFAudTUoKQpDLlFrPW5ldyBQLkUzKCkKQy5OVT1uZXcgUC5KaSgpCkMuQTM9bmV3IFAuTXgobnVs
-bCkKQy5HYj1ILlZNKHQoWzEyNywyMDQ3LDY1NTM1LDExMTQxMTFdKSx1LnQpCkMuYWs9SC5WTSh0KFsw
-LDAsMzI3NzYsMzM3OTIsMSwxMDI0MCwwLDBdKSx1LnQpCkMuY209SC5WTSh0KFsiKjo6Y2xhc3MiLCIq
-OjpkaXIiLCIqOjpkcmFnZ2FibGUiLCIqOjpoaWRkZW4iLCIqOjppZCIsIio6OmluZXJ0IiwiKjo6aXRl
-bXByb3AiLCIqOjppdGVtcmVmIiwiKjo6aXRlbXNjb3BlIiwiKjo6bGFuZyIsIio6OnNwZWxsY2hlY2si
-LCIqOjp0aXRsZSIsIio6OnRyYW5zbGF0ZSIsIkE6OmFjY2Vzc2tleSIsIkE6OmNvb3JkcyIsIkE6Omhy
-ZWZsYW5nIiwiQTo6bmFtZSIsIkE6OnNoYXBlIiwiQTo6dGFiaW5kZXgiLCJBOjp0YXJnZXQiLCJBOjp0
-eXBlIiwiQVJFQTo6YWNjZXNza2V5IiwiQVJFQTo6YWx0IiwiQVJFQTo6Y29vcmRzIiwiQVJFQTo6bm9o
-cmVmIiwiQVJFQTo6c2hhcGUiLCJBUkVBOjp0YWJpbmRleCIsIkFSRUE6OnRhcmdldCIsIkFVRElPOjpj
-b250cm9scyIsIkFVRElPOjpsb29wIiwiQVVESU86Om1lZGlhZ3JvdXAiLCJBVURJTzo6bXV0ZWQiLCJB
-VURJTzo6cHJlbG9hZCIsIkJETzo6ZGlyIiwiQk9EWTo6YWxpbmsiLCJCT0RZOjpiZ2NvbG9yIiwiQk9E
-WTo6bGluayIsIkJPRFk6OnRleHQiLCJCT0RZOjp2bGluayIsIkJSOjpjbGVhciIsIkJVVFRPTjo6YWNj
-ZXNza2V5IiwiQlVUVE9OOjpkaXNhYmxlZCIsIkJVVFRPTjo6bmFtZSIsIkJVVFRPTjo6dGFiaW5kZXgi
-LCJCVVRUT046OnR5cGUiLCJCVVRUT046OnZhbHVlIiwiQ0FOVkFTOjpoZWlnaHQiLCJDQU5WQVM6Ondp
-ZHRoIiwiQ0FQVElPTjo6YWxpZ24iLCJDT0w6OmFsaWduIiwiQ09MOjpjaGFyIiwiQ09MOjpjaGFyb2Zm
-IiwiQ09MOjpzcGFuIiwiQ09MOjp2YWxpZ24iLCJDT0w6OndpZHRoIiwiQ09MR1JPVVA6OmFsaWduIiwi
-Q09MR1JPVVA6OmNoYXIiLCJDT0xHUk9VUDo6Y2hhcm9mZiIsIkNPTEdST1VQOjpzcGFuIiwiQ09MR1JP
-VVA6OnZhbGlnbiIsIkNPTEdST1VQOjp3aWR0aCIsIkNPTU1BTkQ6OmNoZWNrZWQiLCJDT01NQU5EOjpj
-b21tYW5kIiwiQ09NTUFORDo6ZGlzYWJsZWQiLCJDT01NQU5EOjpsYWJlbCIsIkNPTU1BTkQ6OnJhZGlv
-Z3JvdXAiLCJDT01NQU5EOjp0eXBlIiwiREFUQTo6dmFsdWUiLCJERUw6OmRhdGV0aW1lIiwiREVUQUlM
-Uzo6b3BlbiIsIkRJUjo6Y29tcGFjdCIsIkRJVjo6YWxpZ24iLCJETDo6Y29tcGFjdCIsIkZJRUxEU0VU
-OjpkaXNhYmxlZCIsIkZPTlQ6OmNvbG9yIiwiRk9OVDo6ZmFjZSIsIkZPTlQ6OnNpemUiLCJGT1JNOjph
-Y2NlcHQiLCJGT1JNOjphdXRvY29tcGxldGUiLCJGT1JNOjplbmN0eXBlIiwiRk9STTo6bWV0aG9kIiwi
-Rk9STTo6bmFtZSIsIkZPUk06Om5vdmFsaWRhdGUiLCJGT1JNOjp0YXJnZXQiLCJGUkFNRTo6bmFtZSIs
-IkgxOjphbGlnbiIsIkgyOjphbGlnbiIsIkgzOjphbGlnbiIsIkg0OjphbGlnbiIsIkg1OjphbGlnbiIs
-Ikg2OjphbGlnbiIsIkhSOjphbGlnbiIsIkhSOjpub3NoYWRlIiwiSFI6OnNpemUiLCJIUjo6d2lkdGgi
-LCJIVE1MOjp2ZXJzaW9uIiwiSUZSQU1FOjphbGlnbiIsIklGUkFNRTo6ZnJhbWVib3JkZXIiLCJJRlJB
-TUU6OmhlaWdodCIsIklGUkFNRTo6bWFyZ2luaGVpZ2h0IiwiSUZSQU1FOjptYXJnaW53aWR0aCIsIklG
-UkFNRTo6d2lkdGgiLCJJTUc6OmFsaWduIiwiSU1HOjphbHQiLCJJTUc6OmJvcmRlciIsIklNRzo6aGVp
-Z2h0IiwiSU1HOjpoc3BhY2UiLCJJTUc6OmlzbWFwIiwiSU1HOjpuYW1lIiwiSU1HOjp1c2VtYXAiLCJJ
-TUc6OnZzcGFjZSIsIklNRzo6d2lkdGgiLCJJTlBVVDo6YWNjZXB0IiwiSU5QVVQ6OmFjY2Vzc2tleSIs
-IklOUFVUOjphbGlnbiIsIklOUFVUOjphbHQiLCJJTlBVVDo6YXV0b2NvbXBsZXRlIiwiSU5QVVQ6OmF1
-dG9mb2N1cyIsIklOUFVUOjpjaGVja2VkIiwiSU5QVVQ6OmRpc2FibGVkIiwiSU5QVVQ6OmlucHV0bW9k
-ZSIsIklOUFVUOjppc21hcCIsIklOUFVUOjpsaXN0IiwiSU5QVVQ6Om1heCIsIklOUFVUOjptYXhsZW5n
-dGgiLCJJTlBVVDo6bWluIiwiSU5QVVQ6Om11bHRpcGxlIiwiSU5QVVQ6Om5hbWUiLCJJTlBVVDo6cGxh
-Y2Vob2xkZXIiLCJJTlBVVDo6cmVhZG9ubHkiLCJJTlBVVDo6cmVxdWlyZWQiLCJJTlBVVDo6c2l6ZSIs
-IklOUFVUOjpzdGVwIiwiSU5QVVQ6OnRhYmluZGV4IiwiSU5QVVQ6OnR5cGUiLCJJTlBVVDo6dXNlbWFw
-IiwiSU5QVVQ6OnZhbHVlIiwiSU5TOjpkYXRldGltZSIsIktFWUdFTjo6ZGlzYWJsZWQiLCJLRVlHRU46
-OmtleXR5cGUiLCJLRVlHRU46Om5hbWUiLCJMQUJFTDo6YWNjZXNza2V5IiwiTEFCRUw6OmZvciIsIkxF
-R0VORDo6YWNjZXNza2V5IiwiTEVHRU5EOjphbGlnbiIsIkxJOjp0eXBlIiwiTEk6OnZhbHVlIiwiTElO
-Szo6c2l6ZXMiLCJNQVA6Om5hbWUiLCJNRU5VOjpjb21wYWN0IiwiTUVOVTo6bGFiZWwiLCJNRU5VOjp0
-eXBlIiwiTUVURVI6OmhpZ2giLCJNRVRFUjo6bG93IiwiTUVURVI6Om1heCIsIk1FVEVSOjptaW4iLCJN
-RVRFUjo6dmFsdWUiLCJPQkpFQ1Q6OnR5cGVtdXN0bWF0Y2giLCJPTDo6Y29tcGFjdCIsIk9MOjpyZXZl
-cnNlZCIsIk9MOjpzdGFydCIsIk9MOjp0eXBlIiwiT1BUR1JPVVA6OmRpc2FibGVkIiwiT1BUR1JPVVA6
-OmxhYmVsIiwiT1BUSU9OOjpkaXNhYmxlZCIsIk9QVElPTjo6bGFiZWwiLCJPUFRJT046OnNlbGVjdGVk
-IiwiT1BUSU9OOjp2YWx1ZSIsIk9VVFBVVDo6Zm9yIiwiT1VUUFVUOjpuYW1lIiwiUDo6YWxpZ24iLCJQ
-UkU6OndpZHRoIiwiUFJPR1JFU1M6Om1heCIsIlBST0dSRVNTOjptaW4iLCJQUk9HUkVTUzo6dmFsdWUi
-LCJTRUxFQ1Q6OmF1dG9jb21wbGV0ZSIsIlNFTEVDVDo6ZGlzYWJsZWQiLCJTRUxFQ1Q6Om11bHRpcGxl
-IiwiU0VMRUNUOjpuYW1lIiwiU0VMRUNUOjpyZXF1aXJlZCIsIlNFTEVDVDo6c2l6ZSIsIlNFTEVDVDo6
-dGFiaW5kZXgiLCJTT1VSQ0U6OnR5cGUiLCJUQUJMRTo6YWxpZ24iLCJUQUJMRTo6Ymdjb2xvciIsIlRB
-QkxFOjpib3JkZXIiLCJUQUJMRTo6Y2VsbHBhZGRpbmciLCJUQUJMRTo6Y2VsbHNwYWNpbmciLCJUQUJM
-RTo6ZnJhbWUiLCJUQUJMRTo6cnVsZXMiLCJUQUJMRTo6c3VtbWFyeSIsIlRBQkxFOjp3aWR0aCIsIlRC
-T0RZOjphbGlnbiIsIlRCT0RZOjpjaGFyIiwiVEJPRFk6OmNoYXJvZmYiLCJUQk9EWTo6dmFsaWduIiwi
-VEQ6OmFiYnIiLCJURDo6YWxpZ24iLCJURDo6YXhpcyIsIlREOjpiZ2NvbG9yIiwiVEQ6OmNoYXIiLCJU
-RDo6Y2hhcm9mZiIsIlREOjpjb2xzcGFuIiwiVEQ6OmhlYWRlcnMiLCJURDo6aGVpZ2h0IiwiVEQ6Om5v
-d3JhcCIsIlREOjpyb3dzcGFuIiwiVEQ6OnNjb3BlIiwiVEQ6OnZhbGlnbiIsIlREOjp3aWR0aCIsIlRF
-WFRBUkVBOjphY2Nlc3NrZXkiLCJURVhUQVJFQTo6YXV0b2NvbXBsZXRlIiwiVEVYVEFSRUE6OmNvbHMi
-LCJURVhUQVJFQTo6ZGlzYWJsZWQiLCJURVhUQVJFQTo6aW5wdXRtb2RlIiwiVEVYVEFSRUE6Om5hbWUi
-LCJURVhUQVJFQTo6cGxhY2Vob2xkZXIiLCJURVhUQVJFQTo6cmVhZG9ubHkiLCJURVhUQVJFQTo6cmVx
-dWlyZWQiLCJURVhUQVJFQTo6cm93cyIsIlRFWFRBUkVBOjp0YWJpbmRleCIsIlRFWFRBUkVBOjp3cmFw
-IiwiVEZPT1Q6OmFsaWduIiwiVEZPT1Q6OmNoYXIiLCJURk9PVDo6Y2hhcm9mZiIsIlRGT09UOjp2YWxp
-Z24iLCJUSDo6YWJiciIsIlRIOjphbGlnbiIsIlRIOjpheGlzIiwiVEg6OmJnY29sb3IiLCJUSDo6Y2hh
-ciIsIlRIOjpjaGFyb2ZmIiwiVEg6OmNvbHNwYW4iLCJUSDo6aGVhZGVycyIsIlRIOjpoZWlnaHQiLCJU
-SDo6bm93cmFwIiwiVEg6OnJvd3NwYW4iLCJUSDo6c2NvcGUiLCJUSDo6dmFsaWduIiwiVEg6OndpZHRo
-IiwiVEhFQUQ6OmFsaWduIiwiVEhFQUQ6OmNoYXIiLCJUSEVBRDo6Y2hhcm9mZiIsIlRIRUFEOjp2YWxp
-Z24iLCJUUjo6YWxpZ24iLCJUUjo6Ymdjb2xvciIsIlRSOjpjaGFyIiwiVFI6OmNoYXJvZmYiLCJUUjo6
-dmFsaWduIiwiVFJBQ0s6OmRlZmF1bHQiLCJUUkFDSzo6a2luZCIsIlRSQUNLOjpsYWJlbCIsIlRSQUNL
-OjpzcmNsYW5nIiwiVUw6OmNvbXBhY3QiLCJVTDo6dHlwZSIsIlZJREVPOjpjb250cm9scyIsIlZJREVP
-OjpoZWlnaHQiLCJWSURFTzo6bG9vcCIsIlZJREVPOjptZWRpYWdyb3VwIiwiVklERU86Om11dGVkIiwi
-VklERU86OnByZWxvYWQiLCJWSURFTzo6d2lkdGgiXSksdS5zKQpDLlZDPUguVk0odChbMCwwLDY1NDkw
-LDQ1MDU1LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50KQpDLm1LPUguVk0odChbMCwwLDI2NjI0
-LDEwMjMsNjU1MzQsMjA0Nyw2NTUzNCwyMDQ3XSksdS50KQpDLlNxPUguVk0odChbIkhFQUQiLCJBUkVB
-IiwiQkFTRSIsIkJBU0VGT05UIiwiQlIiLCJDT0wiLCJDT0xHUk9VUCIsIkVNQkVEIiwiRlJBTUUiLCJG
-UkFNRVNFVCIsIkhSIiwiSU1BR0UiLCJJTUciLCJJTlBVVCIsIklTSU5ERVgiLCJMSU5LIiwiTUVUQSIs
-IlBBUkFNIiwiU09VUkNFIiwiU1RZTEUiLCJUSVRMRSIsIldCUiJdKSx1LnMpCkMueEQ9SC5WTSh0KFtd
-KSx1LnUpCkMuZG49SC5WTSh0KFtdKSx1LnMpCkMuaFU9SC5WTSh0KFtdKSx1Lm0pCkMudG89SC5WTSh0
-KFswLDAsMzI3MjIsMTIyODcsNjU1MzQsMzQ4MTUsNjU1MzQsMTg0MzFdKSx1LnQpCkMuRjM9SC5WTSh0
-KFswLDAsMjQ1NzYsMTAyMyw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5lYT1ILlZNKHQo
-WzAsMCwzMjc1NCwxMTI2Myw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5aSj1ILlZNKHQo
-WzAsMCwzMjcyMiwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5XZD1ILlZNKHQo
-WzAsMCw2NTQ5MCwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5ReD1ILlZNKHQo
-WyJiaW5kIiwiaWYiLCJyZWYiLCJyZXBlYXQiLCJzeW50YXgiXSksdS5zKQpDLkJJPUguVk0odChbIkE6
-OmhyZWYiLCJBUkVBOjpocmVmIiwiQkxPQ0tRVU9URTo6Y2l0ZSIsIkJPRFk6OmJhY2tncm91bmQiLCJD
-T01NQU5EOjppY29uIiwiREVMOjpjaXRlIiwiRk9STTo6YWN0aW9uIiwiSU1HOjpzcmMiLCJJTlBVVDo6
-c3JjIiwiSU5TOjpjaXRlIiwiUTo6Y2l0ZSIsIlZJREVPOjpwb3N0ZXIiXSksdS5zKQpDLldPPW5ldyBI
-LkxQKDAse30sQy5kbixILk4wKCJMUDxxVSxxVT4iKSkKQy5pSD1ILlZNKHQoW10pLEguTjAoImpkPEdE
-PiIpKQpDLkNNPW5ldyBILkxQKDAse30sQy5pSCxILk4wKCJMUDxHRCxAPiIpKQpDLlkyPW5ldyBMLnk4
-KCJOYXZpZ2F0aW9uVHJlZU5vZGVUeXBlLmRpcmVjdG9yeSIpCkMucmY9bmV3IEwueTgoIk5hdmlnYXRp
-b25UcmVlTm9kZVR5cGUuZmlsZSIpCkMuVGU9bmV3IEgud3YoImNhbGwiKX0pKCk7KGZ1bmN0aW9uIHN0
-YXRpY0ZpZWxkcygpeyQueWo9MAokLm1KPW51bGwKJC5QND1udWxsCiQuTkY9bnVsbAokLlRYPW51bGwK
-JC54Nz1udWxsCiQubnc9bnVsbAokLnZ2PW51bGwKJC5Cdj1udWxsCiQuUzY9bnVsbAokLms4PW51bGwK
-JC5tZz1udWxsCiQuVUQ9ITEKJC5YMz1DLk5VCiQueGc9W10KJC54bz1udWxsCiQuQk89bnVsbAokLmx0
-PW51bGwKJC5FVT1udWxsCiQub3I9UC5GbCh1Lk4sdS5aKQokLkk2PW51bGwKJC5GZj1udWxsfSkoKTso
-ZnVuY3Rpb24gbGF6eUluaXRpYWxpemVycygpe3ZhciB0PWh1bmtIZWxwZXJzLmxhenkKdCgkLCJmYSIs
-InciLGZ1bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8kZGFydF9kYXJ0Q2xvc3VyZSIpfSkKdCgkLCJZMiIs
-IlVOIixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfanMiKX0pCnQoJCwiVTIiLCJTbiIsZnVu
-Y3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHsKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4iJHJlY2Vp
-dmVyJCJ9fSkpfSkKdCgkLCJ4cSIsImxxIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzcoeyRtZXRo
-b2QkOm51bGwsCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0pCnQoJCwi
-UjEiLCJOOSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KG51bGwpKX0pCnQoJCwiZk4iLCJpSSIs
-ZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1
-bWVudHMkJwp0cnl7bnVsbC4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHMpe3JldHVybiBz
-Lm1lc3NhZ2V9fSgpKX0pCnQoJCwicWkiLCJLZiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHZv
-aWQgMCkpfSkKdCgkLCJyWiIsIlpoIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dmFy
-ICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXsodm9pZCAwKS4kbWV0aG9kJCgkYXJndW1l
-bnRzRXhwciQpfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwia3EiLCJyTiIsZnVu
-Y3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKG51bGwpKX0pCnQoJCwidHQiLCJjMyIsZnVuY3Rpb24oKXty
-ZXR1cm4gSC5jTShmdW5jdGlvbigpe3RyeXtudWxsLiRtZXRob2QkfWNhdGNoKHMpe3JldHVybiBzLm1l
-c3NhZ2V9fSgpKX0pCnQoJCwiZHQiLCJISyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKHZvaWQg
-MCkpfSkKdCgkLCJBNyIsInIxIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dHJ5eyh2
-b2lkIDApLiRtZXRob2QkfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwiV2MiLCJ1
-dCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5PaigpfSkKdCgkLCJraCIsInJmIixmdW5jdGlvbigpe3JldHVy
-biBQLldJKCl9KQp0KCQsImJ0IiwiVjciLGZ1bmN0aW9uKCl7cmV0dXJuIEguRFEoSC5YRihILlZNKFst
+IiwiR20uRSI6InVIIn0sIlNOIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJldyI6eyJlYSI6W119
+LCJscCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiVGIiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpb
+XX0sIkl2Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJCVCI6eyJjdiI6W10sInVIIjpbXSwiRDAi
+OltdfSwieVkiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sInc2Ijp7ImVhIjpbXX0sIks1Ijp7InY2
+IjpbXSwiRDAiOltdfSwiQ20iOnsiRDAiOltdfSwiQ1EiOnsidUgiOltdLCJEMCI6W119LCJ3NCI6eyJ0
+biI6WyJGSyJdfSwicmgiOnsiR20iOlsidUgiXSwibEQiOlsidUgiXSwiek0iOlsidUgiXSwiWGoiOlsi
+dUgiXSwiY1giOlsidUgiXSwibEQuRSI6InVIIiwiR20uRSI6InVIIn0sImNmIjp7IllrIjpbInFVIiwi
+cVUiXSwiWjAiOlsicVUiLCJxVSJdfSwiaTciOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFV
+Il0sIllrLksiOiJxVSIsIllrLlYiOiJxVSJ9LCJTeSI6eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFV
+IiwicVUiXSwiWWsuSyI6InFVIiwiWWsuViI6InFVIn0sIkk0Ijp7ImxmIjpbInFVIl0sInh1IjpbInFV
+Il0sImNYIjpbInFVIl19LCJSTyI6eyJxaCI6WyIxIl19LCJDcSI6eyJSTyI6WyIxIl0sInFoIjpbIjEi
+XX0sInhDIjp7Ik1PIjpbIjEiXX0sIkpRIjp7ImtGIjpbXX0sInZEIjp7ImtGIjpbXX0sIm02Ijp7ImtG
+IjpbXX0sImN0Ijp7ImtGIjpbXX0sIk93Ijp7ImtGIjpbXX0sIlc5Ijp7IkFuIjpbIjEiXX0sImRXIjp7
+InY2IjpbXSwiRDAiOltdfSwibWsiOnsieTAiOltdfSwiS28iOnsib24iOltdfSwiQXMiOnsibGYiOlsi
+cVUiXSwieHUiOlsicVUiXSwiY1giOlsicVUiXX0sInI3Ijp7IkU0IjpbXX0sIlR6Ijp7ImxEIjpbIjEi
+XSwiek0iOlsiMSJdLCJFNCI6W10sImNYIjpbIjEiXSwibEQuRSI6IjEifSwibmQiOnsiZDUiOltdLCJj
+diI6W10sInVIIjpbXSwiRDAiOltdfSwiS2UiOnsibGYiOlsicVUiXSwieHUiOlsicVUiXSwiY1giOlsi
+cVUiXX0sImQ1Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJuNiI6eyJ6TSI6WyJLTiJdLCJBUyI6
+W10sImNYIjpbIktOIl19LCJYQSI6eyJrRiI6W119LCJPRiI6eyJMdSI6W119LCJydSI6eyJMdSI6W119
+LCJJViI6eyJMdSI6W119fScpKQpILkZGKHYudHlwZVVuaXZlcnNlLEpTT04ucGFyc2UoJ3siYlEiOjEs
+IlhDIjoxLCJNTyI6MSwia1QiOjIsIm1XIjoxLCJMVSI6MSwiaWwiOjIsIlZqIjoxLCJuWSI6MSwiV1ki
+OjEsImNvIjoxfScpKQp2YXIgdT0oZnVuY3Rpb24gcnRpaSgpe3ZhciB0PUguTjAKcmV0dXJue2k6dCgi
+R2giKSxuOnQoIkN3IiksY1I6dCgibkIiKSxkOnQoIkF6IiksWTp0KCJRUCIpLGdGOnQoIlBEPEdELEA+
+IiksaDp0KCJjdiIpLGJVOnQoIlhTIiksQjp0KCJlYSIpLGFTOnQoIkQwIiksYzg6dCgiVDUiKSxaOnQo
+IkVIIiksYzp0KCJiODxAPiIpLHI6dCgiTzciKSxJOnQoIlNnIiksbzp0KCJ2USIpLGVoOnQoImNYPHVI
+PiIpLFg6dCgiY1g8cVU+IiksUjp0KCJjWDxAPiIpLGZBOnQoImpkPFNlPiIpLHU6dCgiamQ8ajg+Iiks
+YlA6dCgiamQ8dUY+IiksZmg6dCgiamQ8Wlo+Iiksazp0KCJqZDxrRj4iKSxzOnQoImpkPHFVPiIpLGho
+OnQoImpkPHlEPiIpLGFKOnQoImpkPHdiPiIpLG06dCgiamQ8QD4iKSx0OnQoImpkPEtOPiIpLGVIOnQo
+InZtIiksZzp0KCJjNSIpLGFVOnQoIlhqPEA+IiksYW06dCgiVHo8QD4iKSxlbzp0KCJONTxHRCxAPiIp
+LHY6dCgiRTQiKSxkejp0KCJoRiIpLGE6dCgiek08cVU+Iiksajp0KCJ6TTxAPiIpLEw6dCgiek08S04+
+IiksRjp0KCJ1OCIpLGY6dCgiWjA8cVUscVU+IiksYjp0KCJaMDxxVSxAPiIpLEc6dCgiWjA8QCxAPiIp
+LGR2OnQoIkE4PHFVLHFVPiIpLGRvOnQoIkE4PHFVLEA+IiksVjp0KCJBaiIpLGREOnQoIkVUIiksYm06
+dCgiVjYiKSxBOnQoInVIIiksZTp0KCJrRiIpLFA6dCgiYzgiKSxLOnQoImsiKSxwOnQoImV3IikscTp0
+KCJ0bjxGSz4iKSxmdjp0KCJ3TCIpLGF2OnQoIkpjIiksZXc6dCgibmQiKSxDOnQoInh1PHFVPiIpLGw6
+dCgiR3oiKSxOOnQoInFVIiksZEc6dCgicVUocVUpIiksZzc6dCgiZDUiKSxmbzp0KCJHRCIpLGFXOnQo
+InlZIiksdzp0KCJBUyIpLGdjOnQoIm42IiksYWs6dCgia2QiKSxUOnQoIkdqPHFVLHFVPiIpLEQ6dCgi
+aUQiKSxjYzp0KCJVNTxxVT4iKSxnNDp0KCJLNSIpLGNpOnQoInY2IiksZzI6dCgiQ20iKSxiajp0KCJa
+ZjxPNz4iKSxoOTp0KCJDUSIpLGFjOnQoImU3IiksUTp0KCJDcTxBaj4iKSxTOnQoInd6PGN2PiIpLHg6
+dCgiRmU8QCxAPiIpLGFvOnQoInZzPE83PiIpLF86dCgidnM8QD4iKSxmSjp0KCJ2czxLTj4iKSxPOnQo
+IkpRIiksSjp0KCJibiIpLGNKOnQoImEyIiksYWw6dCgiYTIoaykiKSxiQjp0KCJhMihxVSkiKSxiZjp0
+KCJhMihAKSIpLHo6dCgiQCIpLGZPOnQoIkAoKSIpLFU6dCgiQChlYSkiKSx5OnQoIkAoaykiKSxlcDp0
+KCJAKGssaykiKSxXOnQoIkAoayxHeikiKSxjaDp0KCJAKHh1PHFVPikiKSxkTzp0KCJAKHFVKSIpLGI4
+OnQoIkAoQCxAKSIpLGVnOnQoIktOIiksSDp0KCJ+IiksTTp0KCJ+KCkiKSxhbjp0KCJ+KGV3KSIpLEU6
+dCgifihxVSxxVSkiKSxjQTp0KCJ+KHFVLEApIil9fSkoKTsoZnVuY3Rpb24gY29uc3RhbnRzKCl7dmFy
+IHQ9aHVua0hlbHBlcnMubWFrZUNvbnN0TGlzdApDLlJZPVcuUVAucHJvdG90eXBlCkMuQlo9Vy5WYi5w
+cm90b3R5cGUKQy5EdD1XLk83LnByb3RvdHlwZQpDLk9rPUoudkIucHJvdG90eXBlCkMuTm09Si5qZC5w
+cm90b3R5cGUKQy5qbj1KLnVyLnByb3RvdHlwZQpDLmpOPUouWUUucHJvdG90eXBlCkMuQ0Q9Si5xSS5w
+cm90b3R5cGUKQy54Qj1KLkRyLnByb3RvdHlwZQpDLkRHPUouYzUucHJvdG90eXBlCkMuRXg9Vy51OC5w
+cm90b3R5cGUKQy5MdD1XLlNOLnByb3RvdHlwZQpDLlpRPUouaUMucHJvdG90eXBlCkMuSWU9Vy5UYi5w
+cm90b3R5cGUKQy52Qj1KLmtkLnByb3RvdHlwZQpDLm9sPVcuSzUucHJvdG90eXBlCkMueTg9bmV3IFAu
+VTgoKQpDLmg5PW5ldyBQLkNWKCkKQy5PND1mdW5jdGlvbiBnZXRUYWdGYWxsYmFjayhvKSB7CiAgdmFy
+IHMgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobyk7CiAgcmV0dXJuIHMuc3Vic3RyaW5n
+KDgsIHMubGVuZ3RoIC0gMSk7Cn0KQy5ZcT1mdW5jdGlvbigpIHsKICB2YXIgdG9TdHJpbmdGdW5jdGlv
+biA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7CiAgZnVuY3Rpb24gZ2V0VGFnKG8pIHsKICAgIHZh
+ciBzID0gdG9TdHJpbmdGdW5jdGlvbi5jYWxsKG8pOwogICAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMu
+bGVuZ3RoIC0gMSk7CiAgfQogIGZ1bmN0aW9uIGdldFVua25vd25UYWcob2JqZWN0LCB0YWcpIHsKICAg
+IGlmICgvXkhUTUxbQS1aXS4qRWxlbWVudCQvLnRlc3QodGFnKSkgewogICAgICB2YXIgbmFtZSA9IHRv
+U3RyaW5nRnVuY3Rpb24uY2FsbChvYmplY3QpOwogICAgICBpZiAobmFtZSA9PSAiW29iamVjdCBPYmpl
+Y3RdIikgcmV0dXJuIG51bGw7CiAgICAgIHJldHVybiAiSFRNTEVsZW1lbnQiOwogICAgfQogIH0KICBm
+dW5jdGlvbiBnZXRVbmtub3duVGFnR2VuZXJpY0Jyb3dzZXIob2JqZWN0LCB0YWcpIHsKICAgIGlmIChz
+ZWxmLkhUTUxFbGVtZW50ICYmIG9iamVjdCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSByZXR1cm4gIkhU
+TUxFbGVtZW50IjsKICAgIHJldHVybiBnZXRVbmtub3duVGFnKG9iamVjdCwgdGFnKTsKICB9CiAgZnVu
+Y3Rpb24gcHJvdG90eXBlRm9yVGFnKHRhZykgewogICAgaWYgKHR5cGVvZiB3aW5kb3cgPT0gInVuZGVm
+aW5lZCIpIHJldHVybiBudWxsOwogICAgaWYgKHR5cGVvZiB3aW5kb3dbdGFnXSA9PSAidW5kZWZpbmVk
+IikgcmV0dXJuIG51bGw7CiAgICB2YXIgY29uc3RydWN0b3IgPSB3aW5kb3dbdGFnXTsKICAgIGlmICh0
+eXBlb2YgY29uc3RydWN0b3IgIT0gImZ1bmN0aW9uIikgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gY29u
+c3RydWN0b3IucHJvdG90eXBlOwogIH0KICBmdW5jdGlvbiBkaXNjcmltaW5hdG9yKHRhZykgeyByZXR1
+cm4gbnVsbDsgfQogIHZhciBpc0Jyb3dzZXIgPSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiOwog
+IHJldHVybiB7CiAgICBnZXRUYWc6IGdldFRhZywKICAgIGdldFVua25vd25UYWc6IGlzQnJvd3NlciA/
+IGdldFVua25vd25UYWdHZW5lcmljQnJvd3NlciA6IGdldFVua25vd25UYWcsCiAgICBwcm90b3R5cGVG
+b3JUYWc6IHByb3RvdHlwZUZvclRhZywKICAgIGRpc2NyaW1pbmF0b3I6IGRpc2NyaW1pbmF0b3IgfTsK
+fQpDLndiPWZ1bmN0aW9uKGdldFRhZ0ZhbGxiYWNrKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKGhvb2tzKSB7
+CiAgICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPSAib2JqZWN0IikgcmV0dXJuIGhvb2tzOwogICAgdmFy
+IHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudDsKICAgIGlmICh1YS5pbmRleE9mKCJEdW1wUmVuZGVyVHJl
+ZSIpID49IDApIHJldHVybiBob29rczsKICAgIGlmICh1YS5pbmRleE9mKCJDaHJvbWUiKSA+PSAwKSB7
+CiAgICAgIGZ1bmN0aW9uIGNvbmZpcm0ocCkgewogICAgICAgIHJldHVybiB0eXBlb2Ygd2luZG93ID09
+ICJvYmplY3QiICYmIHdpbmRvd1twXSAmJiB3aW5kb3dbcF0ubmFtZSA9PSBwOwogICAgICB9CiAgICAg
+IGlmIChjb25maXJtKCJXaW5kb3ciKSAmJiBjb25maXJtKCJIVE1MRWxlbWVudCIpKSByZXR1cm4gaG9v
+a3M7CiAgICB9CiAgICBob29rcy5nZXRUYWcgPSBnZXRUYWdGYWxsYmFjazsKICB9Owp9CkMuS1U9ZnVu
+Y3Rpb24oaG9va3MpIHsKICBpZiAodHlwZW9mIGRhcnRFeHBlcmltZW50YWxGaXh1cEdldFRhZyAhPSAi
+ZnVuY3Rpb24iKSByZXR1cm4gaG9va3M7CiAgaG9va3MuZ2V0VGFnID0gZGFydEV4cGVyaW1lbnRhbEZp
+eHVwR2V0VGFnKGhvb2tzLmdldFRhZyk7Cn0KQy5mUT1mdW5jdGlvbihob29rcykgewogIHZhciBnZXRU
+YWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHByb3RvdHlwZUZvclRhZyA9IGhvb2tzLnByb3RvdHlwZUZv
+clRhZzsKICBmdW5jdGlvbiBnZXRUYWdGaXhlZChvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwog
+ICAgaWYgKHRhZyA9PSAiRG9jdW1lbnQiKSB7CiAgICAgIGlmICghIW8ueG1sVmVyc2lvbikgcmV0dXJu
+ICIhRG9jdW1lbnQiOwogICAgICByZXR1cm4gIiFIVE1MRG9jdW1lbnQiOwogICAgfQogICAgcmV0dXJu
+IHRhZzsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnRml4ZWQodGFnKSB7CiAgICBpZiAodGFn
+ID09ICJEb2N1bWVudCIpIHJldHVybiBudWxsOwogICAgcmV0dXJuIHByb3RvdHlwZUZvclRhZyh0YWcp
+OwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdGaXhlZDsKICBob29rcy5wcm90b3R5cGVGb3JUYWcg
+PSBwcm90b3R5cGVGb3JUYWdGaXhlZDsKfQpDLmRrPWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIHVzZXJB
+Z2VudCA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCIgPyBuYXZpZ2F0b3IudXNlckFnZW50IDog
+IiI7CiAgaWYgKHVzZXJBZ2VudC5pbmRleE9mKCJGaXJlZm94IikgPT0gLTEpIHJldHVybiBob29rczsK
+ICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwogIHZhciBxdWlja01hcCA9IHsKICAgICJCZWZvcmVV
+bmxvYWRFdmVudCI6ICJFdmVudCIsCiAgICAiRGF0YVRyYW5zZmVyIjogIkNsaXBib2FyZCIsCiAgICAi
+R2VvR2VvbG9jYXRpb24iOiAiR2VvbG9jYXRpb24iLAogICAgIkxvY2F0aW9uIjogIiFMb2NhdGlvbiIs
+CiAgICAiV29ya2VyTWVzc2FnZUV2ZW50IjogIk1lc3NhZ2VFdmVudCIsCiAgICAiWE1MRG9jdW1lbnQi
+OiAiIURvY3VtZW50In07CiAgZnVuY3Rpb24gZ2V0VGFnRmlyZWZveChvKSB7CiAgICB2YXIgdGFnID0g
+Z2V0VGFnKG8pOwogICAgcmV0dXJuIHF1aWNrTWFwW3RhZ10gfHwgdGFnOwogIH0KICBob29rcy5nZXRU
+YWcgPSBnZXRUYWdGaXJlZm94Owp9CkMueGk9ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIgdXNlckFnZW50
+ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2JqZWN0IiA/IG5hdmlnYXRvci51c2VyQWdlbnQgOiAiIjsK
+ICBpZiAodXNlckFnZW50LmluZGV4T2YoIlRyaWRlbnQvIikgPT0gLTEpIHJldHVybiBob29rczsKICB2
+YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwogIHZhciBxdWlja01hcCA9IHsKICAgICJCZWZvcmVVbmxv
+YWRFdmVudCI6ICJFdmVudCIsCiAgICAiRGF0YVRyYW5zZmVyIjogIkNsaXBib2FyZCIsCiAgICAiSFRN
+TERERWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiSFRNTERURWxlbWVudCI6ICJIVE1MRWxlbWVu
+dCIsCiAgICAiSFRNTFBocmFzZUVsZW1lbnQiOiAiSFRNTEVsZW1lbnQiLAogICAgIlBvc2l0aW9uIjog
+Ikdlb3Bvc2l0aW9uIgogIH07CiAgZnVuY3Rpb24gZ2V0VGFnSUUobykgewogICAgdmFyIHRhZyA9IGdl
+dFRhZyhvKTsKICAgIHZhciBuZXdUYWcgPSBxdWlja01hcFt0YWddOwogICAgaWYgKG5ld1RhZykgcmV0
+dXJuIG5ld1RhZzsKICAgIGlmICh0YWcgPT0gIk9iamVjdCIpIHsKICAgICAgaWYgKHdpbmRvdy5EYXRh
+VmlldyAmJiAobyBpbnN0YW5jZW9mIHdpbmRvdy5EYXRhVmlldykpIHJldHVybiAiRGF0YVZpZXciOwog
+ICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnSUUodGFnKSB7
+CiAgICB2YXIgY29uc3RydWN0b3IgPSB3aW5kb3dbdGFnXTsKICAgIGlmIChjb25zdHJ1Y3RvciA9PSBu
+dWxsKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBjb25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAgfQogIGhv
+b2tzLmdldFRhZyA9IGdldFRhZ0lFOwogIGhvb2tzLnByb3RvdHlwZUZvclRhZyA9IHByb3RvdHlwZUZv
+clRhZ0lFOwp9CkMuaTc9ZnVuY3Rpb24oaG9va3MpIHsgcmV0dXJuIGhvb2tzOyB9CgpDLkN0PW5ldyBQ
+LmJ5KCkKQy5FcT1uZXcgUC5rNSgpCkMueE09bmV3IFAudTUoKQpDLlFrPW5ldyBQLkUzKCkKQy5OVT1u
+ZXcgUC5KaSgpCkMuQTM9bmV3IFAuTXgobnVsbCkKQy5HYj1ILlZNKHQoWzEyNywyMDQ3LDY1NTM1LDEx
+MTQxMTFdKSx1LnQpCkMuYWs9SC5WTSh0KFswLDAsMzI3NzYsMzM3OTIsMSwxMDI0MCwwLDBdKSx1LnQp
+CkMuY209SC5WTSh0KFsiKjo6Y2xhc3MiLCIqOjpkaXIiLCIqOjpkcmFnZ2FibGUiLCIqOjpoaWRkZW4i
+LCIqOjppZCIsIio6OmluZXJ0IiwiKjo6aXRlbXByb3AiLCIqOjppdGVtcmVmIiwiKjo6aXRlbXNjb3Bl
+IiwiKjo6bGFuZyIsIio6OnNwZWxsY2hlY2siLCIqOjp0aXRsZSIsIio6OnRyYW5zbGF0ZSIsIkE6OmFj
+Y2Vzc2tleSIsIkE6OmNvb3JkcyIsIkE6OmhyZWZsYW5nIiwiQTo6bmFtZSIsIkE6OnNoYXBlIiwiQTo6
+dGFiaW5kZXgiLCJBOjp0YXJnZXQiLCJBOjp0eXBlIiwiQVJFQTo6YWNjZXNza2V5IiwiQVJFQTo6YWx0
+IiwiQVJFQTo6Y29vcmRzIiwiQVJFQTo6bm9ocmVmIiwiQVJFQTo6c2hhcGUiLCJBUkVBOjp0YWJpbmRl
+eCIsIkFSRUE6OnRhcmdldCIsIkFVRElPOjpjb250cm9scyIsIkFVRElPOjpsb29wIiwiQVVESU86Om1l
+ZGlhZ3JvdXAiLCJBVURJTzo6bXV0ZWQiLCJBVURJTzo6cHJlbG9hZCIsIkJETzo6ZGlyIiwiQk9EWTo6
+YWxpbmsiLCJCT0RZOjpiZ2NvbG9yIiwiQk9EWTo6bGluayIsIkJPRFk6OnRleHQiLCJCT0RZOjp2bGlu
+ayIsIkJSOjpjbGVhciIsIkJVVFRPTjo6YWNjZXNza2V5IiwiQlVUVE9OOjpkaXNhYmxlZCIsIkJVVFRP
+Tjo6bmFtZSIsIkJVVFRPTjo6dGFiaW5kZXgiLCJCVVRUT046OnR5cGUiLCJCVVRUT046OnZhbHVlIiwi
+Q0FOVkFTOjpoZWlnaHQiLCJDQU5WQVM6OndpZHRoIiwiQ0FQVElPTjo6YWxpZ24iLCJDT0w6OmFsaWdu
+IiwiQ09MOjpjaGFyIiwiQ09MOjpjaGFyb2ZmIiwiQ09MOjpzcGFuIiwiQ09MOjp2YWxpZ24iLCJDT0w6
+OndpZHRoIiwiQ09MR1JPVVA6OmFsaWduIiwiQ09MR1JPVVA6OmNoYXIiLCJDT0xHUk9VUDo6Y2hhcm9m
+ZiIsIkNPTEdST1VQOjpzcGFuIiwiQ09MR1JPVVA6OnZhbGlnbiIsIkNPTEdST1VQOjp3aWR0aCIsIkNP
+TU1BTkQ6OmNoZWNrZWQiLCJDT01NQU5EOjpjb21tYW5kIiwiQ09NTUFORDo6ZGlzYWJsZWQiLCJDT01N
+QU5EOjpsYWJlbCIsIkNPTU1BTkQ6OnJhZGlvZ3JvdXAiLCJDT01NQU5EOjp0eXBlIiwiREFUQTo6dmFs
+dWUiLCJERUw6OmRhdGV0aW1lIiwiREVUQUlMUzo6b3BlbiIsIkRJUjo6Y29tcGFjdCIsIkRJVjo6YWxp
+Z24iLCJETDo6Y29tcGFjdCIsIkZJRUxEU0VUOjpkaXNhYmxlZCIsIkZPTlQ6OmNvbG9yIiwiRk9OVDo6
+ZmFjZSIsIkZPTlQ6OnNpemUiLCJGT1JNOjphY2NlcHQiLCJGT1JNOjphdXRvY29tcGxldGUiLCJGT1JN
+OjplbmN0eXBlIiwiRk9STTo6bWV0aG9kIiwiRk9STTo6bmFtZSIsIkZPUk06Om5vdmFsaWRhdGUiLCJG
+T1JNOjp0YXJnZXQiLCJGUkFNRTo6bmFtZSIsIkgxOjphbGlnbiIsIkgyOjphbGlnbiIsIkgzOjphbGln
+biIsIkg0OjphbGlnbiIsIkg1OjphbGlnbiIsIkg2OjphbGlnbiIsIkhSOjphbGlnbiIsIkhSOjpub3No
+YWRlIiwiSFI6OnNpemUiLCJIUjo6d2lkdGgiLCJIVE1MOjp2ZXJzaW9uIiwiSUZSQU1FOjphbGlnbiIs
+IklGUkFNRTo6ZnJhbWVib3JkZXIiLCJJRlJBTUU6OmhlaWdodCIsIklGUkFNRTo6bWFyZ2luaGVpZ2h0
+IiwiSUZSQU1FOjptYXJnaW53aWR0aCIsIklGUkFNRTo6d2lkdGgiLCJJTUc6OmFsaWduIiwiSU1HOjph
+bHQiLCJJTUc6OmJvcmRlciIsIklNRzo6aGVpZ2h0IiwiSU1HOjpoc3BhY2UiLCJJTUc6OmlzbWFwIiwi
+SU1HOjpuYW1lIiwiSU1HOjp1c2VtYXAiLCJJTUc6OnZzcGFjZSIsIklNRzo6d2lkdGgiLCJJTlBVVDo6
+YWNjZXB0IiwiSU5QVVQ6OmFjY2Vzc2tleSIsIklOUFVUOjphbGlnbiIsIklOUFVUOjphbHQiLCJJTlBV
+VDo6YXV0b2NvbXBsZXRlIiwiSU5QVVQ6OmF1dG9mb2N1cyIsIklOUFVUOjpjaGVja2VkIiwiSU5QVVQ6
+OmRpc2FibGVkIiwiSU5QVVQ6OmlucHV0bW9kZSIsIklOUFVUOjppc21hcCIsIklOUFVUOjpsaXN0Iiwi
+SU5QVVQ6Om1heCIsIklOUFVUOjptYXhsZW5ndGgiLCJJTlBVVDo6bWluIiwiSU5QVVQ6Om11bHRpcGxl
+IiwiSU5QVVQ6Om5hbWUiLCJJTlBVVDo6cGxhY2Vob2xkZXIiLCJJTlBVVDo6cmVhZG9ubHkiLCJJTlBV
+VDo6cmVxdWlyZWQiLCJJTlBVVDo6c2l6ZSIsIklOUFVUOjpzdGVwIiwiSU5QVVQ6OnRhYmluZGV4Iiwi
+SU5QVVQ6OnR5cGUiLCJJTlBVVDo6dXNlbWFwIiwiSU5QVVQ6OnZhbHVlIiwiSU5TOjpkYXRldGltZSIs
+IktFWUdFTjo6ZGlzYWJsZWQiLCJLRVlHRU46OmtleXR5cGUiLCJLRVlHRU46Om5hbWUiLCJMQUJFTDo6
+YWNjZXNza2V5IiwiTEFCRUw6OmZvciIsIkxFR0VORDo6YWNjZXNza2V5IiwiTEVHRU5EOjphbGlnbiIs
+IkxJOjp0eXBlIiwiTEk6OnZhbHVlIiwiTElOSzo6c2l6ZXMiLCJNQVA6Om5hbWUiLCJNRU5VOjpjb21w
+YWN0IiwiTUVOVTo6bGFiZWwiLCJNRU5VOjp0eXBlIiwiTUVURVI6OmhpZ2giLCJNRVRFUjo6bG93Iiwi
+TUVURVI6Om1heCIsIk1FVEVSOjptaW4iLCJNRVRFUjo6dmFsdWUiLCJPQkpFQ1Q6OnR5cGVtdXN0bWF0
+Y2giLCJPTDo6Y29tcGFjdCIsIk9MOjpyZXZlcnNlZCIsIk9MOjpzdGFydCIsIk9MOjp0eXBlIiwiT1BU
+R1JPVVA6OmRpc2FibGVkIiwiT1BUR1JPVVA6OmxhYmVsIiwiT1BUSU9OOjpkaXNhYmxlZCIsIk9QVElP
+Tjo6bGFiZWwiLCJPUFRJT046OnNlbGVjdGVkIiwiT1BUSU9OOjp2YWx1ZSIsIk9VVFBVVDo6Zm9yIiwi
+T1VUUFVUOjpuYW1lIiwiUDo6YWxpZ24iLCJQUkU6OndpZHRoIiwiUFJPR1JFU1M6Om1heCIsIlBST0dS
+RVNTOjptaW4iLCJQUk9HUkVTUzo6dmFsdWUiLCJTRUxFQ1Q6OmF1dG9jb21wbGV0ZSIsIlNFTEVDVDo6
+ZGlzYWJsZWQiLCJTRUxFQ1Q6Om11bHRpcGxlIiwiU0VMRUNUOjpuYW1lIiwiU0VMRUNUOjpyZXF1aXJl
+ZCIsIlNFTEVDVDo6c2l6ZSIsIlNFTEVDVDo6dGFiaW5kZXgiLCJTT1VSQ0U6OnR5cGUiLCJUQUJMRTo6
+YWxpZ24iLCJUQUJMRTo6Ymdjb2xvciIsIlRBQkxFOjpib3JkZXIiLCJUQUJMRTo6Y2VsbHBhZGRpbmci
+LCJUQUJMRTo6Y2VsbHNwYWNpbmciLCJUQUJMRTo6ZnJhbWUiLCJUQUJMRTo6cnVsZXMiLCJUQUJMRTo6
+c3VtbWFyeSIsIlRBQkxFOjp3aWR0aCIsIlRCT0RZOjphbGlnbiIsIlRCT0RZOjpjaGFyIiwiVEJPRFk6
+OmNoYXJvZmYiLCJUQk9EWTo6dmFsaWduIiwiVEQ6OmFiYnIiLCJURDo6YWxpZ24iLCJURDo6YXhpcyIs
+IlREOjpiZ2NvbG9yIiwiVEQ6OmNoYXIiLCJURDo6Y2hhcm9mZiIsIlREOjpjb2xzcGFuIiwiVEQ6Omhl
+YWRlcnMiLCJURDo6aGVpZ2h0IiwiVEQ6Om5vd3JhcCIsIlREOjpyb3dzcGFuIiwiVEQ6OnNjb3BlIiwi
+VEQ6OnZhbGlnbiIsIlREOjp3aWR0aCIsIlRFWFRBUkVBOjphY2Nlc3NrZXkiLCJURVhUQVJFQTo6YXV0
+b2NvbXBsZXRlIiwiVEVYVEFSRUE6OmNvbHMiLCJURVhUQVJFQTo6ZGlzYWJsZWQiLCJURVhUQVJFQTo6
+aW5wdXRtb2RlIiwiVEVYVEFSRUE6Om5hbWUiLCJURVhUQVJFQTo6cGxhY2Vob2xkZXIiLCJURVhUQVJF
+QTo6cmVhZG9ubHkiLCJURVhUQVJFQTo6cmVxdWlyZWQiLCJURVhUQVJFQTo6cm93cyIsIlRFWFRBUkVB
+Ojp0YWJpbmRleCIsIlRFWFRBUkVBOjp3cmFwIiwiVEZPT1Q6OmFsaWduIiwiVEZPT1Q6OmNoYXIiLCJU
+Rk9PVDo6Y2hhcm9mZiIsIlRGT09UOjp2YWxpZ24iLCJUSDo6YWJiciIsIlRIOjphbGlnbiIsIlRIOjph
+eGlzIiwiVEg6OmJnY29sb3IiLCJUSDo6Y2hhciIsIlRIOjpjaGFyb2ZmIiwiVEg6OmNvbHNwYW4iLCJU
+SDo6aGVhZGVycyIsIlRIOjpoZWlnaHQiLCJUSDo6bm93cmFwIiwiVEg6OnJvd3NwYW4iLCJUSDo6c2Nv
+cGUiLCJUSDo6dmFsaWduIiwiVEg6OndpZHRoIiwiVEhFQUQ6OmFsaWduIiwiVEhFQUQ6OmNoYXIiLCJU
+SEVBRDo6Y2hhcm9mZiIsIlRIRUFEOjp2YWxpZ24iLCJUUjo6YWxpZ24iLCJUUjo6Ymdjb2xvciIsIlRS
+OjpjaGFyIiwiVFI6OmNoYXJvZmYiLCJUUjo6dmFsaWduIiwiVFJBQ0s6OmRlZmF1bHQiLCJUUkFDSzo6
+a2luZCIsIlRSQUNLOjpsYWJlbCIsIlRSQUNLOjpzcmNsYW5nIiwiVUw6OmNvbXBhY3QiLCJVTDo6dHlw
+ZSIsIlZJREVPOjpjb250cm9scyIsIlZJREVPOjpoZWlnaHQiLCJWSURFTzo6bG9vcCIsIlZJREVPOjpt
+ZWRpYWdyb3VwIiwiVklERU86Om11dGVkIiwiVklERU86OnByZWxvYWQiLCJWSURFTzo6d2lkdGgiXSks
+dS5zKQpDLlZDPUguVk0odChbMCwwLDY1NDkwLDQ1MDU1LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSks
+dS50KQpDLm1LPUguVk0odChbMCwwLDI2NjI0LDEwMjMsNjU1MzQsMjA0Nyw2NTUzNCwyMDQ3XSksdS50
+KQpDLlNxPUguVk0odChbIkhFQUQiLCJBUkVBIiwiQkFTRSIsIkJBU0VGT05UIiwiQlIiLCJDT0wiLCJD
+T0xHUk9VUCIsIkVNQkVEIiwiRlJBTUUiLCJGUkFNRVNFVCIsIkhSIiwiSU1BR0UiLCJJTUciLCJJTlBV
+VCIsIklTSU5ERVgiLCJMSU5LIiwiTUVUQSIsIlBBUkFNIiwiU09VUkNFIiwiU1RZTEUiLCJUSVRMRSIs
+IldCUiJdKSx1LnMpCkMueEQ9SC5WTSh0KFtdKSx1LnUpCkMuZG49SC5WTSh0KFtdKSx1LnMpCkMuaFU9
+SC5WTSh0KFtdKSx1Lm0pCkMudG89SC5WTSh0KFswLDAsMzI3MjIsMTIyODcsNjU1MzQsMzQ4MTUsNjU1
+MzQsMTg0MzFdKSx1LnQpCkMuRjM9SC5WTSh0KFswLDAsMjQ1NzYsMTAyMyw2NTUzNCwzNDgxNSw2NTUz
+NCwxODQzMV0pLHUudCkKQy5lYT1ILlZNKHQoWzAsMCwzMjc1NCwxMTI2Myw2NTUzNCwzNDgxNSw2NTUz
+NCwxODQzMV0pLHUudCkKQy5aSj1ILlZNKHQoWzAsMCwzMjcyMiwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUz
+NCwxODQzMV0pLHUudCkKQy5XZD1ILlZNKHQoWzAsMCw2NTQ5MCwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUz
+NCwxODQzMV0pLHUudCkKQy5ReD1ILlZNKHQoWyJiaW5kIiwiaWYiLCJyZWYiLCJyZXBlYXQiLCJzeW50
+YXgiXSksdS5zKQpDLkJJPUguVk0odChbIkE6OmhyZWYiLCJBUkVBOjpocmVmIiwiQkxPQ0tRVU9URTo6
+Y2l0ZSIsIkJPRFk6OmJhY2tncm91bmQiLCJDT01NQU5EOjppY29uIiwiREVMOjpjaXRlIiwiRk9STTo6
+YWN0aW9uIiwiSU1HOjpzcmMiLCJJTlBVVDo6c3JjIiwiSU5TOjpjaXRlIiwiUTo6Y2l0ZSIsIlZJREVP
+Ojpwb3N0ZXIiXSksdS5zKQpDLldPPW5ldyBILkxQKDAse30sQy5kbixILk4wKCJMUDxxVSxxVT4iKSkK
+Qy5pSD1ILlZNKHQoW10pLEguTjAoImpkPEdEPiIpKQpDLkNNPW5ldyBILkxQKDAse30sQy5pSCxILk4w
+KCJMUDxHRCxAPiIpKQpDLlkyPW5ldyBMLnk4KCJOYXZpZ2F0aW9uVHJlZU5vZGVUeXBlLmRpcmVjdG9y
+eSIpCkMucmY9bmV3IEwueTgoIk5hdmlnYXRpb25UcmVlTm9kZVR5cGUuZmlsZSIpCkMuVGU9bmV3IEgu
+d3YoImNhbGwiKX0pKCk7KGZ1bmN0aW9uIHN0YXRpY0ZpZWxkcygpeyQueWo9MAokLm1KPW51bGwKJC5Q
+ND1udWxsCiQuTkY9bnVsbAokLlRYPW51bGwKJC54Nz1udWxsCiQubnc9bnVsbAokLnZ2PW51bGwKJC5C
+dj1udWxsCiQuUzY9bnVsbAokLms4PW51bGwKJC5tZz1udWxsCiQuVUQ9ITEKJC5YMz1DLk5VCiQueGc9
+W10KJC54bz1udWxsCiQuQk89bnVsbAokLmx0PW51bGwKJC5FVT1udWxsCiQub3I9UC5GbCh1Lk4sdS5a
+KQokLkk2PW51bGwKJC5GZj1udWxsfSkoKTsoZnVuY3Rpb24gbGF6eUluaXRpYWxpemVycygpe3ZhciB0
+PWh1bmtIZWxwZXJzLmxhenkKdCgkLCJmYSIsInciLGZ1bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8kZGFy
+dF9kYXJ0Q2xvc3VyZSIpfSkKdCgkLCJZMiIsIlVOIixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRh
+cnRfanMiKX0pCnQoJCwiVTIiLCJTbiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHsKdG9TdHJp
+bmc6ZnVuY3Rpb24oKXtyZXR1cm4iJHJlY2VpdmVyJCJ9fSkpfSkKdCgkLCJ4cSIsImxxIixmdW5jdGlv
+bigpe3JldHVybiBILmNNKEguUzcoeyRtZXRob2QkOm51bGwsCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0
+dXJuIiRyZWNlaXZlciQifX0pKX0pCnQoJCwiUjEiLCJOOSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShI
+LlM3KG51bGwpKX0pCnQoJCwiZk4iLCJpSSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigp
+e3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7bnVsbC4kbWV0aG9kJCgkYXJndW1l
+bnRzRXhwciQpfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwicWkiLCJLZiIsZnVu
+Y3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHZvaWQgMCkpfSkKdCgkLCJyWiIsIlpoIixmdW5jdGlvbigp
+e3JldHVybiBILmNNKGZ1bmN0aW9uKCl7dmFyICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRy
+eXsodm9pZCAwKS4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHMpe3JldHVybiBzLm1lc3Nh
+Z2V9fSgpKX0pCnQoJCwia3EiLCJyTiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKG51bGwpKX0p
+CnQoJCwidHQiLCJjMyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3RyeXtudWxsLiRt
+ZXRob2QkfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwiZHQiLCJISyIsZnVuY3Rp
+b24oKXtyZXR1cm4gSC5jTShILk1qKHZvaWQgMCkpfSkKdCgkLCJBNyIsInIxIixmdW5jdGlvbigpe3Jl
+dHVybiBILmNNKGZ1bmN0aW9uKCl7dHJ5eyh2b2lkIDApLiRtZXRob2QkfWNhdGNoKHMpe3JldHVybiBz
+Lm1lc3NhZ2V9fSgpKX0pCnQoJCwiV2MiLCJ1dCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5PaigpfSkKdCgk
+LCJraCIsInJmIixmdW5jdGlvbigpe3JldHVybiBQLldJKCl9KQp0KCQsImJ0IiwiVjciLGZ1bmN0aW9u
+KCl7cmV0dXJuIEguRFEoSC5YRihILlZNKFstMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
 MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
-MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMSwtMiwtMiwt
-MiwtMiwtMiw2MiwtMiw2MiwtMiw2Myw1Miw1Myw1NCw1NSw1Niw1Nyw1OCw1OSw2MCw2MSwtMiwtMiwt
-MiwtMSwtMiwtMiwtMiwwLDEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4
-LDE5LDIwLDIxLDIyLDIzLDI0LDI1LC0yLC0yLC0yLC0yLDYzLC0yLDI2LDI3LDI4LDI5LDMwLDMxLDMy
-LDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQwLDQxLDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLC0y
-LC0yLC0yLC0yLC0yXSx1LnQpKSl9KQp0KCQsIk01Iiwid1EiLGZ1bmN0aW9uKCl7cmV0dXJuIHR5cGVv
-ZiBwcm9jZXNzIT0idW5kZWZpbmVkIiYmT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHByb2Nl
-c3MpPT0iW29iamVjdCBwcm9jZXNzXSImJnByb2Nlc3MucGxhdGZvcm09PSJ3aW4zMiJ9KQp0KCQsIm1m
-IiwiejQiLGZ1bmN0aW9uKCl7cmV0dXJuIFAubnUoIl5bXFwtXFwuMC05QS1aX2Eten5dKiQiKX0pCnQo
-JCwiSkciLCJ2WiIsZnVuY3Rpb24oKXtyZXR1cm4gUC51eCgpfSkKdCgkLCJTQyIsIkFOIixmdW5jdGlv
-bigpe3JldHVybiBQLnRNKFsiQSIsIkFCQlIiLCJBQ1JPTllNIiwiQUREUkVTUyIsIkFSRUEiLCJBUlRJ
-Q0xFIiwiQVNJREUiLCJBVURJTyIsIkIiLCJCREkiLCJCRE8iLCJCSUciLCJCTE9DS1FVT1RFIiwiQlIi
-LCJCVVRUT04iLCJDQU5WQVMiLCJDQVBUSU9OIiwiQ0VOVEVSIiwiQ0lURSIsIkNPREUiLCJDT0wiLCJD
-T0xHUk9VUCIsIkNPTU1BTkQiLCJEQVRBIiwiREFUQUxJU1QiLCJERCIsIkRFTCIsIkRFVEFJTFMiLCJE
-Rk4iLCJESVIiLCJESVYiLCJETCIsIkRUIiwiRU0iLCJGSUVMRFNFVCIsIkZJR0NBUFRJT04iLCJGSUdV
-UkUiLCJGT05UIiwiRk9PVEVSIiwiRk9STSIsIkgxIiwiSDIiLCJIMyIsIkg0IiwiSDUiLCJINiIsIkhF
-QURFUiIsIkhHUk9VUCIsIkhSIiwiSSIsIklGUkFNRSIsIklNRyIsIklOUFVUIiwiSU5TIiwiS0JEIiwi
-TEFCRUwiLCJMRUdFTkQiLCJMSSIsIk1BUCIsIk1BUksiLCJNRU5VIiwiTUVURVIiLCJOQVYiLCJOT0JS
-IiwiT0wiLCJPUFRHUk9VUCIsIk9QVElPTiIsIk9VVFBVVCIsIlAiLCJQUkUiLCJQUk9HUkVTUyIsIlEi
-LCJTIiwiU0FNUCIsIlNFQ1RJT04iLCJTRUxFQ1QiLCJTTUFMTCIsIlNPVVJDRSIsIlNQQU4iLCJTVFJJ
-S0UiLCJTVFJPTkciLCJTVUIiLCJTVU1NQVJZIiwiU1VQIiwiVEFCTEUiLCJUQk9EWSIsIlREIiwiVEVY
-VEFSRUEiLCJURk9PVCIsIlRIIiwiVEhFQUQiLCJUSU1FIiwiVFIiLCJUUkFDSyIsIlRUIiwiVSIsIlVM
-IiwiVkFSIiwiVklERU8iLCJXQlIiXSx1Lk4pfSkKdCgkLCJYNCIsImhHIixmdW5jdGlvbigpe3JldHVy
-biBQLm51KCJeXFxTKyQiKX0pCnQoJCwid08iLCJvdyIsZnVuY3Rpb24oKXtyZXR1cm4gdS52LmIoUC5O
-RChzZWxmKSl9KQp0KCQsImt0IiwiUjgiLGZ1bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8kZGFydF9kYXJ0
-T2JqZWN0Iil9KQp0KCQsImZLIiwia0kiLGZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uIERhcnRPYmpl
-Y3QoYSl7dGhpcy5vPWF9fSkKdCgkLCJxdCIsInpCIixmdW5jdGlvbigpe3JldHVybiBuZXcgVC5HVigp
-fSkKdCgkLCJFWSIsImZpIixmdW5jdGlvbigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiaGVh
-ZGVyIil9KQp0KCQsIlRSIiwiRFciLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9y
-KCJmb290ZXIiKX0pCnQoJCwiVzYiLCJoTCIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2Vs
-ZWN0b3IoIi5lZGl0LXBhbmVsIC5wYW5lbC1jb250ZW50Iil9KQp0KCQsImhUIiwibVEiLGZ1bmN0aW9u
-KCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIuZWRpdC1saXN0IC5wYW5lbC1jb250ZW50Iil9
-KQp0KCQsImF2IiwiRDkiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjdW5p
-dC1uYW1lIil9KQp0KCQsImZlIiwiS0ciLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLlhBKCl9KQp0KCQs
-Im1NIiwiblUiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBNLmxJKCQuSGsoKSl9KQp0KCQsInlyIiwiYkQi
-LGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBFLk9GKFAubnUoIi8iKSxQLm51KCJbXi9dJCIpLFAubnUoIl4v
-IikpfSkKdCgkLCJNayIsIktrIixmdW5jdGlvbigpe3JldHVybiBuZXcgTC5JVihQLm51KCJbL1xcXFxd
-IiksUC5udSgiW14vXFxcXF0kIiksUC5udSgiXihcXFxcXFxcXFteXFxcXF0rXFxcXFteXFxcXC9dK3xb
-YS16QS1aXTpbL1xcXFxdKSIpLFAubnUoIl5bL1xcXFxdKD8hWy9cXFxcXSkiKSl9KQp0KCQsImFrIiwi
-RWIiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBGLnJ1KFAubnUoIi8iKSxQLm51KCIoXlthLXpBLVpdWy0r
-LmEtekEtWlxcZF0qOi8vfFteL10pJCIpLFAubnUoIlthLXpBLVpdWy0rLmEtekEtWlxcZF0qOi8vW14v
-XSoiKSxQLm51KCJeLyIpKX0pCnQoJCwibHMiLCJIayIsZnVuY3Rpb24oKXtyZXR1cm4gTy5SaCgpfSl9
-KSgpOyhmdW5jdGlvbiBuYXRpdmVTdXBwb3J0KCl7IWZ1bmN0aW9uKCl7dmFyIHQ9ZnVuY3Rpb24oYSl7
-dmFyIG49e30KblthXT0xCnJldHVybiBPYmplY3Qua2V5cyhodW5rSGVscGVycy5jb252ZXJ0VG9GYXN0
-T2JqZWN0KG4pKVswXX0Kdi5nZXRJc29sYXRlVGFnPWZ1bmN0aW9uKGEpe3JldHVybiB0KCJfX19kYXJ0
-XyIrYSt2Lmlzb2xhdGVUYWcpfQp2YXIgcz0iX19fZGFydF9pc29sYXRlX3RhZ3NfIgp2YXIgcj1PYmpl
-Y3Rbc118fChPYmplY3Rbc109T2JqZWN0LmNyZWF0ZShudWxsKSkKdmFyIHE9Il9aeFl4WCIKZm9yKHZh
-ciBwPTA7O3ArKyl7dmFyIG89dChxKyJfIitwKyJfIikKaWYoIShvIGluIHIpKXtyW29dPTEKdi5pc29s
-YXRlVGFnPW8KYnJlYWt9fXYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWU9di5nZXRJc29sYXRlVGFnKCJkaXNw
-YXRjaF9yZWNvcmQiKX0oKQpodW5rSGVscGVycy5zZXRPclVwZGF0ZUludGVyY2VwdG9yc0J5VGFnKHtE
-T01FcnJvcjpKLnZCLERPTUltcGxlbWVudGF0aW9uOkoudkIsTWVkaWFFcnJvcjpKLnZCLE5hdmlnYXRv
-cjpKLnZCLE5hdmlnYXRvckNvbmN1cnJlbnRIYXJkd2FyZTpKLnZCLE5hdmlnYXRvclVzZXJNZWRpYUVy
-cm9yOkoudkIsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6Si52QixQb3NpdGlvbkVycm9yOkoudkIsUmFuZ2U6
-Si52QixTUUxFcnJvcjpKLnZCLERhdGFWaWV3OkguRVQsQXJyYXlCdWZmZXJWaWV3OkguRVQsRmxvYXQz
-MkFycmF5OkguRGcsRmxvYXQ2NEFycmF5OkguRGcsSW50MTZBcnJheTpILnhqLEludDMyQXJyYXk6SC5k
-RSxJbnQ4QXJyYXk6SC5aQSxVaW50MTZBcnJheTpILndmLFVpbnQzMkFycmF5OkguUHEsVWludDhDbGFt
-cGVkQXJyYXk6SC5lRSxDYW52YXNQaXhlbEFycmF5OkguZUUsVWludDhBcnJheTpILlY2LEhUTUxBdWRp
-b0VsZW1lbnQ6Vy5xRSxIVE1MQlJFbGVtZW50OlcucUUsSFRNTEJ1dHRvbkVsZW1lbnQ6Vy5xRSxIVE1M
-Q2FudmFzRWxlbWVudDpXLnFFLEhUTUxDb250ZW50RWxlbWVudDpXLnFFLEhUTUxETGlzdEVsZW1lbnQ6
-Vy5xRSxIVE1MRGF0YUVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUxpc3RFbGVtZW50OlcucUUsSFRNTERldGFp
-bHNFbGVtZW50OlcucUUsSFRNTERpYWxvZ0VsZW1lbnQ6Vy5xRSxIVE1MRGl2RWxlbWVudDpXLnFFLEhU
-TUxFbWJlZEVsZW1lbnQ6Vy5xRSxIVE1MRmllbGRTZXRFbGVtZW50OlcucUUsSFRNTEhSRWxlbWVudDpX
-LnFFLEhUTUxIZWFkRWxlbWVudDpXLnFFLEhUTUxIZWFkaW5nRWxlbWVudDpXLnFFLEhUTUxIdG1sRWxl
-bWVudDpXLnFFLEhUTUxJRnJhbWVFbGVtZW50OlcucUUsSFRNTEltYWdlRWxlbWVudDpXLnFFLEhUTUxJ
-bnB1dEVsZW1lbnQ6Vy5xRSxIVE1MTElFbGVtZW50OlcucUUsSFRNTExhYmVsRWxlbWVudDpXLnFFLEhU
-TUxMZWdlbmRFbGVtZW50OlcucUUsSFRNTExpbmtFbGVtZW50OlcucUUsSFRNTE1hcEVsZW1lbnQ6Vy5x
-RSxIVE1MTWVkaWFFbGVtZW50OlcucUUsSFRNTE1lbnVFbGVtZW50OlcucUUsSFRNTE1ldGFFbGVtZW50
-OlcucUUsSFRNTE1ldGVyRWxlbWVudDpXLnFFLEhUTUxNb2RFbGVtZW50OlcucUUsSFRNTE9MaXN0RWxl
-bWVudDpXLnFFLEhUTUxPYmplY3RFbGVtZW50OlcucUUsSFRNTE9wdEdyb3VwRWxlbWVudDpXLnFFLEhU
-TUxPcHRpb25FbGVtZW50OlcucUUsSFRNTE91dHB1dEVsZW1lbnQ6Vy5xRSxIVE1MUGFyYW1FbGVtZW50
-OlcucUUsSFRNTFBpY3R1cmVFbGVtZW50OlcucUUsSFRNTFByZUVsZW1lbnQ6Vy5xRSxIVE1MUHJvZ3Jl
-c3NFbGVtZW50OlcucUUsSFRNTFF1b3RlRWxlbWVudDpXLnFFLEhUTUxTY3JpcHRFbGVtZW50OlcucUUs
-SFRNTFNoYWRvd0VsZW1lbnQ6Vy5xRSxIVE1MU2xvdEVsZW1lbnQ6Vy5xRSxIVE1MU291cmNlRWxlbWVu
-dDpXLnFFLEhUTUxTcGFuRWxlbWVudDpXLnFFLEhUTUxTdHlsZUVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVD
-YXB0aW9uRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlRGF0YUNl
-bGxFbGVtZW50OlcucUUsSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDb2xF
-bGVtZW50OlcucUUsSFRNTFRleHRBcmVhRWxlbWVudDpXLnFFLEhUTUxUaW1lRWxlbWVudDpXLnFFLEhU
-TUxUaXRsZUVsZW1lbnQ6Vy5xRSxIVE1MVHJhY2tFbGVtZW50OlcucUUsSFRNTFVMaXN0RWxlbWVudDpX
-LnFFLEhUTUxVbmtub3duRWxlbWVudDpXLnFFLEhUTUxWaWRlb0VsZW1lbnQ6Vy5xRSxIVE1MRGlyZWN0
-b3J5RWxlbWVudDpXLnFFLEhUTUxGb250RWxlbWVudDpXLnFFLEhUTUxGcmFtZUVsZW1lbnQ6Vy5xRSxI
-VE1MRnJhbWVTZXRFbGVtZW50OlcucUUsSFRNTE1hcnF1ZWVFbGVtZW50OlcucUUsSFRNTEVsZW1lbnQ6
-Vy5xRSxIVE1MQW5jaG9yRWxlbWVudDpXLkdoLEhUTUxBcmVhRWxlbWVudDpXLmZZLEhUTUxCYXNlRWxl
-bWVudDpXLm5CLEJsb2I6Vy5BeixIVE1MQm9keUVsZW1lbnQ6Vy5RUCxDREFUQVNlY3Rpb246Vy5ueCxD
-aGFyYWN0ZXJEYXRhOlcubngsQ29tbWVudDpXLm54LFByb2Nlc3NpbmdJbnN0cnVjdGlvbjpXLm54LFRl
-eHQ6Vy5ueCxDU1NTdHlsZURlY2xhcmF0aW9uOlcub0osTVNTdHlsZUNTU1Byb3BlcnRpZXM6Vy5vSixD
-U1MyUHJvcGVydGllczpXLm9KLFhNTERvY3VtZW50OlcuUUYsRG9jdW1lbnQ6Vy5RRixET01FeGNlcHRp
-b246Vy5OaCxET01SZWN0UmVhZE9ubHk6Vy5JQixET01Ub2tlbkxpc3Q6Vy5uNyxFbGVtZW50OlcuY3Ys
-QWJvcnRQYXltZW50RXZlbnQ6Vy5lYSxBbmltYXRpb25FdmVudDpXLmVhLEFuaW1hdGlvblBsYXliYWNr
-RXZlbnQ6Vy5lYSxBcHBsaWNhdGlvbkNhY2hlRXJyb3JFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaENs
-aWNrRXZlbnQ6Vy5lYSxCYWNrZ3JvdW5kRmV0Y2hFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaEZhaWxF
-dmVudDpXLmVhLEJhY2tncm91bmRGZXRjaGVkRXZlbnQ6Vy5lYSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZl
-bnQ6Vy5lYSxCZWZvcmVVbmxvYWRFdmVudDpXLmVhLEJsb2JFdmVudDpXLmVhLENhbk1ha2VQYXltZW50
-RXZlbnQ6Vy5lYSxDbGlwYm9hcmRFdmVudDpXLmVhLENsb3NlRXZlbnQ6Vy5lYSxDdXN0b21FdmVudDpX
-LmVhLERldmljZU1vdGlvbkV2ZW50OlcuZWEsRGV2aWNlT3JpZW50YXRpb25FdmVudDpXLmVhLEVycm9y
-RXZlbnQ6Vy5lYSxFeHRlbmRhYmxlRXZlbnQ6Vy5lYSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OlcuZWEs
-RmV0Y2hFdmVudDpXLmVhLEZvbnRGYWNlU2V0TG9hZEV2ZW50OlcuZWEsRm9yZWlnbkZldGNoRXZlbnQ6
-Vy5lYSxHYW1lcGFkRXZlbnQ6Vy5lYSxIYXNoQ2hhbmdlRXZlbnQ6Vy5lYSxJbnN0YWxsRXZlbnQ6Vy5l
-YSxNZWRpYUVuY3J5cHRlZEV2ZW50OlcuZWEsTWVkaWFLZXlNZXNzYWdlRXZlbnQ6Vy5lYSxNZWRpYVF1
-ZXJ5TGlzdEV2ZW50OlcuZWEsTWVkaWFTdHJlYW1FdmVudDpXLmVhLE1lZGlhU3RyZWFtVHJhY2tFdmVu
-dDpXLmVhLE1lc3NhZ2VFdmVudDpXLmVhLE1JRElDb25uZWN0aW9uRXZlbnQ6Vy5lYSxNSURJTWVzc2Fn
-ZUV2ZW50OlcuZWEsTXV0YXRpb25FdmVudDpXLmVhLE5vdGlmaWNhdGlvbkV2ZW50OlcuZWEsUGFnZVRy
-YW5zaXRpb25FdmVudDpXLmVhLFBheW1lbnRSZXF1ZXN0RXZlbnQ6Vy5lYSxQYXltZW50UmVxdWVzdFVw
-ZGF0ZUV2ZW50OlcuZWEsUG9wU3RhdGVFdmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFp
-bGFibGVFdmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25DbG9zZUV2ZW50OlcuZWEsUHJvbWlz
-ZVJlamVjdGlvbkV2ZW50OlcuZWEsUHVzaEV2ZW50OlcuZWEsUlRDRGF0YUNoYW5uZWxFdmVudDpXLmVh
-LFJUQ0RUTUZUb25lQ2hhbmdlRXZlbnQ6Vy5lYSxSVENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OlcuZWEs
-UlRDVHJhY2tFdmVudDpXLmVhLFNlY3VyaXR5UG9saWN5VmlvbGF0aW9uRXZlbnQ6Vy5lYSxTZW5zb3JF
-cnJvckV2ZW50OlcuZWEsU3BlZWNoUmVjb2duaXRpb25FcnJvcjpXLmVhLFNwZWVjaFJlY29nbml0aW9u
-RXZlbnQ6Vy5lYSxTcGVlY2hTeW50aGVzaXNFdmVudDpXLmVhLFN0b3JhZ2VFdmVudDpXLmVhLFN5bmNF
-dmVudDpXLmVhLFRyYWNrRXZlbnQ6Vy5lYSxUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxXZWJLaXRUcmFuc2l0
-aW9uRXZlbnQ6Vy5lYSxWUkRldmljZUV2ZW50OlcuZWEsVlJEaXNwbGF5RXZlbnQ6Vy5lYSxWUlNlc3Np
-b25FdmVudDpXLmVhLE1vam9JbnRlcmZhY2VSZXF1ZXN0RXZlbnQ6Vy5lYSxVU0JDb25uZWN0aW9uRXZl
-bnQ6Vy5lYSxJREJWZXJzaW9uQ2hhbmdlRXZlbnQ6Vy5lYSxBdWRpb1Byb2Nlc3NpbmdFdmVudDpXLmVh
-LE9mZmxpbmVBdWRpb0NvbXBsZXRpb25FdmVudDpXLmVhLFdlYkdMQ29udGV4dEV2ZW50OlcuZWEsRXZl
-bnQ6Vy5lYSxJbnB1dEV2ZW50OlcuZWEsRXZlbnRUYXJnZXQ6Vy5EMCxGaWxlOlcuVDUsSFRNTEZvcm1F
-bGVtZW50OlcuaDQsSGlzdG9yeTpXLmJyLEhUTUxEb2N1bWVudDpXLlZiLFhNTEh0dHBSZXF1ZXN0Olcu
-TzcsWE1MSHR0cFJlcXVlc3RFdmVudFRhcmdldDpXLndhLEltYWdlRGF0YTpXLlNnLExvY2F0aW9uOlcu
-dTgsTW91c2VFdmVudDpXLkFqLERyYWdFdmVudDpXLkFqLFBvaW50ZXJFdmVudDpXLkFqLFdoZWVsRXZl
-bnQ6Vy5BaixEb2N1bWVudEZyYWdtZW50OlcudUgsU2hhZG93Um9vdDpXLnVILERvY3VtZW50VHlwZTpX
-LnVILE5vZGU6Vy51SCxOb2RlTGlzdDpXLkJILFJhZGlvTm9kZUxpc3Q6Vy5CSCxIVE1MUGFyYWdyYXBo
-RWxlbWVudDpXLlNOLFByb2dyZXNzRXZlbnQ6Vy5ldyxSZXNvdXJjZVByb2dyZXNzRXZlbnQ6Vy5ldyxI
-VE1MU2VsZWN0RWxlbWVudDpXLmxwLEhUTUxUYWJsZUVsZW1lbnQ6Vy5UYixIVE1MVGFibGVSb3dFbGVt
-ZW50OlcuSXYsSFRNTFRhYmxlU2VjdGlvbkVsZW1lbnQ6Vy5CVCxIVE1MVGVtcGxhdGVFbGVtZW50Olcu
-eVksQ29tcG9zaXRpb25FdmVudDpXLnc2LEZvY3VzRXZlbnQ6Vy53NixLZXlib2FyZEV2ZW50OlcudzYs
-VGV4dEV2ZW50OlcudzYsVG91Y2hFdmVudDpXLnc2LFVJRXZlbnQ6Vy53NixXaW5kb3c6Vy5LNSxET01X
-aW5kb3c6Vy5LNSxEZWRpY2F0ZWRXb3JrZXJHbG9iYWxTY29wZTpXLkNtLFNlcnZpY2VXb3JrZXJHbG9i
-YWxTY29wZTpXLkNtLFNoYXJlZFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sV29ya2VyR2xvYmFsU2NvcGU6
-Vy5DbSxBdHRyOlcuQ1EsQ2xpZW50UmVjdDpXLnc0LERPTVJlY3Q6Vy53NCxOYW1lZE5vZGVNYXA6Vy5y
-aCxNb3pOYW1lZEF0dHJNYXA6Vy5yaCxJREJLZXlSYW5nZTpQLmhGLFNWR1NjcmlwdEVsZW1lbnQ6UC5u
-ZCxTVkdBRWxlbWVudDpQLmQ1LFNWR0FuaW1hdGVFbGVtZW50OlAuZDUsU1ZHQW5pbWF0ZU1vdGlvbkVs
-ZW1lbnQ6UC5kNSxTVkdBbmltYXRlVHJhbnNmb3JtRWxlbWVudDpQLmQ1LFNWR0FuaW1hdGlvbkVsZW1l
-bnQ6UC5kNSxTVkdDaXJjbGVFbGVtZW50OlAuZDUsU1ZHQ2xpcFBhdGhFbGVtZW50OlAuZDUsU1ZHRGVm
-c0VsZW1lbnQ6UC5kNSxTVkdEZXNjRWxlbWVudDpQLmQ1LFNWR0Rpc2NhcmRFbGVtZW50OlAuZDUsU1ZH
-RWxsaXBzZUVsZW1lbnQ6UC5kNSxTVkdGRUJsZW5kRWxlbWVudDpQLmQ1LFNWR0ZFQ29sb3JNYXRyaXhF
-bGVtZW50OlAuZDUsU1ZHRkVDb21wb25lbnRUcmFuc2ZlckVsZW1lbnQ6UC5kNSxTVkdGRUNvbXBvc2l0
-ZUVsZW1lbnQ6UC5kNSxTVkdGRUNvbnZvbHZlTWF0cml4RWxlbWVudDpQLmQ1LFNWR0ZFRGlmZnVzZUxp
-Z2h0aW5nRWxlbWVudDpQLmQ1LFNWR0ZFRGlzcGxhY2VtZW50TWFwRWxlbWVudDpQLmQ1LFNWR0ZFRGlz
-dGFudExpZ2h0RWxlbWVudDpQLmQ1LFNWR0ZFRmxvb2RFbGVtZW50OlAuZDUsU1ZHRkVGdW5jQUVsZW1l
-bnQ6UC5kNSxTVkdGRUZ1bmNCRWxlbWVudDpQLmQ1LFNWR0ZFRnVuY0dFbGVtZW50OlAuZDUsU1ZHRkVG
-dW5jUkVsZW1lbnQ6UC5kNSxTVkdGRUdhdXNzaWFuQmx1ckVsZW1lbnQ6UC5kNSxTVkdGRUltYWdlRWxl
-bWVudDpQLmQ1LFNWR0ZFTWVyZ2VFbGVtZW50OlAuZDUsU1ZHRkVNZXJnZU5vZGVFbGVtZW50OlAuZDUs
-U1ZHRkVNb3JwaG9sb2d5RWxlbWVudDpQLmQ1LFNWR0ZFT2Zmc2V0RWxlbWVudDpQLmQ1LFNWR0ZFUG9p
-bnRMaWdodEVsZW1lbnQ6UC5kNSxTVkdGRVNwZWN1bGFyTGlnaHRpbmdFbGVtZW50OlAuZDUsU1ZHRkVT
-cG90TGlnaHRFbGVtZW50OlAuZDUsU1ZHRkVUaWxlRWxlbWVudDpQLmQ1LFNWR0ZFVHVyYnVsZW5jZUVs
-ZW1lbnQ6UC5kNSxTVkdGaWx0ZXJFbGVtZW50OlAuZDUsU1ZHRm9yZWlnbk9iamVjdEVsZW1lbnQ6UC5k
-NSxTVkdHRWxlbWVudDpQLmQ1LFNWR0dlb21ldHJ5RWxlbWVudDpQLmQ1LFNWR0dyYXBoaWNzRWxlbWVu
-dDpQLmQ1LFNWR0ltYWdlRWxlbWVudDpQLmQ1LFNWR0xpbmVFbGVtZW50OlAuZDUsU1ZHTGluZWFyR3Jh
-ZGllbnRFbGVtZW50OlAuZDUsU1ZHTWFya2VyRWxlbWVudDpQLmQ1LFNWR01hc2tFbGVtZW50OlAuZDUs
-U1ZHTWV0YWRhdGFFbGVtZW50OlAuZDUsU1ZHUGF0aEVsZW1lbnQ6UC5kNSxTVkdQYXR0ZXJuRWxlbWVu
-dDpQLmQ1LFNWR1BvbHlnb25FbGVtZW50OlAuZDUsU1ZHUG9seWxpbmVFbGVtZW50OlAuZDUsU1ZHUmFk
-aWFsR3JhZGllbnRFbGVtZW50OlAuZDUsU1ZHUmVjdEVsZW1lbnQ6UC5kNSxTVkdTZXRFbGVtZW50OlAu
-ZDUsU1ZHU3RvcEVsZW1lbnQ6UC5kNSxTVkdTdHlsZUVsZW1lbnQ6UC5kNSxTVkdTVkdFbGVtZW50OlAu
-ZDUsU1ZHU3dpdGNoRWxlbWVudDpQLmQ1LFNWR1N5bWJvbEVsZW1lbnQ6UC5kNSxTVkdUU3BhbkVsZW1l
-bnQ6UC5kNSxTVkdUZXh0Q29udGVudEVsZW1lbnQ6UC5kNSxTVkdUZXh0RWxlbWVudDpQLmQ1LFNWR1Rl
-eHRQYXRoRWxlbWVudDpQLmQ1LFNWR1RleHRQb3NpdGlvbmluZ0VsZW1lbnQ6UC5kNSxTVkdUaXRsZUVs
-ZW1lbnQ6UC5kNSxTVkdVc2VFbGVtZW50OlAuZDUsU1ZHVmlld0VsZW1lbnQ6UC5kNSxTVkdHcmFkaWVu
-dEVsZW1lbnQ6UC5kNSxTVkdDb21wb25lbnRUcmFuc2ZlckZ1bmN0aW9uRWxlbWVudDpQLmQ1LFNWR0ZF
-RHJvcFNoYWRvd0VsZW1lbnQ6UC5kNSxTVkdNUGF0aEVsZW1lbnQ6UC5kNSxTVkdFbGVtZW50OlAuZDV9
-KQpodW5rSGVscGVycy5zZXRPclVwZGF0ZUxlYWZUYWdzKHtET01FcnJvcjp0cnVlLERPTUltcGxlbWVu
-dGF0aW9uOnRydWUsTWVkaWFFcnJvcjp0cnVlLE5hdmlnYXRvcjp0cnVlLE5hdmlnYXRvckNvbmN1cnJl
-bnRIYXJkd2FyZTp0cnVlLE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOnRydWUsT3ZlcmNvbnN0cmFpbmVk
-RXJyb3I6dHJ1ZSxQb3NpdGlvbkVycm9yOnRydWUsUmFuZ2U6dHJ1ZSxTUUxFcnJvcjp0cnVlLERhdGFW
-aWV3OnRydWUsQXJyYXlCdWZmZXJWaWV3OmZhbHNlLEZsb2F0MzJBcnJheTp0cnVlLEZsb2F0NjRBcnJh
-eTp0cnVlLEludDE2QXJyYXk6dHJ1ZSxJbnQzMkFycmF5OnRydWUsSW50OEFycmF5OnRydWUsVWludDE2
-QXJyYXk6dHJ1ZSxVaW50MzJBcnJheTp0cnVlLFVpbnQ4Q2xhbXBlZEFycmF5OnRydWUsQ2FudmFzUGl4
-ZWxBcnJheTp0cnVlLFVpbnQ4QXJyYXk6ZmFsc2UsSFRNTEF1ZGlvRWxlbWVudDp0cnVlLEhUTUxCUkVs
-ZW1lbnQ6dHJ1ZSxIVE1MQnV0dG9uRWxlbWVudDp0cnVlLEhUTUxDYW52YXNFbGVtZW50OnRydWUsSFRN
-TENvbnRlbnRFbGVtZW50OnRydWUsSFRNTERMaXN0RWxlbWVudDp0cnVlLEhUTUxEYXRhRWxlbWVudDp0
-cnVlLEhUTUxEYXRhTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MRGV0YWlsc0VsZW1lbnQ6dHJ1ZSxIVE1MRGlh
-bG9nRWxlbWVudDp0cnVlLEhUTUxEaXZFbGVtZW50OnRydWUsSFRNTEVtYmVkRWxlbWVudDp0cnVlLEhU
-TUxGaWVsZFNldEVsZW1lbnQ6dHJ1ZSxIVE1MSFJFbGVtZW50OnRydWUsSFRNTEhlYWRFbGVtZW50OnRy
-dWUsSFRNTEhlYWRpbmdFbGVtZW50OnRydWUsSFRNTEh0bWxFbGVtZW50OnRydWUsSFRNTElGcmFtZUVs
-ZW1lbnQ6dHJ1ZSxIVE1MSW1hZ2VFbGVtZW50OnRydWUsSFRNTElucHV0RWxlbWVudDp0cnVlLEhUTUxM
-SUVsZW1lbnQ6dHJ1ZSxIVE1MTGFiZWxFbGVtZW50OnRydWUsSFRNTExlZ2VuZEVsZW1lbnQ6dHJ1ZSxI
-VE1MTGlua0VsZW1lbnQ6dHJ1ZSxIVE1MTWFwRWxlbWVudDp0cnVlLEhUTUxNZWRpYUVsZW1lbnQ6dHJ1
-ZSxIVE1MTWVudUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0YUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0ZXJFbGVtZW50
-OnRydWUsSFRNTE1vZEVsZW1lbnQ6dHJ1ZSxIVE1MT0xpc3RFbGVtZW50OnRydWUsSFRNTE9iamVjdEVs
-ZW1lbnQ6dHJ1ZSxIVE1MT3B0R3JvdXBFbGVtZW50OnRydWUsSFRNTE9wdGlvbkVsZW1lbnQ6dHJ1ZSxI
-VE1MT3V0cHV0RWxlbWVudDp0cnVlLEhUTUxQYXJhbUVsZW1lbnQ6dHJ1ZSxIVE1MUGljdHVyZUVsZW1l
-bnQ6dHJ1ZSxIVE1MUHJlRWxlbWVudDp0cnVlLEhUTUxQcm9ncmVzc0VsZW1lbnQ6dHJ1ZSxIVE1MUXVv
-dGVFbGVtZW50OnRydWUsSFRNTFNjcmlwdEVsZW1lbnQ6dHJ1ZSxIVE1MU2hhZG93RWxlbWVudDp0cnVl
-LEhUTUxTbG90RWxlbWVudDp0cnVlLEhUTUxTb3VyY2VFbGVtZW50OnRydWUsSFRNTFNwYW5FbGVtZW50
-OnRydWUsSFRNTFN0eWxlRWxlbWVudDp0cnVlLEhUTUxUYWJsZUNhcHRpb25FbGVtZW50OnRydWUsSFRN
-TFRhYmxlQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVEYXRhQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFi
-bGVIZWFkZXJDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZUNvbEVsZW1lbnQ6dHJ1ZSxIVE1MVGV4dEFy
-ZWFFbGVtZW50OnRydWUsSFRNTFRpbWVFbGVtZW50OnRydWUsSFRNTFRpdGxlRWxlbWVudDp0cnVlLEhU
-TUxUcmFja0VsZW1lbnQ6dHJ1ZSxIVE1MVUxpc3RFbGVtZW50OnRydWUsSFRNTFVua25vd25FbGVtZW50
-OnRydWUsSFRNTFZpZGVvRWxlbWVudDp0cnVlLEhUTUxEaXJlY3RvcnlFbGVtZW50OnRydWUsSFRNTEZv
-bnRFbGVtZW50OnRydWUsSFRNTEZyYW1lRWxlbWVudDp0cnVlLEhUTUxGcmFtZVNldEVsZW1lbnQ6dHJ1
-ZSxIVE1MTWFycXVlZUVsZW1lbnQ6dHJ1ZSxIVE1MRWxlbWVudDpmYWxzZSxIVE1MQW5jaG9yRWxlbWVu
-dDp0cnVlLEhUTUxBcmVhRWxlbWVudDp0cnVlLEhUTUxCYXNlRWxlbWVudDp0cnVlLEJsb2I6ZmFsc2Us
-SFRNTEJvZHlFbGVtZW50OnRydWUsQ0RBVEFTZWN0aW9uOnRydWUsQ2hhcmFjdGVyRGF0YTp0cnVlLENv
-bW1lbnQ6dHJ1ZSxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb246dHJ1ZSxUZXh0OnRydWUsQ1NTU3R5bGVEZWNs
-YXJhdGlvbjp0cnVlLE1TU3R5bGVDU1NQcm9wZXJ0aWVzOnRydWUsQ1NTMlByb3BlcnRpZXM6dHJ1ZSxY
-TUxEb2N1bWVudDp0cnVlLERvY3VtZW50OmZhbHNlLERPTUV4Y2VwdGlvbjp0cnVlLERPTVJlY3RSZWFk
-T25seTpmYWxzZSxET01Ub2tlbkxpc3Q6dHJ1ZSxFbGVtZW50OmZhbHNlLEFib3J0UGF5bWVudEV2ZW50
-OnRydWUsQW5pbWF0aW9uRXZlbnQ6dHJ1ZSxBbmltYXRpb25QbGF5YmFja0V2ZW50OnRydWUsQXBwbGlj
-YXRpb25DYWNoZUVycm9yRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hDbGlja0V2ZW50OnRydWUsQmFj
-a2dyb3VuZEZldGNoRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hGYWlsRXZlbnQ6dHJ1ZSxCYWNrZ3Jv
-dW5kRmV0Y2hlZEV2ZW50OnRydWUsQmVmb3JlSW5zdGFsbFByb21wdEV2ZW50OnRydWUsQmVmb3JlVW5s
-b2FkRXZlbnQ6dHJ1ZSxCbG9iRXZlbnQ6dHJ1ZSxDYW5NYWtlUGF5bWVudEV2ZW50OnRydWUsQ2xpcGJv
-YXJkRXZlbnQ6dHJ1ZSxDbG9zZUV2ZW50OnRydWUsQ3VzdG9tRXZlbnQ6dHJ1ZSxEZXZpY2VNb3Rpb25F
-dmVudDp0cnVlLERldmljZU9yaWVudGF0aW9uRXZlbnQ6dHJ1ZSxFcnJvckV2ZW50OnRydWUsRXh0ZW5k
-YWJsZUV2ZW50OnRydWUsRXh0ZW5kYWJsZU1lc3NhZ2VFdmVudDp0cnVlLEZldGNoRXZlbnQ6dHJ1ZSxG
-b250RmFjZVNldExvYWRFdmVudDp0cnVlLEZvcmVpZ25GZXRjaEV2ZW50OnRydWUsR2FtZXBhZEV2ZW50
-OnRydWUsSGFzaENoYW5nZUV2ZW50OnRydWUsSW5zdGFsbEV2ZW50OnRydWUsTWVkaWFFbmNyeXB0ZWRF
-dmVudDp0cnVlLE1lZGlhS2V5TWVzc2FnZUV2ZW50OnRydWUsTWVkaWFRdWVyeUxpc3RFdmVudDp0cnVl
-LE1lZGlhU3RyZWFtRXZlbnQ6dHJ1ZSxNZWRpYVN0cmVhbVRyYWNrRXZlbnQ6dHJ1ZSxNZXNzYWdlRXZl
-bnQ6dHJ1ZSxNSURJQ29ubmVjdGlvbkV2ZW50OnRydWUsTUlESU1lc3NhZ2VFdmVudDp0cnVlLE11dGF0
-aW9uRXZlbnQ6dHJ1ZSxOb3RpZmljYXRpb25FdmVudDp0cnVlLFBhZ2VUcmFuc2l0aW9uRXZlbnQ6dHJ1
-ZSxQYXltZW50UmVxdWVzdEV2ZW50OnRydWUsUGF5bWVudFJlcXVlc3RVcGRhdGVFdmVudDp0cnVlLFBv
-cFN0YXRlRXZlbnQ6dHJ1ZSxQcmVzZW50YXRpb25Db25uZWN0aW9uQXZhaWxhYmxlRXZlbnQ6dHJ1ZSxQ
-cmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VFdmVudDp0cnVlLFByb21pc2VSZWplY3Rpb25FdmVudDp0
-cnVlLFB1c2hFdmVudDp0cnVlLFJUQ0RhdGFDaGFubmVsRXZlbnQ6dHJ1ZSxSVENEVE1GVG9uZUNoYW5n
-ZUV2ZW50OnRydWUsUlRDUGVlckNvbm5lY3Rpb25JY2VFdmVudDp0cnVlLFJUQ1RyYWNrRXZlbnQ6dHJ1
-ZSxTZWN1cml0eVBvbGljeVZpb2xhdGlvbkV2ZW50OnRydWUsU2Vuc29yRXJyb3JFdmVudDp0cnVlLFNw
-ZWVjaFJlY29nbml0aW9uRXJyb3I6dHJ1ZSxTcGVlY2hSZWNvZ25pdGlvbkV2ZW50OnRydWUsU3BlZWNo
-U3ludGhlc2lzRXZlbnQ6dHJ1ZSxTdG9yYWdlRXZlbnQ6dHJ1ZSxTeW5jRXZlbnQ6dHJ1ZSxUcmFja0V2
-ZW50OnRydWUsVHJhbnNpdGlvbkV2ZW50OnRydWUsV2ViS2l0VHJhbnNpdGlvbkV2ZW50OnRydWUsVlJE
-ZXZpY2VFdmVudDp0cnVlLFZSRGlzcGxheUV2ZW50OnRydWUsVlJTZXNzaW9uRXZlbnQ6dHJ1ZSxNb2pv
-SW50ZXJmYWNlUmVxdWVzdEV2ZW50OnRydWUsVVNCQ29ubmVjdGlvbkV2ZW50OnRydWUsSURCVmVyc2lv
-bkNoYW5nZUV2ZW50OnRydWUsQXVkaW9Qcm9jZXNzaW5nRXZlbnQ6dHJ1ZSxPZmZsaW5lQXVkaW9Db21w
-bGV0aW9uRXZlbnQ6dHJ1ZSxXZWJHTENvbnRleHRFdmVudDp0cnVlLEV2ZW50OmZhbHNlLElucHV0RXZl
-bnQ6ZmFsc2UsRXZlbnRUYXJnZXQ6ZmFsc2UsRmlsZTp0cnVlLEhUTUxGb3JtRWxlbWVudDp0cnVlLEhp
-c3Rvcnk6dHJ1ZSxIVE1MRG9jdW1lbnQ6dHJ1ZSxYTUxIdHRwUmVxdWVzdDp0cnVlLFhNTEh0dHBSZXF1
-ZXN0RXZlbnRUYXJnZXQ6ZmFsc2UsSW1hZ2VEYXRhOnRydWUsTG9jYXRpb246dHJ1ZSxNb3VzZUV2ZW50
-OnRydWUsRHJhZ0V2ZW50OnRydWUsUG9pbnRlckV2ZW50OnRydWUsV2hlZWxFdmVudDp0cnVlLERvY3Vt
-ZW50RnJhZ21lbnQ6dHJ1ZSxTaGFkb3dSb290OnRydWUsRG9jdW1lbnRUeXBlOnRydWUsTm9kZTpmYWxz
-ZSxOb2RlTGlzdDp0cnVlLFJhZGlvTm9kZUxpc3Q6dHJ1ZSxIVE1MUGFyYWdyYXBoRWxlbWVudDp0cnVl
-LFByb2dyZXNzRXZlbnQ6dHJ1ZSxSZXNvdXJjZVByb2dyZXNzRXZlbnQ6dHJ1ZSxIVE1MU2VsZWN0RWxl
-bWVudDp0cnVlLEhUTUxUYWJsZUVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVSb3dFbGVtZW50OnRydWUsSFRN
-TFRhYmxlU2VjdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MVGVtcGxhdGVFbGVtZW50OnRydWUsQ29tcG9zaXRp
-b25FdmVudDp0cnVlLEZvY3VzRXZlbnQ6dHJ1ZSxLZXlib2FyZEV2ZW50OnRydWUsVGV4dEV2ZW50OnRy
-dWUsVG91Y2hFdmVudDp0cnVlLFVJRXZlbnQ6ZmFsc2UsV2luZG93OnRydWUsRE9NV2luZG93OnRydWUs
-RGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxTZXJ2aWNlV29ya2VyR2xvYmFsU2NvcGU6dHJ1
-ZSxTaGFyZWRXb3JrZXJHbG9iYWxTY29wZTp0cnVlLFdvcmtlckdsb2JhbFNjb3BlOnRydWUsQXR0cjp0
-cnVlLENsaWVudFJlY3Q6dHJ1ZSxET01SZWN0OnRydWUsTmFtZWROb2RlTWFwOnRydWUsTW96TmFtZWRB
-dHRyTWFwOnRydWUsSURCS2V5UmFuZ2U6dHJ1ZSxTVkdTY3JpcHRFbGVtZW50OnRydWUsU1ZHQUVsZW1l
-bnQ6dHJ1ZSxTVkdBbmltYXRlRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVNb3Rpb25FbGVtZW50OnRydWUs
-U1ZHQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRpb25FbGVtZW50OnRydWUsU1ZH
-Q2lyY2xlRWxlbWVudDp0cnVlLFNWR0NsaXBQYXRoRWxlbWVudDp0cnVlLFNWR0RlZnNFbGVtZW50OnRy
-dWUsU1ZHRGVzY0VsZW1lbnQ6dHJ1ZSxTVkdEaXNjYXJkRWxlbWVudDp0cnVlLFNWR0VsbGlwc2VFbGVt
-ZW50OnRydWUsU1ZHRkVCbGVuZEVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbG9yTWF0cml4RWxlbWVudDp0cnVl
-LFNWR0ZFQ29tcG9uZW50VHJhbnNmZXJFbGVtZW50OnRydWUsU1ZHRkVDb21wb3NpdGVFbGVtZW50OnRy
-dWUsU1ZHRkVDb252b2x2ZU1hdHJpeEVsZW1lbnQ6dHJ1ZSxTVkdGRURpZmZ1c2VMaWdodGluZ0VsZW1l
-bnQ6dHJ1ZSxTVkdGRURpc3BsYWNlbWVudE1hcEVsZW1lbnQ6dHJ1ZSxTVkdGRURpc3RhbnRMaWdodEVs
-ZW1lbnQ6dHJ1ZSxTVkdGRUZsb29kRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0FFbGVtZW50OnRydWUsU1ZH
-RkVGdW5jQkVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNHRWxlbWVudDp0cnVlLFNWR0ZFRnVuY1JFbGVtZW50
-OnRydWUsU1ZHRkVHYXVzc2lhbkJsdXJFbGVtZW50OnRydWUsU1ZHRkVJbWFnZUVsZW1lbnQ6dHJ1ZSxT
-VkdGRU1lcmdlRWxlbWVudDp0cnVlLFNWR0ZFTWVyZ2VOb2RlRWxlbWVudDp0cnVlLFNWR0ZFTW9ycGhv
-bG9neUVsZW1lbnQ6dHJ1ZSxTVkdGRU9mZnNldEVsZW1lbnQ6dHJ1ZSxTVkdGRVBvaW50TGlnaHRFbGVt
-ZW50OnRydWUsU1ZHRkVTcGVjdWxhckxpZ2h0aW5nRWxlbWVudDp0cnVlLFNWR0ZFU3BvdExpZ2h0RWxl
-bWVudDp0cnVlLFNWR0ZFVGlsZUVsZW1lbnQ6dHJ1ZSxTVkdGRVR1cmJ1bGVuY2VFbGVtZW50OnRydWUs
-U1ZHRmlsdGVyRWxlbWVudDp0cnVlLFNWR0ZvcmVpZ25PYmplY3RFbGVtZW50OnRydWUsU1ZHR0VsZW1l
-bnQ6dHJ1ZSxTVkdHZW9tZXRyeUVsZW1lbnQ6dHJ1ZSxTVkdHcmFwaGljc0VsZW1lbnQ6dHJ1ZSxTVkdJ
-bWFnZUVsZW1lbnQ6dHJ1ZSxTVkdMaW5lRWxlbWVudDp0cnVlLFNWR0xpbmVhckdyYWRpZW50RWxlbWVu
-dDp0cnVlLFNWR01hcmtlckVsZW1lbnQ6dHJ1ZSxTVkdNYXNrRWxlbWVudDp0cnVlLFNWR01ldGFkYXRh
-RWxlbWVudDp0cnVlLFNWR1BhdGhFbGVtZW50OnRydWUsU1ZHUGF0dGVybkVsZW1lbnQ6dHJ1ZSxTVkdQ
-b2x5Z29uRWxlbWVudDp0cnVlLFNWR1BvbHlsaW5lRWxlbWVudDp0cnVlLFNWR1JhZGlhbEdyYWRpZW50
-RWxlbWVudDp0cnVlLFNWR1JlY3RFbGVtZW50OnRydWUsU1ZHU2V0RWxlbWVudDp0cnVlLFNWR1N0b3BF
-bGVtZW50OnRydWUsU1ZHU3R5bGVFbGVtZW50OnRydWUsU1ZHU1ZHRWxlbWVudDp0cnVlLFNWR1N3aXRj
-aEVsZW1lbnQ6dHJ1ZSxTVkdTeW1ib2xFbGVtZW50OnRydWUsU1ZHVFNwYW5FbGVtZW50OnRydWUsU1ZH
-VGV4dENvbnRlbnRFbGVtZW50OnRydWUsU1ZHVGV4dEVsZW1lbnQ6dHJ1ZSxTVkdUZXh0UGF0aEVsZW1l
-bnQ6dHJ1ZSxTVkdUZXh0UG9zaXRpb25pbmdFbGVtZW50OnRydWUsU1ZHVGl0bGVFbGVtZW50OnRydWUs
-U1ZHVXNlRWxlbWVudDp0cnVlLFNWR1ZpZXdFbGVtZW50OnRydWUsU1ZHR3JhZGllbnRFbGVtZW50OnRy
-dWUsU1ZHQ29tcG9uZW50VHJhbnNmZXJGdW5jdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdGRURyb3BTaGFkb3dF
-bGVtZW50OnRydWUsU1ZHTVBhdGhFbGVtZW50OnRydWUsU1ZHRWxlbWVudDpmYWxzZX0pCkguYjAuJG5h
-dGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5SRy4kbmF0aXZlU3VwZXJjbGFzc1Rh
-Zz0iQXJyYXlCdWZmZXJWaWV3IgpILlZQLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZp
-ZXciCkguRGcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5XQi4kbmF0aXZl
-U3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlpHLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJB
-cnJheUJ1ZmZlclZpZXciCkguUGcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyJ9
-KSgpCmNvbnZlcnRBbGxUb0Zhc3RPYmplY3QodykKY29udmVydFRvRmFzdE9iamVjdCgkKTsoZnVuY3Rp
-b24oYSl7aWYodHlwZW9mIGRvY3VtZW50PT09InVuZGVmaW5lZCIpe2EobnVsbCkKcmV0dXJufWlmKHR5
-cGVvZiBkb2N1bWVudC5jdXJyZW50U2NyaXB0IT0ndW5kZWZpbmVkJyl7YShkb2N1bWVudC5jdXJyZW50
-U2NyaXB0KQpyZXR1cm59dmFyIHQ9ZG9jdW1lbnQuc2NyaXB0cwpmdW5jdGlvbiBvbkxvYWQoYil7Zm9y
-KHZhciByPTA7cjx0Lmxlbmd0aDsrK3IpdFtyXS5yZW1vdmVFdmVudExpc3RlbmVyKCJsb2FkIixvbkxv
-YWQsZmFsc2UpCmEoYi50YXJnZXQpfWZvcih2YXIgcz0wO3M8dC5sZW5ndGg7KytzKXRbc10uYWRkRXZl
-bnRMaXN0ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKX0pKGZ1bmN0aW9uKGEpe3YuY3VycmVudFNjcmlw
-dD1hCmlmKHR5cGVvZiBkYXJ0TWFpblJ1bm5lcj09PSJmdW5jdGlvbiIpZGFydE1haW5SdW5uZXIoTC5J
-cSxbXSkKZWxzZSBMLklxKFtdKX0pfSkoKQovLyMgc291cmNlTWFwcGluZ1VSTD1taWdyYXRpb24uanMu
-bWFwCg==
+MiwtMiwtMiwtMiwtMiwtMiwtMSwtMiwtMiwtMiwtMiwtMiw2MiwtMiw2MiwtMiw2Myw1Miw1Myw1NCw1
+NSw1Niw1Nyw1OCw1OSw2MCw2MSwtMiwtMiwtMiwtMSwtMiwtMiwtMiwwLDEsMiwzLDQsNSw2LDcsOCw5
+LDEwLDExLDEyLDEzLDE0LDE1LDE2LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LC0yLC0yLC0yLC0y
+LDYzLC0yLDI2LDI3LDI4LDI5LDMwLDMxLDMyLDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQwLDQxLDQyLDQz
+LDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUwLDUxLC0yLC0yLC0yLC0yLC0yXSx1LnQpKSl9KQp0KCQsIk01Iiwi
+d1EiLGZ1bmN0aW9uKCl7cmV0dXJuIHR5cGVvZiBwcm9jZXNzIT0idW5kZWZpbmVkIiYmT2JqZWN0LnBy
+b3RvdHlwZS50b1N0cmluZy5jYWxsKHByb2Nlc3MpPT0iW29iamVjdCBwcm9jZXNzXSImJnByb2Nlc3Mu
+cGxhdGZvcm09PSJ3aW4zMiJ9KQp0KCQsIm1mIiwiejQiLGZ1bmN0aW9uKCl7cmV0dXJuIFAubnUoIl5b
+XFwtXFwuMC05QS1aX2Eten5dKiQiKX0pCnQoJCwiSkciLCJ2WiIsZnVuY3Rpb24oKXtyZXR1cm4gUC51
+eCgpfSkKdCgkLCJTQyIsIkFOIixmdW5jdGlvbigpe3JldHVybiBQLnRNKFsiQSIsIkFCQlIiLCJBQ1JP
+TllNIiwiQUREUkVTUyIsIkFSRUEiLCJBUlRJQ0xFIiwiQVNJREUiLCJBVURJTyIsIkIiLCJCREkiLCJC
+RE8iLCJCSUciLCJCTE9DS1FVT1RFIiwiQlIiLCJCVVRUT04iLCJDQU5WQVMiLCJDQVBUSU9OIiwiQ0VO
+VEVSIiwiQ0lURSIsIkNPREUiLCJDT0wiLCJDT0xHUk9VUCIsIkNPTU1BTkQiLCJEQVRBIiwiREFUQUxJ
+U1QiLCJERCIsIkRFTCIsIkRFVEFJTFMiLCJERk4iLCJESVIiLCJESVYiLCJETCIsIkRUIiwiRU0iLCJG
+SUVMRFNFVCIsIkZJR0NBUFRJT04iLCJGSUdVUkUiLCJGT05UIiwiRk9PVEVSIiwiRk9STSIsIkgxIiwi
+SDIiLCJIMyIsIkg0IiwiSDUiLCJINiIsIkhFQURFUiIsIkhHUk9VUCIsIkhSIiwiSSIsIklGUkFNRSIs
+IklNRyIsIklOUFVUIiwiSU5TIiwiS0JEIiwiTEFCRUwiLCJMRUdFTkQiLCJMSSIsIk1BUCIsIk1BUksi
+LCJNRU5VIiwiTUVURVIiLCJOQVYiLCJOT0JSIiwiT0wiLCJPUFRHUk9VUCIsIk9QVElPTiIsIk9VVFBV
+VCIsIlAiLCJQUkUiLCJQUk9HUkVTUyIsIlEiLCJTIiwiU0FNUCIsIlNFQ1RJT04iLCJTRUxFQ1QiLCJT
+TUFMTCIsIlNPVVJDRSIsIlNQQU4iLCJTVFJJS0UiLCJTVFJPTkciLCJTVUIiLCJTVU1NQVJZIiwiU1VQ
+IiwiVEFCTEUiLCJUQk9EWSIsIlREIiwiVEVYVEFSRUEiLCJURk9PVCIsIlRIIiwiVEhFQUQiLCJUSU1F
+IiwiVFIiLCJUUkFDSyIsIlRUIiwiVSIsIlVMIiwiVkFSIiwiVklERU8iLCJXQlIiXSx1Lk4pfSkKdCgk
+LCJYNCIsImhHIixmdW5jdGlvbigpe3JldHVybiBQLm51KCJeXFxTKyQiKX0pCnQoJCwid08iLCJvdyIs
+ZnVuY3Rpb24oKXtyZXR1cm4gdS52LmIoUC5ORChzZWxmKSl9KQp0KCQsImt0IiwiUjgiLGZ1bmN0aW9u
+KCl7cmV0dXJuIEguWWcoIl8kZGFydF9kYXJ0T2JqZWN0Iil9KQp0KCQsImZLIiwia0kiLGZ1bmN0aW9u
+KCl7cmV0dXJuIGZ1bmN0aW9uIERhcnRPYmplY3QoYSl7dGhpcy5vPWF9fSkKdCgkLCJxdCIsInpCIixm
+dW5jdGlvbigpe3JldHVybiBuZXcgVC5HVigpfSkKdCgkLCJFWSIsImZpIixmdW5jdGlvbigpe3JldHVy
+biBXLlpyKCkucXVlcnlTZWxlY3RvcigiaGVhZGVyIil9KQp0KCQsIlRSIiwiRFciLGZ1bmN0aW9uKCl7
+cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCJmb290ZXIiKX0pCnQoJCwiVzYiLCJoTCIsZnVuY3Rp
+b24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIi5lZGl0LXBhbmVsIC5wYW5lbC1jb250ZW50
+Iil9KQp0KCQsImhUIiwibVEiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIu
+ZWRpdC1saXN0IC5wYW5lbC1jb250ZW50Iil9KQp0KCQsImF2IiwiRDkiLGZ1bmN0aW9uKCl7cmV0dXJu
+IFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIjdW5pdC1uYW1lIil9KQp0KCQsImZlIiwiS0ciLGZ1bmN0aW9u
+KCl7cmV0dXJuIG5ldyBMLlhBKCl9KQp0KCQsIm1NIiwiblUiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBN
+LmxJKCQuSGsoKSl9KQp0KCQsInlyIiwiYkQiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBFLk9GKFAubnUo
+Ii8iKSxQLm51KCJbXi9dJCIpLFAubnUoIl4vIikpfSkKdCgkLCJNayIsIktrIixmdW5jdGlvbigpe3Jl
+dHVybiBuZXcgTC5JVihQLm51KCJbL1xcXFxdIiksUC5udSgiW14vXFxcXF0kIiksUC5udSgiXihcXFxc
+XFxcXFteXFxcXF0rXFxcXFteXFxcXC9dK3xbYS16QS1aXTpbL1xcXFxdKSIpLFAubnUoIl5bL1xcXFxd
+KD8hWy9cXFxcXSkiKSl9KQp0KCQsImFrIiwiRWIiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBGLnJ1KFAu
+bnUoIi8iKSxQLm51KCIoXlthLXpBLVpdWy0rLmEtekEtWlxcZF0qOi8vfFteL10pJCIpLFAubnUoIlth
+LXpBLVpdWy0rLmEtekEtWlxcZF0qOi8vW14vXSoiKSxQLm51KCJeLyIpKX0pCnQoJCwibHMiLCJIayIs
+ZnVuY3Rpb24oKXtyZXR1cm4gTy5SaCgpfSl9KSgpOyhmdW5jdGlvbiBuYXRpdmVTdXBwb3J0KCl7IWZ1
+bmN0aW9uKCl7dmFyIHQ9ZnVuY3Rpb24oYSl7dmFyIG49e30KblthXT0xCnJldHVybiBPYmplY3Qua2V5
+cyhodW5rSGVscGVycy5jb252ZXJ0VG9GYXN0T2JqZWN0KG4pKVswXX0Kdi5nZXRJc29sYXRlVGFnPWZ1
+bmN0aW9uKGEpe3JldHVybiB0KCJfX19kYXJ0XyIrYSt2Lmlzb2xhdGVUYWcpfQp2YXIgcz0iX19fZGFy
+dF9pc29sYXRlX3RhZ3NfIgp2YXIgcj1PYmplY3Rbc118fChPYmplY3Rbc109T2JqZWN0LmNyZWF0ZShu
+dWxsKSkKdmFyIHE9Il9aeFl4WCIKZm9yKHZhciBwPTA7O3ArKyl7dmFyIG89dChxKyJfIitwKyJfIikK
+aWYoIShvIGluIHIpKXtyW29dPTEKdi5pc29sYXRlVGFnPW8KYnJlYWt9fXYuZGlzcGF0Y2hQcm9wZXJ0
+eU5hbWU9di5nZXRJc29sYXRlVGFnKCJkaXNwYXRjaF9yZWNvcmQiKX0oKQpodW5rSGVscGVycy5zZXRP
+clVwZGF0ZUludGVyY2VwdG9yc0J5VGFnKHtET01FcnJvcjpKLnZCLERPTUltcGxlbWVudGF0aW9uOkou
+dkIsTWVkaWFFcnJvcjpKLnZCLE5hdmlnYXRvcjpKLnZCLE5hdmlnYXRvckNvbmN1cnJlbnRIYXJkd2Fy
+ZTpKLnZCLE5hdmlnYXRvclVzZXJNZWRpYUVycm9yOkoudkIsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6Si52
+QixQb3NpdGlvbkVycm9yOkoudkIsUmFuZ2U6Si52QixTUUxFcnJvcjpKLnZCLERhdGFWaWV3OkguRVQs
+QXJyYXlCdWZmZXJWaWV3OkguRVQsRmxvYXQzMkFycmF5OkguRGcsRmxvYXQ2NEFycmF5OkguRGcsSW50
+MTZBcnJheTpILnhqLEludDMyQXJyYXk6SC5kRSxJbnQ4QXJyYXk6SC5aQSxVaW50MTZBcnJheTpILndm
+LFVpbnQzMkFycmF5OkguUHEsVWludDhDbGFtcGVkQXJyYXk6SC5lRSxDYW52YXNQaXhlbEFycmF5Okgu
+ZUUsVWludDhBcnJheTpILlY2LEhUTUxBdWRpb0VsZW1lbnQ6Vy5xRSxIVE1MQlJFbGVtZW50OlcucUUs
+SFRNTEJ1dHRvbkVsZW1lbnQ6Vy5xRSxIVE1MQ2FudmFzRWxlbWVudDpXLnFFLEhUTUxDb250ZW50RWxl
+bWVudDpXLnFFLEhUTUxETGlzdEVsZW1lbnQ6Vy5xRSxIVE1MRGF0YUVsZW1lbnQ6Vy5xRSxIVE1MRGF0
+YUxpc3RFbGVtZW50OlcucUUsSFRNTERldGFpbHNFbGVtZW50OlcucUUsSFRNTERpYWxvZ0VsZW1lbnQ6
+Vy5xRSxIVE1MRGl2RWxlbWVudDpXLnFFLEhUTUxFbWJlZEVsZW1lbnQ6Vy5xRSxIVE1MRmllbGRTZXRF
+bGVtZW50OlcucUUsSFRNTEhSRWxlbWVudDpXLnFFLEhUTUxIZWFkRWxlbWVudDpXLnFFLEhUTUxIZWFk
+aW5nRWxlbWVudDpXLnFFLEhUTUxIdG1sRWxlbWVudDpXLnFFLEhUTUxJRnJhbWVFbGVtZW50OlcucUUs
+SFRNTEltYWdlRWxlbWVudDpXLnFFLEhUTUxJbnB1dEVsZW1lbnQ6Vy5xRSxIVE1MTElFbGVtZW50Olcu
+cUUsSFRNTExhYmVsRWxlbWVudDpXLnFFLEhUTUxMZWdlbmRFbGVtZW50OlcucUUsSFRNTExpbmtFbGVt
+ZW50OlcucUUsSFRNTE1hcEVsZW1lbnQ6Vy5xRSxIVE1MTWVkaWFFbGVtZW50OlcucUUsSFRNTE1lbnVF
+bGVtZW50OlcucUUsSFRNTE1ldGFFbGVtZW50OlcucUUsSFRNTE1ldGVyRWxlbWVudDpXLnFFLEhUTUxN
+b2RFbGVtZW50OlcucUUsSFRNTE9MaXN0RWxlbWVudDpXLnFFLEhUTUxPYmplY3RFbGVtZW50OlcucUUs
+SFRNTE9wdEdyb3VwRWxlbWVudDpXLnFFLEhUTUxPcHRpb25FbGVtZW50OlcucUUsSFRNTE91dHB1dEVs
+ZW1lbnQ6Vy5xRSxIVE1MUGFyYW1FbGVtZW50OlcucUUsSFRNTFBpY3R1cmVFbGVtZW50OlcucUUsSFRN
+TFByZUVsZW1lbnQ6Vy5xRSxIVE1MUHJvZ3Jlc3NFbGVtZW50OlcucUUsSFRNTFF1b3RlRWxlbWVudDpX
+LnFFLEhUTUxTY3JpcHRFbGVtZW50OlcucUUsSFRNTFNoYWRvd0VsZW1lbnQ6Vy5xRSxIVE1MU2xvdEVs
+ZW1lbnQ6Vy5xRSxIVE1MU291cmNlRWxlbWVudDpXLnFFLEhUTUxTcGFuRWxlbWVudDpXLnFFLEhUTUxT
+dHlsZUVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDYXB0aW9uRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNlbGxF
+bGVtZW50OlcucUUsSFRNTFRhYmxlRGF0YUNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlSGVhZGVyQ2Vs
+bEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVDb2xFbGVtZW50OlcucUUsSFRNTFRleHRBcmVhRWxlbWVudDpX
+LnFFLEhUTUxUaW1lRWxlbWVudDpXLnFFLEhUTUxUaXRsZUVsZW1lbnQ6Vy5xRSxIVE1MVHJhY2tFbGVt
+ZW50OlcucUUsSFRNTFVMaXN0RWxlbWVudDpXLnFFLEhUTUxVbmtub3duRWxlbWVudDpXLnFFLEhUTUxW
+aWRlb0VsZW1lbnQ6Vy5xRSxIVE1MRGlyZWN0b3J5RWxlbWVudDpXLnFFLEhUTUxGb250RWxlbWVudDpX
+LnFFLEhUTUxGcmFtZUVsZW1lbnQ6Vy5xRSxIVE1MRnJhbWVTZXRFbGVtZW50OlcucUUsSFRNTE1hcnF1
+ZWVFbGVtZW50OlcucUUsSFRNTEVsZW1lbnQ6Vy5xRSxIVE1MQW5jaG9yRWxlbWVudDpXLkdoLEhUTUxB
+cmVhRWxlbWVudDpXLmZZLEhUTUxCYXNlRWxlbWVudDpXLm5CLEJsb2I6Vy5BeixIVE1MQm9keUVsZW1l
+bnQ6Vy5RUCxDREFUQVNlY3Rpb246Vy5ueCxDaGFyYWN0ZXJEYXRhOlcubngsQ29tbWVudDpXLm54LFBy
+b2Nlc3NpbmdJbnN0cnVjdGlvbjpXLm54LFRleHQ6Vy5ueCxDU1NTdHlsZURlY2xhcmF0aW9uOlcub0os
+TVNTdHlsZUNTU1Byb3BlcnRpZXM6Vy5vSixDU1MyUHJvcGVydGllczpXLm9KLFhNTERvY3VtZW50Olcu
+UUYsRG9jdW1lbnQ6Vy5RRixET01FeGNlcHRpb246Vy5OaCxET01SZWN0UmVhZE9ubHk6Vy5JQixET01U
+b2tlbkxpc3Q6Vy5uNyxFbGVtZW50OlcuY3YsQWJvcnRQYXltZW50RXZlbnQ6Vy5lYSxBbmltYXRpb25F
+dmVudDpXLmVhLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6Vy5lYSxBcHBsaWNhdGlvbkNhY2hlRXJyb3JF
+dmVudDpXLmVhLEJhY2tncm91bmRGZXRjaENsaWNrRXZlbnQ6Vy5lYSxCYWNrZ3JvdW5kRmV0Y2hFdmVu
+dDpXLmVhLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDpXLmVhLEJhY2tncm91bmRGZXRjaGVkRXZlbnQ6
+Vy5lYSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6Vy5lYSxCZWZvcmVVbmxvYWRFdmVudDpXLmVhLEJs
+b2JFdmVudDpXLmVhLENhbk1ha2VQYXltZW50RXZlbnQ6Vy5lYSxDbGlwYm9hcmRFdmVudDpXLmVhLENs
+b3NlRXZlbnQ6Vy5lYSxDdXN0b21FdmVudDpXLmVhLERldmljZU1vdGlvbkV2ZW50OlcuZWEsRGV2aWNl
+T3JpZW50YXRpb25FdmVudDpXLmVhLEVycm9yRXZlbnQ6Vy5lYSxFeHRlbmRhYmxlRXZlbnQ6Vy5lYSxF
+eHRlbmRhYmxlTWVzc2FnZUV2ZW50OlcuZWEsRmV0Y2hFdmVudDpXLmVhLEZvbnRGYWNlU2V0TG9hZEV2
+ZW50OlcuZWEsRm9yZWlnbkZldGNoRXZlbnQ6Vy5lYSxHYW1lcGFkRXZlbnQ6Vy5lYSxIYXNoQ2hhbmdl
+RXZlbnQ6Vy5lYSxJbnN0YWxsRXZlbnQ6Vy5lYSxNZWRpYUVuY3J5cHRlZEV2ZW50OlcuZWEsTWVkaWFL
+ZXlNZXNzYWdlRXZlbnQ6Vy5lYSxNZWRpYVF1ZXJ5TGlzdEV2ZW50OlcuZWEsTWVkaWFTdHJlYW1FdmVu
+dDpXLmVhLE1lZGlhU3RyZWFtVHJhY2tFdmVudDpXLmVhLE1lc3NhZ2VFdmVudDpXLmVhLE1JRElDb25u
+ZWN0aW9uRXZlbnQ6Vy5lYSxNSURJTWVzc2FnZUV2ZW50OlcuZWEsTXV0YXRpb25FdmVudDpXLmVhLE5v
+dGlmaWNhdGlvbkV2ZW50OlcuZWEsUGFnZVRyYW5zaXRpb25FdmVudDpXLmVhLFBheW1lbnRSZXF1ZXN0
+RXZlbnQ6Vy5lYSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OlcuZWEsUG9wU3RhdGVFdmVudDpXLmVh
+LFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDpXLmVhLFByZXNlbnRhdGlvbkNvbm5l
+Y3Rpb25DbG9zZUV2ZW50OlcuZWEsUHJvbWlzZVJlamVjdGlvbkV2ZW50OlcuZWEsUHVzaEV2ZW50Olcu
+ZWEsUlRDRGF0YUNoYW5uZWxFdmVudDpXLmVhLFJUQ0RUTUZUb25lQ2hhbmdlRXZlbnQ6Vy5lYSxSVENQ
+ZWVyQ29ubmVjdGlvbkljZUV2ZW50OlcuZWEsUlRDVHJhY2tFdmVudDpXLmVhLFNlY3VyaXR5UG9saWN5
+VmlvbGF0aW9uRXZlbnQ6Vy5lYSxTZW5zb3JFcnJvckV2ZW50OlcuZWEsU3BlZWNoUmVjb2duaXRpb25F
+cnJvcjpXLmVhLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6Vy5lYSxTcGVlY2hTeW50aGVzaXNFdmVudDpX
+LmVhLFN0b3JhZ2VFdmVudDpXLmVhLFN5bmNFdmVudDpXLmVhLFRyYWNrRXZlbnQ6Vy5lYSxUcmFuc2l0
+aW9uRXZlbnQ6Vy5lYSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxWUkRldmljZUV2ZW50OlcuZWEs
+VlJEaXNwbGF5RXZlbnQ6Vy5lYSxWUlNlc3Npb25FdmVudDpXLmVhLE1vam9JbnRlcmZhY2VSZXF1ZXN0
+RXZlbnQ6Vy5lYSxVU0JDb25uZWN0aW9uRXZlbnQ6Vy5lYSxJREJWZXJzaW9uQ2hhbmdlRXZlbnQ6Vy5l
+YSxBdWRpb1Byb2Nlc3NpbmdFdmVudDpXLmVhLE9mZmxpbmVBdWRpb0NvbXBsZXRpb25FdmVudDpXLmVh
+LFdlYkdMQ29udGV4dEV2ZW50OlcuZWEsRXZlbnQ6Vy5lYSxJbnB1dEV2ZW50OlcuZWEsRXZlbnRUYXJn
+ZXQ6Vy5EMCxGaWxlOlcuVDUsSFRNTEZvcm1FbGVtZW50OlcuaDQsSGlzdG9yeTpXLmJyLEhUTUxEb2N1
+bWVudDpXLlZiLFhNTEh0dHBSZXF1ZXN0OlcuTzcsWE1MSHR0cFJlcXVlc3RFdmVudFRhcmdldDpXLndh
+LEltYWdlRGF0YTpXLlNnLExvY2F0aW9uOlcudTgsTW91c2VFdmVudDpXLkFqLERyYWdFdmVudDpXLkFq
+LFBvaW50ZXJFdmVudDpXLkFqLFdoZWVsRXZlbnQ6Vy5BaixEb2N1bWVudEZyYWdtZW50OlcudUgsU2hh
+ZG93Um9vdDpXLnVILERvY3VtZW50VHlwZTpXLnVILE5vZGU6Vy51SCxOb2RlTGlzdDpXLkJILFJhZGlv
+Tm9kZUxpc3Q6Vy5CSCxIVE1MUGFyYWdyYXBoRWxlbWVudDpXLlNOLFByb2dyZXNzRXZlbnQ6Vy5ldyxS
+ZXNvdXJjZVByb2dyZXNzRXZlbnQ6Vy5ldyxIVE1MU2VsZWN0RWxlbWVudDpXLmxwLEhUTUxUYWJsZUVs
+ZW1lbnQ6Vy5UYixIVE1MVGFibGVSb3dFbGVtZW50OlcuSXYsSFRNTFRhYmxlU2VjdGlvbkVsZW1lbnQ6
+Vy5CVCxIVE1MVGVtcGxhdGVFbGVtZW50OlcueVksQ29tcG9zaXRpb25FdmVudDpXLnc2LEZvY3VzRXZl
+bnQ6Vy53NixLZXlib2FyZEV2ZW50OlcudzYsVGV4dEV2ZW50OlcudzYsVG91Y2hFdmVudDpXLnc2LFVJ
+RXZlbnQ6Vy53NixXaW5kb3c6Vy5LNSxET01XaW5kb3c6Vy5LNSxEZWRpY2F0ZWRXb3JrZXJHbG9iYWxT
+Y29wZTpXLkNtLFNlcnZpY2VXb3JrZXJHbG9iYWxTY29wZTpXLkNtLFNoYXJlZFdvcmtlckdsb2JhbFNj
+b3BlOlcuQ20sV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxBdHRyOlcuQ1EsQ2xpZW50UmVjdDpXLnc0LERP
+TVJlY3Q6Vy53NCxOYW1lZE5vZGVNYXA6Vy5yaCxNb3pOYW1lZEF0dHJNYXA6Vy5yaCxJREJLZXlSYW5n
+ZTpQLmhGLFNWR1NjcmlwdEVsZW1lbnQ6UC5uZCxTVkdBRWxlbWVudDpQLmQ1LFNWR0FuaW1hdGVFbGVt
+ZW50OlAuZDUsU1ZHQW5pbWF0ZU1vdGlvbkVsZW1lbnQ6UC5kNSxTVkdBbmltYXRlVHJhbnNmb3JtRWxl
+bWVudDpQLmQ1LFNWR0FuaW1hdGlvbkVsZW1lbnQ6UC5kNSxTVkdDaXJjbGVFbGVtZW50OlAuZDUsU1ZH
+Q2xpcFBhdGhFbGVtZW50OlAuZDUsU1ZHRGVmc0VsZW1lbnQ6UC5kNSxTVkdEZXNjRWxlbWVudDpQLmQ1
+LFNWR0Rpc2NhcmRFbGVtZW50OlAuZDUsU1ZHRWxsaXBzZUVsZW1lbnQ6UC5kNSxTVkdGRUJsZW5kRWxl
+bWVudDpQLmQ1LFNWR0ZFQ29sb3JNYXRyaXhFbGVtZW50OlAuZDUsU1ZHRkVDb21wb25lbnRUcmFuc2Zl
+ckVsZW1lbnQ6UC5kNSxTVkdGRUNvbXBvc2l0ZUVsZW1lbnQ6UC5kNSxTVkdGRUNvbnZvbHZlTWF0cml4
+RWxlbWVudDpQLmQ1LFNWR0ZFRGlmZnVzZUxpZ2h0aW5nRWxlbWVudDpQLmQ1LFNWR0ZFRGlzcGxhY2Vt
+ZW50TWFwRWxlbWVudDpQLmQ1LFNWR0ZFRGlzdGFudExpZ2h0RWxlbWVudDpQLmQ1LFNWR0ZFRmxvb2RF
+bGVtZW50OlAuZDUsU1ZHRkVGdW5jQUVsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNCRWxlbWVudDpQLmQ1LFNW
+R0ZFRnVuY0dFbGVtZW50OlAuZDUsU1ZHRkVGdW5jUkVsZW1lbnQ6UC5kNSxTVkdGRUdhdXNzaWFuQmx1
+ckVsZW1lbnQ6UC5kNSxTVkdGRUltYWdlRWxlbWVudDpQLmQ1LFNWR0ZFTWVyZ2VFbGVtZW50OlAuZDUs
+U1ZHRkVNZXJnZU5vZGVFbGVtZW50OlAuZDUsU1ZHRkVNb3JwaG9sb2d5RWxlbWVudDpQLmQ1LFNWR0ZF
+T2Zmc2V0RWxlbWVudDpQLmQ1LFNWR0ZFUG9pbnRMaWdodEVsZW1lbnQ6UC5kNSxTVkdGRVNwZWN1bGFy
+TGlnaHRpbmdFbGVtZW50OlAuZDUsU1ZHRkVTcG90TGlnaHRFbGVtZW50OlAuZDUsU1ZHRkVUaWxlRWxl
+bWVudDpQLmQ1LFNWR0ZFVHVyYnVsZW5jZUVsZW1lbnQ6UC5kNSxTVkdGaWx0ZXJFbGVtZW50OlAuZDUs
+U1ZHRm9yZWlnbk9iamVjdEVsZW1lbnQ6UC5kNSxTVkdHRWxlbWVudDpQLmQ1LFNWR0dlb21ldHJ5RWxl
+bWVudDpQLmQ1LFNWR0dyYXBoaWNzRWxlbWVudDpQLmQ1LFNWR0ltYWdlRWxlbWVudDpQLmQ1LFNWR0xp
+bmVFbGVtZW50OlAuZDUsU1ZHTGluZWFyR3JhZGllbnRFbGVtZW50OlAuZDUsU1ZHTWFya2VyRWxlbWVu
+dDpQLmQ1LFNWR01hc2tFbGVtZW50OlAuZDUsU1ZHTWV0YWRhdGFFbGVtZW50OlAuZDUsU1ZHUGF0aEVs
+ZW1lbnQ6UC5kNSxTVkdQYXR0ZXJuRWxlbWVudDpQLmQ1LFNWR1BvbHlnb25FbGVtZW50OlAuZDUsU1ZH
+UG9seWxpbmVFbGVtZW50OlAuZDUsU1ZHUmFkaWFsR3JhZGllbnRFbGVtZW50OlAuZDUsU1ZHUmVjdEVs
+ZW1lbnQ6UC5kNSxTVkdTZXRFbGVtZW50OlAuZDUsU1ZHU3RvcEVsZW1lbnQ6UC5kNSxTVkdTdHlsZUVs
+ZW1lbnQ6UC5kNSxTVkdTVkdFbGVtZW50OlAuZDUsU1ZHU3dpdGNoRWxlbWVudDpQLmQ1LFNWR1N5bWJv
+bEVsZW1lbnQ6UC5kNSxTVkdUU3BhbkVsZW1lbnQ6UC5kNSxTVkdUZXh0Q29udGVudEVsZW1lbnQ6UC5k
+NSxTVkdUZXh0RWxlbWVudDpQLmQ1LFNWR1RleHRQYXRoRWxlbWVudDpQLmQ1LFNWR1RleHRQb3NpdGlv
+bmluZ0VsZW1lbnQ6UC5kNSxTVkdUaXRsZUVsZW1lbnQ6UC5kNSxTVkdVc2VFbGVtZW50OlAuZDUsU1ZH
+Vmlld0VsZW1lbnQ6UC5kNSxTVkdHcmFkaWVudEVsZW1lbnQ6UC5kNSxTVkdDb21wb25lbnRUcmFuc2Zl
+ckZ1bmN0aW9uRWxlbWVudDpQLmQ1LFNWR0ZFRHJvcFNoYWRvd0VsZW1lbnQ6UC5kNSxTVkdNUGF0aEVs
+ZW1lbnQ6UC5kNSxTVkdFbGVtZW50OlAuZDV9KQpodW5rSGVscGVycy5zZXRPclVwZGF0ZUxlYWZUYWdz
+KHtET01FcnJvcjp0cnVlLERPTUltcGxlbWVudGF0aW9uOnRydWUsTWVkaWFFcnJvcjp0cnVlLE5hdmln
+YXRvcjp0cnVlLE5hdmlnYXRvckNvbmN1cnJlbnRIYXJkd2FyZTp0cnVlLE5hdmlnYXRvclVzZXJNZWRp
+YUVycm9yOnRydWUsT3ZlcmNvbnN0cmFpbmVkRXJyb3I6dHJ1ZSxQb3NpdGlvbkVycm9yOnRydWUsUmFu
+Z2U6dHJ1ZSxTUUxFcnJvcjp0cnVlLERhdGFWaWV3OnRydWUsQXJyYXlCdWZmZXJWaWV3OmZhbHNlLEZs
+b2F0MzJBcnJheTp0cnVlLEZsb2F0NjRBcnJheTp0cnVlLEludDE2QXJyYXk6dHJ1ZSxJbnQzMkFycmF5
+OnRydWUsSW50OEFycmF5OnRydWUsVWludDE2QXJyYXk6dHJ1ZSxVaW50MzJBcnJheTp0cnVlLFVpbnQ4
+Q2xhbXBlZEFycmF5OnRydWUsQ2FudmFzUGl4ZWxBcnJheTp0cnVlLFVpbnQ4QXJyYXk6ZmFsc2UsSFRN
+TEF1ZGlvRWxlbWVudDp0cnVlLEhUTUxCUkVsZW1lbnQ6dHJ1ZSxIVE1MQnV0dG9uRWxlbWVudDp0cnVl
+LEhUTUxDYW52YXNFbGVtZW50OnRydWUsSFRNTENvbnRlbnRFbGVtZW50OnRydWUsSFRNTERMaXN0RWxl
+bWVudDp0cnVlLEhUTUxEYXRhRWxlbWVudDp0cnVlLEhUTUxEYXRhTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1M
+RGV0YWlsc0VsZW1lbnQ6dHJ1ZSxIVE1MRGlhbG9nRWxlbWVudDp0cnVlLEhUTUxEaXZFbGVtZW50OnRy
+dWUsSFRNTEVtYmVkRWxlbWVudDp0cnVlLEhUTUxGaWVsZFNldEVsZW1lbnQ6dHJ1ZSxIVE1MSFJFbGVt
+ZW50OnRydWUsSFRNTEhlYWRFbGVtZW50OnRydWUsSFRNTEhlYWRpbmdFbGVtZW50OnRydWUsSFRNTEh0
+bWxFbGVtZW50OnRydWUsSFRNTElGcmFtZUVsZW1lbnQ6dHJ1ZSxIVE1MSW1hZ2VFbGVtZW50OnRydWUs
+SFRNTElucHV0RWxlbWVudDp0cnVlLEhUTUxMSUVsZW1lbnQ6dHJ1ZSxIVE1MTGFiZWxFbGVtZW50OnRy
+dWUsSFRNTExlZ2VuZEVsZW1lbnQ6dHJ1ZSxIVE1MTGlua0VsZW1lbnQ6dHJ1ZSxIVE1MTWFwRWxlbWVu
+dDp0cnVlLEhUTUxNZWRpYUVsZW1lbnQ6dHJ1ZSxIVE1MTWVudUVsZW1lbnQ6dHJ1ZSxIVE1MTWV0YUVs
+ZW1lbnQ6dHJ1ZSxIVE1MTWV0ZXJFbGVtZW50OnRydWUsSFRNTE1vZEVsZW1lbnQ6dHJ1ZSxIVE1MT0xp
+c3RFbGVtZW50OnRydWUsSFRNTE9iamVjdEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0R3JvdXBFbGVtZW50OnRy
+dWUsSFRNTE9wdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MT3V0cHV0RWxlbWVudDp0cnVlLEhUTUxQYXJhbUVs
+ZW1lbnQ6dHJ1ZSxIVE1MUGljdHVyZUVsZW1lbnQ6dHJ1ZSxIVE1MUHJlRWxlbWVudDp0cnVlLEhUTUxQ
+cm9ncmVzc0VsZW1lbnQ6dHJ1ZSxIVE1MUXVvdGVFbGVtZW50OnRydWUsSFRNTFNjcmlwdEVsZW1lbnQ6
+dHJ1ZSxIVE1MU2hhZG93RWxlbWVudDp0cnVlLEhUTUxTbG90RWxlbWVudDp0cnVlLEhUTUxTb3VyY2VF
+bGVtZW50OnRydWUsSFRNTFNwYW5FbGVtZW50OnRydWUsSFRNTFN0eWxlRWxlbWVudDp0cnVlLEhUTUxU
+YWJsZUNhcHRpb25FbGVtZW50OnRydWUsSFRNTFRhYmxlQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVE
+YXRhQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVIZWFkZXJDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJs
+ZUNvbEVsZW1lbnQ6dHJ1ZSxIVE1MVGV4dEFyZWFFbGVtZW50OnRydWUsSFRNTFRpbWVFbGVtZW50OnRy
+dWUsSFRNTFRpdGxlRWxlbWVudDp0cnVlLEhUTUxUcmFja0VsZW1lbnQ6dHJ1ZSxIVE1MVUxpc3RFbGVt
+ZW50OnRydWUsSFRNTFVua25vd25FbGVtZW50OnRydWUsSFRNTFZpZGVvRWxlbWVudDp0cnVlLEhUTUxE
+aXJlY3RvcnlFbGVtZW50OnRydWUsSFRNTEZvbnRFbGVtZW50OnRydWUsSFRNTEZyYW1lRWxlbWVudDp0
+cnVlLEhUTUxGcmFtZVNldEVsZW1lbnQ6dHJ1ZSxIVE1MTWFycXVlZUVsZW1lbnQ6dHJ1ZSxIVE1MRWxl
+bWVudDpmYWxzZSxIVE1MQW5jaG9yRWxlbWVudDp0cnVlLEhUTUxBcmVhRWxlbWVudDp0cnVlLEhUTUxC
+YXNlRWxlbWVudDp0cnVlLEJsb2I6ZmFsc2UsSFRNTEJvZHlFbGVtZW50OnRydWUsQ0RBVEFTZWN0aW9u
+OnRydWUsQ2hhcmFjdGVyRGF0YTp0cnVlLENvbW1lbnQ6dHJ1ZSxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb246
+dHJ1ZSxUZXh0OnRydWUsQ1NTU3R5bGVEZWNsYXJhdGlvbjp0cnVlLE1TU3R5bGVDU1NQcm9wZXJ0aWVz
+OnRydWUsQ1NTMlByb3BlcnRpZXM6dHJ1ZSxYTUxEb2N1bWVudDp0cnVlLERvY3VtZW50OmZhbHNlLERP
+TUV4Y2VwdGlvbjp0cnVlLERPTVJlY3RSZWFkT25seTpmYWxzZSxET01Ub2tlbkxpc3Q6dHJ1ZSxFbGVt
+ZW50OmZhbHNlLEFib3J0UGF5bWVudEV2ZW50OnRydWUsQW5pbWF0aW9uRXZlbnQ6dHJ1ZSxBbmltYXRp
+b25QbGF5YmFja0V2ZW50OnRydWUsQXBwbGljYXRpb25DYWNoZUVycm9yRXZlbnQ6dHJ1ZSxCYWNrZ3Jv
+dW5kRmV0Y2hDbGlja0V2ZW50OnRydWUsQmFja2dyb3VuZEZldGNoRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5k
+RmV0Y2hGYWlsRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hlZEV2ZW50OnRydWUsQmVmb3JlSW5zdGFs
+bFByb21wdEV2ZW50OnRydWUsQmVmb3JlVW5sb2FkRXZlbnQ6dHJ1ZSxCbG9iRXZlbnQ6dHJ1ZSxDYW5N
+YWtlUGF5bWVudEV2ZW50OnRydWUsQ2xpcGJvYXJkRXZlbnQ6dHJ1ZSxDbG9zZUV2ZW50OnRydWUsQ3Vz
+dG9tRXZlbnQ6dHJ1ZSxEZXZpY2VNb3Rpb25FdmVudDp0cnVlLERldmljZU9yaWVudGF0aW9uRXZlbnQ6
+dHJ1ZSxFcnJvckV2ZW50OnRydWUsRXh0ZW5kYWJsZUV2ZW50OnRydWUsRXh0ZW5kYWJsZU1lc3NhZ2VF
+dmVudDp0cnVlLEZldGNoRXZlbnQ6dHJ1ZSxGb250RmFjZVNldExvYWRFdmVudDp0cnVlLEZvcmVpZ25G
+ZXRjaEV2ZW50OnRydWUsR2FtZXBhZEV2ZW50OnRydWUsSGFzaENoYW5nZUV2ZW50OnRydWUsSW5zdGFs
+bEV2ZW50OnRydWUsTWVkaWFFbmNyeXB0ZWRFdmVudDp0cnVlLE1lZGlhS2V5TWVzc2FnZUV2ZW50OnRy
+dWUsTWVkaWFRdWVyeUxpc3RFdmVudDp0cnVlLE1lZGlhU3RyZWFtRXZlbnQ6dHJ1ZSxNZWRpYVN0cmVh
+bVRyYWNrRXZlbnQ6dHJ1ZSxNZXNzYWdlRXZlbnQ6dHJ1ZSxNSURJQ29ubmVjdGlvbkV2ZW50OnRydWUs
+TUlESU1lc3NhZ2VFdmVudDp0cnVlLE11dGF0aW9uRXZlbnQ6dHJ1ZSxOb3RpZmljYXRpb25FdmVudDp0
+cnVlLFBhZ2VUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxQYXltZW50UmVxdWVzdEV2ZW50OnRydWUsUGF5bWVu
+dFJlcXVlc3RVcGRhdGVFdmVudDp0cnVlLFBvcFN0YXRlRXZlbnQ6dHJ1ZSxQcmVzZW50YXRpb25Db25u
+ZWN0aW9uQXZhaWxhYmxlRXZlbnQ6dHJ1ZSxQcmVzZW50YXRpb25Db25uZWN0aW9uQ2xvc2VFdmVudDp0
+cnVlLFByb21pc2VSZWplY3Rpb25FdmVudDp0cnVlLFB1c2hFdmVudDp0cnVlLFJUQ0RhdGFDaGFubmVs
+RXZlbnQ6dHJ1ZSxSVENEVE1GVG9uZUNoYW5nZUV2ZW50OnRydWUsUlRDUGVlckNvbm5lY3Rpb25JY2VF
+dmVudDp0cnVlLFJUQ1RyYWNrRXZlbnQ6dHJ1ZSxTZWN1cml0eVBvbGljeVZpb2xhdGlvbkV2ZW50OnRy
+dWUsU2Vuc29yRXJyb3JFdmVudDp0cnVlLFNwZWVjaFJlY29nbml0aW9uRXJyb3I6dHJ1ZSxTcGVlY2hS
+ZWNvZ25pdGlvbkV2ZW50OnRydWUsU3BlZWNoU3ludGhlc2lzRXZlbnQ6dHJ1ZSxTdG9yYWdlRXZlbnQ6
+dHJ1ZSxTeW5jRXZlbnQ6dHJ1ZSxUcmFja0V2ZW50OnRydWUsVHJhbnNpdGlvbkV2ZW50OnRydWUsV2Vi
+S2l0VHJhbnNpdGlvbkV2ZW50OnRydWUsVlJEZXZpY2VFdmVudDp0cnVlLFZSRGlzcGxheUV2ZW50OnRy
+dWUsVlJTZXNzaW9uRXZlbnQ6dHJ1ZSxNb2pvSW50ZXJmYWNlUmVxdWVzdEV2ZW50OnRydWUsVVNCQ29u
+bmVjdGlvbkV2ZW50OnRydWUsSURCVmVyc2lvbkNoYW5nZUV2ZW50OnRydWUsQXVkaW9Qcm9jZXNzaW5n
+RXZlbnQ6dHJ1ZSxPZmZsaW5lQXVkaW9Db21wbGV0aW9uRXZlbnQ6dHJ1ZSxXZWJHTENvbnRleHRFdmVu
+dDp0cnVlLEV2ZW50OmZhbHNlLElucHV0RXZlbnQ6ZmFsc2UsRXZlbnRUYXJnZXQ6ZmFsc2UsRmlsZTp0
+cnVlLEhUTUxGb3JtRWxlbWVudDp0cnVlLEhpc3Rvcnk6dHJ1ZSxIVE1MRG9jdW1lbnQ6dHJ1ZSxYTUxI
+dHRwUmVxdWVzdDp0cnVlLFhNTEh0dHBSZXF1ZXN0RXZlbnRUYXJnZXQ6ZmFsc2UsSW1hZ2VEYXRhOnRy
+dWUsTG9jYXRpb246dHJ1ZSxNb3VzZUV2ZW50OnRydWUsRHJhZ0V2ZW50OnRydWUsUG9pbnRlckV2ZW50
+OnRydWUsV2hlZWxFdmVudDp0cnVlLERvY3VtZW50RnJhZ21lbnQ6dHJ1ZSxTaGFkb3dSb290OnRydWUs
+RG9jdW1lbnRUeXBlOnRydWUsTm9kZTpmYWxzZSxOb2RlTGlzdDp0cnVlLFJhZGlvTm9kZUxpc3Q6dHJ1
+ZSxIVE1MUGFyYWdyYXBoRWxlbWVudDp0cnVlLFByb2dyZXNzRXZlbnQ6dHJ1ZSxSZXNvdXJjZVByb2dy
+ZXNzRXZlbnQ6dHJ1ZSxIVE1MU2VsZWN0RWxlbWVudDp0cnVlLEhUTUxUYWJsZUVsZW1lbnQ6dHJ1ZSxI
+VE1MVGFibGVSb3dFbGVtZW50OnRydWUsSFRNTFRhYmxlU2VjdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MVGVt
+cGxhdGVFbGVtZW50OnRydWUsQ29tcG9zaXRpb25FdmVudDp0cnVlLEZvY3VzRXZlbnQ6dHJ1ZSxLZXli
+b2FyZEV2ZW50OnRydWUsVGV4dEV2ZW50OnRydWUsVG91Y2hFdmVudDp0cnVlLFVJRXZlbnQ6ZmFsc2Us
+V2luZG93OnRydWUsRE9NV2luZG93OnRydWUsRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxT
+ZXJ2aWNlV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxTaGFyZWRXb3JrZXJHbG9iYWxTY29wZTp0cnVlLFdv
+cmtlckdsb2JhbFNjb3BlOnRydWUsQXR0cjp0cnVlLENsaWVudFJlY3Q6dHJ1ZSxET01SZWN0OnRydWUs
+TmFtZWROb2RlTWFwOnRydWUsTW96TmFtZWRBdHRyTWFwOnRydWUsSURCS2V5UmFuZ2U6dHJ1ZSxTVkdT
+Y3JpcHRFbGVtZW50OnRydWUsU1ZHQUVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlRWxlbWVudDp0cnVlLFNW
+R0FuaW1hdGVNb3Rpb25FbGVtZW50OnRydWUsU1ZHQW5pbWF0ZVRyYW5zZm9ybUVsZW1lbnQ6dHJ1ZSxT
+VkdBbmltYXRpb25FbGVtZW50OnRydWUsU1ZHQ2lyY2xlRWxlbWVudDp0cnVlLFNWR0NsaXBQYXRoRWxl
+bWVudDp0cnVlLFNWR0RlZnNFbGVtZW50OnRydWUsU1ZHRGVzY0VsZW1lbnQ6dHJ1ZSxTVkdEaXNjYXJk
+RWxlbWVudDp0cnVlLFNWR0VsbGlwc2VFbGVtZW50OnRydWUsU1ZHRkVCbGVuZEVsZW1lbnQ6dHJ1ZSxT
+VkdGRUNvbG9yTWF0cml4RWxlbWVudDp0cnVlLFNWR0ZFQ29tcG9uZW50VHJhbnNmZXJFbGVtZW50OnRy
+dWUsU1ZHRkVDb21wb3NpdGVFbGVtZW50OnRydWUsU1ZHRkVDb252b2x2ZU1hdHJpeEVsZW1lbnQ6dHJ1
+ZSxTVkdGRURpZmZ1c2VMaWdodGluZ0VsZW1lbnQ6dHJ1ZSxTVkdGRURpc3BsYWNlbWVudE1hcEVsZW1l
+bnQ6dHJ1ZSxTVkdGRURpc3RhbnRMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRUZsb29kRWxlbWVudDp0cnVl
+LFNWR0ZFRnVuY0FFbGVtZW50OnRydWUsU1ZHRkVGdW5jQkVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNHRWxl
+bWVudDp0cnVlLFNWR0ZFRnVuY1JFbGVtZW50OnRydWUsU1ZHRkVHYXVzc2lhbkJsdXJFbGVtZW50OnRy
+dWUsU1ZHRkVJbWFnZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1lcmdlRWxlbWVudDp0cnVlLFNWR0ZFTWVyZ2VO
+b2RlRWxlbWVudDp0cnVlLFNWR0ZFTW9ycGhvbG9neUVsZW1lbnQ6dHJ1ZSxTVkdGRU9mZnNldEVsZW1l
+bnQ6dHJ1ZSxTVkdGRVBvaW50TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVTcGVjdWxhckxpZ2h0aW5nRWxl
+bWVudDp0cnVlLFNWR0ZFU3BvdExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFVGlsZUVsZW1lbnQ6dHJ1ZSxT
+VkdGRVR1cmJ1bGVuY2VFbGVtZW50OnRydWUsU1ZHRmlsdGVyRWxlbWVudDp0cnVlLFNWR0ZvcmVpZ25P
+YmplY3RFbGVtZW50OnRydWUsU1ZHR0VsZW1lbnQ6dHJ1ZSxTVkdHZW9tZXRyeUVsZW1lbnQ6dHJ1ZSxT
+VkdHcmFwaGljc0VsZW1lbnQ6dHJ1ZSxTVkdJbWFnZUVsZW1lbnQ6dHJ1ZSxTVkdMaW5lRWxlbWVudDp0
+cnVlLFNWR0xpbmVhckdyYWRpZW50RWxlbWVudDp0cnVlLFNWR01hcmtlckVsZW1lbnQ6dHJ1ZSxTVkdN
+YXNrRWxlbWVudDp0cnVlLFNWR01ldGFkYXRhRWxlbWVudDp0cnVlLFNWR1BhdGhFbGVtZW50OnRydWUs
+U1ZHUGF0dGVybkVsZW1lbnQ6dHJ1ZSxTVkdQb2x5Z29uRWxlbWVudDp0cnVlLFNWR1BvbHlsaW5lRWxl
+bWVudDp0cnVlLFNWR1JhZGlhbEdyYWRpZW50RWxlbWVudDp0cnVlLFNWR1JlY3RFbGVtZW50OnRydWUs
+U1ZHU2V0RWxlbWVudDp0cnVlLFNWR1N0b3BFbGVtZW50OnRydWUsU1ZHU3R5bGVFbGVtZW50OnRydWUs
+U1ZHU1ZHRWxlbWVudDp0cnVlLFNWR1N3aXRjaEVsZW1lbnQ6dHJ1ZSxTVkdTeW1ib2xFbGVtZW50OnRy
+dWUsU1ZHVFNwYW5FbGVtZW50OnRydWUsU1ZHVGV4dENvbnRlbnRFbGVtZW50OnRydWUsU1ZHVGV4dEVs
+ZW1lbnQ6dHJ1ZSxTVkdUZXh0UGF0aEVsZW1lbnQ6dHJ1ZSxTVkdUZXh0UG9zaXRpb25pbmdFbGVtZW50
+OnRydWUsU1ZHVGl0bGVFbGVtZW50OnRydWUsU1ZHVXNlRWxlbWVudDp0cnVlLFNWR1ZpZXdFbGVtZW50
+OnRydWUsU1ZHR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHQ29tcG9uZW50VHJhbnNmZXJGdW5jdGlvbkVs
+ZW1lbnQ6dHJ1ZSxTVkdGRURyb3BTaGFkb3dFbGVtZW50OnRydWUsU1ZHTVBhdGhFbGVtZW50OnRydWUs
+U1ZHRWxlbWVudDpmYWxzZX0pCkguYjAuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmll
+dyIKSC5SRy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlZQLiRuYXRpdmVT
+dXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguRGcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFy
+cmF5QnVmZmVyVmlldyIKSC5XQi4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpI
+LlpHLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXciCkguUGcuJG5hdGl2ZVN1cGVy
+Y2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyJ9KSgpCmNvbnZlcnRBbGxUb0Zhc3RPYmplY3QodykKY29u
+dmVydFRvRmFzdE9iamVjdCgkKTsoZnVuY3Rpb24oYSl7aWYodHlwZW9mIGRvY3VtZW50PT09InVuZGVm
+aW5lZCIpe2EobnVsbCkKcmV0dXJufWlmKHR5cGVvZiBkb2N1bWVudC5jdXJyZW50U2NyaXB0IT0ndW5k
+ZWZpbmVkJyl7YShkb2N1bWVudC5jdXJyZW50U2NyaXB0KQpyZXR1cm59dmFyIHQ9ZG9jdW1lbnQuc2Ny
+aXB0cwpmdW5jdGlvbiBvbkxvYWQoYil7Zm9yKHZhciByPTA7cjx0Lmxlbmd0aDsrK3IpdFtyXS5yZW1v
+dmVFdmVudExpc3RlbmVyKCJsb2FkIixvbkxvYWQsZmFsc2UpCmEoYi50YXJnZXQpfWZvcih2YXIgcz0w
+O3M8dC5sZW5ndGg7KytzKXRbc10uYWRkRXZlbnRMaXN0ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKX0p
+KGZ1bmN0aW9uKGEpe3YuY3VycmVudFNjcmlwdD1hCmlmKHR5cGVvZiBkYXJ0TWFpblJ1bm5lcj09PSJm
+dW5jdGlvbiIpZGFydE1haW5SdW5uZXIoTC5JcSxbXSkKZWxzZSBMLklxKFtdKX0pfSkoKQovLyMgc291
+cmNlTWFwcGluZ1VSTD1taWdyYXRpb24uanMubWFwCg==
 ''';
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart
index 53b9557..c187ebf 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/web/migration.dart
@@ -374,13 +374,13 @@
 final Element editPanel = document.querySelector('.edit-panel .panel-content');
 
 void populateEditDetails([EditDetails response]) {
+  // Clear out any current edit details.
   editPanel.innerHtml = '';
-
   if (response == null) {
-    // Clear out any current edit details.
-    editPanel.append(ParagraphElement()
+    Element p = editPanel.append(ParagraphElement()
       ..text = 'See details about a proposed edit.'
       ..classes = ['placeholder']);
+    p.scrollIntoView();
     return;
   }
 
@@ -393,6 +393,7 @@
   int line = response.line;
   Element explanation = editPanel.append(document.createElement('p'));
   explanation.append(Text('$explanationMessage at $relPath:$line.'));
+  explanation.scrollIntoView();
   _populateEditTraces(response, editPanel, parentDirectory);
   _populateEditLinks(response, editPanel);
   _populateEditRationale(response, editPanel, parentDirectory);
diff --git a/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart b/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart
index 9a990fd..4fb256c 100644
--- a/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart
+++ b/pkg/analysis_server/lib/src/lsp/channel/lsp_byte_stream_channel.dart
@@ -128,9 +128,9 @@
 
   /// Send [bytes] to [_output].
   void _write(List<int> bytes) {
-    runZoned(
+    runZonedGuarded(
       () => _output.add(bytes),
-      onError: (e) => close(),
+      (e, s) => close(),
     );
   }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index c8a69de..b806164 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -245,7 +245,7 @@
   /// Handle a [message] that was read from the communication channel.
   void handleMessage(Message message) {
     performance.logRequestTiming(null);
-    runZoned(() {
+    runZonedGuarded(() {
       ServerPerformanceStatistics.serverRequests.makeCurrentWhile(() async {
         try {
           if (message is ResponseMessage) {
@@ -284,7 +284,7 @@
           logException(errorMessage, error, stackTrace);
         }
       });
-    }, onError: socketError);
+    }, socketError);
   }
 
   /// Logs the error on the client using window/logMessage.
diff --git a/pkg/analysis_server/lib/src/server/detachable_filesystem_manager.dart b/pkg/analysis_server/lib/src/server/detachable_filesystem_manager.dart
index 1754ffd..d32ca39 100644
--- a/pkg/analysis_server/lib/src/server/detachable_filesystem_manager.dart
+++ b/pkg/analysis_server/lib/src/server/detachable_filesystem_manager.dart
@@ -4,7 +4,7 @@
 
 import 'package:analysis_server/src/analysis_server.dart';
 
-/// A class that can be used to confirm an analysis server instance to better
+/// A class that can be used to configure an analysis server instance to better
 /// support intermittent file systems.
 ///
 /// See also [AnalysisServerOptions.detachableFileSystemManager].
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 6cb9049..fbd4731 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -20,6 +20,7 @@
 import 'package:analysis_server/src/server/features.dart';
 import 'package:analysis_server/src/server/http_server.dart';
 import 'package:analysis_server/src/server/lsp_stdio_server.dart';
+import 'package:analysis_server/src/server/sdk_configuration.dart';
 import 'package:analysis_server/src/server/stdio_server.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_ranking.dart';
 import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart'
@@ -326,6 +327,11 @@
     analysisServerOptions.useLanguageServerProtocol = results[USE_LSP];
     analysisServerOptions.useNewRelevance = results[USE_NEW_RELEVANCE];
 
+    // Read in any per-SDK overrides specified in <sdk>/config/settings.json.
+    SdkConfiguration sdkConfig = SdkConfiguration.readFromSdk();
+    analysisServerOptions.configurationOverrides = sdkConfig;
+
+    // ML model configuration.
     final bool enableCompletionModel = results[ENABLE_COMPLETION_MODEL];
     analysisServerOptions.completionModelFolder =
         results[COMPLETION_MODEL_FOLDER];
@@ -334,6 +340,7 @@
       // code completion.
       analysisServerOptions.completionModelFolder = null;
     }
+    // TODO(devoncarew): Simplify this logic and use the value from sdkConfig.
     if (enableCompletionModel &&
         analysisServerOptions.completionModelFolder == null) {
       // The user has enabled ML code completion without explicitly setting a
@@ -348,14 +355,21 @@
       );
     }
 
+    // Analytics
     bool disableAnalyticsForSession = results[SUPPRESS_ANALYTICS_FLAG];
     if (results.wasParsed(TRAIN_USING)) {
       disableAnalyticsForSession = true;
     }
 
-    telemetry.Analytics analytics = telemetry.createAnalyticsInstance(
-        'UA-26406144-29', 'analysis-server',
-        disableForSession: disableAnalyticsForSession);
+    // Use sdkConfig to optionally override analytics settings.
+    final analyticsId = sdkConfig.analyticsId ?? 'UA-26406144-29';
+    final forceAnalyticsEnabled = sdkConfig.analyticsForceEnabled == true;
+    var analytics = telemetry.createAnalyticsInstance(
+      analyticsId,
+      'analysis-server',
+      disableForSession: disableAnalyticsForSession,
+      forceEnabled: forceAnalyticsEnabled,
+    );
     analysisServerOptions.analytics = analytics;
 
     if (analysisServerOptions.clientId != null) {
@@ -366,13 +380,22 @@
       analytics.setSessionValue('cd1', analysisServerOptions.clientVersion);
     }
 
-    final shouldSendCallback = () {
+    final EnablementCallback shouldSendCallback = () {
+      // Check sdkConfig to optionally force reporting on.
+      if (sdkConfig.crashReportingForceEnabled == true) {
+        return true;
+      }
+
       // TODO(devoncarew): Replace with a real enablement check.
       return false;
     };
 
+    // Crash reporting
+
+    // Use sdkConfig to optionally override analytics settings.
+    final crashProductId = sdkConfig.crashReportingId ?? 'Dart_analysis_server';
     final crashReportSender =
-        CrashReportSender('Dart_analysis_server', shouldSendCallback);
+        CrashReportSender(crashProductId, shouldSendCallback);
 
     if (telemetry.SHOW_ANALYTICS_UI) {
       if (results.wasParsed(ANALYTICS_FLAG)) {
diff --git a/pkg/analysis_server/lib/src/server/sdk_configuration.dart b/pkg/analysis_server/lib/src/server/sdk_configuration.dart
new file mode 100644
index 0000000..d952a21
--- /dev/null
+++ b/pkg/analysis_server/lib/src/server/sdk_configuration.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+
+import 'package:path/path.dart' as path;
+
+/// A class to represent a SDK configuration file.
+///
+/// This file may or may not be present in a Dart SDK. If it exists, the values
+/// in it can be used to configure the SDK for specific environments, like
+/// google3. This file generally lives in `<dart-sdk>/config/settings.json`.
+class SdkConfiguration {
+  final Map<String, dynamic> _values = {};
+
+  SdkConfiguration.readFromFile(File file) {
+    if (!file.existsSync()) {
+      throw '$file not found';
+    }
+
+    _readFromFile(file);
+  }
+
+  /// Create an SDK configuration based on any SDK configuration file at
+  /// <dart-sdk>/config/settings.json.
+  ///
+  /// This constructor will still create an object even if a configuration file
+  /// is not found.
+  SdkConfiguration.readFromSdk() {
+    // <dart-sdk>/config/settings.json:
+    final sdkDir =
+        Directory(path.dirname(path.dirname(Platform.resolvedExecutable)));
+    final configFile = File(path.join(sdkDir.path, 'config', 'settings.json'));
+
+    if (configFile.existsSync()) {
+      _readFromFile(configFile);
+    }
+  }
+
+  /// Whether analytics is forced on.
+  bool get analyticsForceEnabled => _values['server.analytics.forceEnabled'];
+
+  /// Return a override value for the analysis server's google analytics ID.
+  String get analyticsId => _values['server.analytics.id'];
+
+  /// Whether crash reporting is forced on.
+  bool get crashReportingForceEnabled =>
+      _values['server.crash.reporting.forceEnabled'];
+
+  /// Return a override value for the analysis server's crash reporting product
+  /// ID.
+  String get crashReportingId => _values['server.crash.reporting.id'];
+
+  /// Return a string describing the contents of this SDK configuration.
+  String get displayString {
+    return _values.keys.map((key) => '$key: ${_values[key]}').join(('\n'));
+  }
+
+  /// Returns whether this SDK configuration has any configured values.
+  bool get hasAnyOverrides => _values.isNotEmpty;
+
+  /// Return an override value for the analysis server's ML model file path.
+  String get mlModelPath => _values['server.ml.model.path'];
+
+  @override
+  String toString() => displayString;
+
+  void _readFromFile(File file) {
+    try {
+      Map m = jsonDecode(file.readAsStringSync());
+      for (var key in m.keys) {
+        _values[key] = m[key];
+      }
+    } catch (_) {
+      // ignore issues reading the file
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
index 79b566e..8c3d863 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -16,120 +16,162 @@
 import 'package:analyzer/src/util/comment.dart';
 import 'package:meta/meta.dart';
 
-/// Determine the number of arguments.
-int _argCount(DartCompletionRequest request) {
-  AstNode node = request.target.containingNode;
-  if (node is ArgumentList) {
-    if (request.target.entity == node.rightParenthesis) {
-      // Parser ignores trailing commas
-      if (node.findPrevious(node.rightParenthesis)?.lexeme == ',') {
-        return node.arguments.length + 1;
-      }
-    }
-    return node.arguments.length;
-  }
-  return 0;
-}
-
-/// Determine if the completion target is at the end of the list of arguments.
-bool _isAppendingToArgList(DartCompletionRequest request) {
-  AstNode node = request.target.containingNode;
-  if (node is ArgumentList) {
-    var entity = request.target.entity;
-    if (entity == node.rightParenthesis) {
-      return true;
-    }
-    if (node.arguments.isNotEmpty && node.arguments.last == entity) {
-      return entity is SimpleIdentifier;
-    }
-  }
-  return false;
-}
-
-/// Determine if the completion target is the label for a named argument.
-bool _isEditingNamedArgLabel(DartCompletionRequest request) {
-  AstNode node = request.target.containingNode;
-  if (node is ArgumentList) {
-    var entity = request.target.entity;
-    if (entity is NamedExpression) {
-      int offset = request.offset;
-      if (entity.offset < offset && offset < entity.end) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-/// Return `true` if the [request] is inside of a [NamedExpression] name.
-bool _isInNamedExpression(DartCompletionRequest request) {
-  Object entity = request.target.entity;
-  if (entity is NamedExpression) {
-    Label name = entity.name;
-    return name.offset < request.offset && request.offset < name.end;
-  }
-  return false;
-}
-
-/// Determine if the completion target is in the middle or beginning of the list
-/// of named parameters and is not preceded by a comma. This method assumes that
-/// _isAppendingToArgList has been called and is false.
-bool _isInsertingToArgListWithNoSynthetic(DartCompletionRequest request) {
-  AstNode node = request.target.containingNode;
-  if (node is ArgumentList) {
-    var entity = request.target.entity;
-    return entity is NamedExpression;
-  }
-  return false;
-}
-
-/// Determine if the completion target is in the middle or beginning of the list
-/// of named parameters and is preceded by a comma. This method assumes that
-/// _isAppendingToArgList and _isInsertingToArgListWithNoSynthetic have been
-/// called and both return false.
-bool _isInsertingToArgListWithSynthetic(DartCompletionRequest request) {
-  AstNode node = request.target.containingNode;
-  if (node is ArgumentList) {
-    var entity = request.target.entity;
-    if (entity is SimpleIdentifier) {
-      int argIndex = request.target.argIndex;
-      // if the next argument is a NamedExpression, then we are in the named
-      // parameter list, guard first against end of list
-      if (node.arguments.length == argIndex + 1 ||
-          node.arguments.getRange(argIndex + 1, argIndex + 2).first
-              is NamedExpression) {
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-/// Return a collection of currently specified named arguments
-Iterable<String> _namedArgs(DartCompletionRequest request) {
-  AstNode node = request.target.containingNode;
-  List<String> namedArgs = <String>[];
-  if (node is ArgumentList) {
-    for (Expression arg in node.arguments) {
-      if (arg is NamedExpression) {
-        namedArgs.add(arg.name.label.name);
-      }
-    }
-  }
-  return namedArgs;
-}
-
-/// A contributor for calculating `completion.getSuggestions` request results
-/// when the cursor position is inside the arguments to a method call.
+/// A contributor that produces suggestions for named expression labels that
+/// correspond to named parameters when completing in argument lists.
 class ArgListContributor extends DartCompletionContributor {
+  /// The request that is currently being handled.
   DartCompletionRequest request;
+
+  /// The argument list that is the containing node of the target, or `null` if
+  /// the containing node of the target is not an argument list (such as when
+  /// it's a named expression).
+  ArgumentList argumentList;
+
+  /// The list of suggestions that is currently being built.
   List<CompletionSuggestion> suggestions;
 
-  List<CompletionSuggestion> buildClosureSuggestions(
-    DartCompletionRequest request,
-    Expression argument,
-    DartType type,
-  ) {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    var executable = request.target.executableElement;
+    if (executable == null) {
+      return const <CompletionSuggestion>[];
+    }
+    var node = request.target.containingNode;
+    if (node is ArgumentList) {
+      argumentList = node;
+    }
+
+    this.request = request;
+    suggestions = <CompletionSuggestion>[];
+    _addSuggestions(executable.parameters);
+    return suggestions;
+  }
+
+  void _addDefaultParamSuggestions(Iterable<ParameterElement> parameters,
+      [bool appendComma = false]) {
+    var appendColon = !_isInNamedExpression();
+    var namedArgs = _namedArgs();
+    for (var parameter in parameters) {
+      if (parameter.isNamed) {
+        _addNamedParameterSuggestion(
+            namedArgs, parameter, appendColon, appendComma);
+      }
+    }
+  }
+
+  void _addNamedParameterSuggestion(List<String> namedArgs,
+      ParameterElement parameter, bool appendColon, bool appendComma) {
+    var name = parameter.name;
+    var type = parameter.type?.getDisplayString(withNullability: false);
+    if (name != null && name.isNotEmpty && !namedArgs.contains(name)) {
+      var completion = name;
+      if (appendColon) {
+        completion += ': ';
+      }
+      var selectionOffset = completion.length;
+
+      // Optionally add Flutter child widget details.
+      var element = parameter.enclosingElement;
+      if (element is ConstructorElement) {
+        var flutter = Flutter.of(request.result);
+        if (flutter.isWidget(element.enclosingElement)) {
+          var defaultValue = getDefaultStringParameterValue(parameter);
+          // TODO(devoncarew): Should we remove the check here? We would then
+          // suggest values for param types like closures.
+          if (defaultValue != null && defaultValue.text == '<Widget>[]') {
+            var completionLength = completion.length;
+            completion += defaultValue.text;
+            if (defaultValue.cursorPosition != null) {
+              selectionOffset = completionLength + defaultValue.cursorPosition;
+            }
+          }
+        }
+      }
+
+      if (appendComma) {
+        completion += ',';
+      }
+
+      int relevance;
+      if (parameter.isRequiredNamed || parameter.hasRequired) {
+        relevance = request.useNewRelevance
+            ? Relevance.requiredNamedArgument
+            : DART_RELEVANCE_NAMED_PARAMETER_REQUIRED;
+      } else {
+        relevance = request.useNewRelevance
+            ? Relevance.namedArgument
+            : DART_RELEVANCE_NAMED_PARAMETER;
+      }
+
+      var suggestion = CompletionSuggestion(
+          CompletionSuggestionKind.NAMED_ARGUMENT,
+          relevance,
+          completion,
+          selectionOffset,
+          0,
+          false,
+          false,
+          parameterName: name,
+          parameterType: type);
+      if (parameter is FieldFormalParameterElement) {
+        _setDocumentation(suggestion, parameter.field?.documentationComment);
+        suggestion.element = convertElement(parameter);
+      }
+
+      suggestions.add(suggestion);
+    }
+  }
+
+  void _addSuggestions(Iterable<ParameterElement> parameters) {
+    if (parameters == null || parameters.isEmpty) {
+      return;
+    }
+    var requiredParam =
+        parameters.where((ParameterElement p) => p.isRequiredPositional);
+    var requiredCount = requiredParam.length;
+    // TODO(jwren): _isAppendingToArgList can be split into two cases (with and
+    // without preceded), then _isAppendingToArgList,
+    // _isInsertingToArgListWithNoSynthetic and
+    // _isInsertingToArgListWithSynthetic could be formatted into a single
+    // method which returns some enum with 5+ cases.
+    if (_isEditingNamedArgLabel() || _isAppendingToArgList()) {
+      if (requiredCount == 0 || requiredCount < _argCount()) {
+        bool addTrailingComma =
+            !_isFollowedByAComma() && _isInFlutterCreation();
+        _addDefaultParamSuggestions(parameters, addTrailingComma);
+      }
+    } else if (_isInsertingToArgListWithNoSynthetic()) {
+      _addDefaultParamSuggestions(parameters, true);
+    } else if (_isInsertingToArgListWithSynthetic()) {
+      _addDefaultParamSuggestions(parameters, !_isFollowedByAComma());
+    } else {
+      var argument = request.target.containingNode;
+      if (argument is NamedExpression) {
+        _buildClosureSuggestions(argument);
+      }
+    }
+  }
+
+  /// Return the number of arguments in the argument list.
+  int _argCount() {
+    if (argumentList != null) {
+      var paren = argumentList.rightParenthesis;
+      if (request.target.entity == paren) {
+        // Parser ignores trailing commas
+        if (argumentList.findPrevious(paren)?.lexeme == ',') {
+          return argumentList.arguments.length + 1;
+        }
+      }
+      return argumentList.arguments.length;
+    }
+    return 0;
+  }
+
+  void _buildClosureSuggestions(NamedExpression argument) {
+    // TODO(brianwilkerson) Consider moving this support so that it can be used
+    //  whenever the context type is a FunctionType.
+    var type = argument.staticParameterElement?.type;
     if (type is FunctionType) {
       var indent = getRequestLineIndent(request);
       var parametersString = buildClosureParameters(type);
@@ -157,7 +199,7 @@
       }) {
         return CompletionSuggestion(
           CompletionSuggestionKind.INVOCATION,
-          DART_RELEVANCE_HIGH,
+          request.useNewRelevance ? Relevance.closure : DART_RELEVANCE_HIGH,
           completion,
           selectionOffset,
           0,
@@ -167,140 +209,50 @@
         );
       }
 
-      return [
-        createSuggestion(
-          completion: blockBuffer.toString(),
-          displayText: '$parametersString {}',
-          selectionOffset: blockSelectionOffset,
-        ),
-        createSuggestion(
-          completion: expressionBuffer.toString(),
-          displayText: '$parametersString =>',
-          selectionOffset: expressionSelectionOffset,
-        ),
-      ];
+      suggestions.add(createSuggestion(
+        completion: blockBuffer.toString(),
+        displayText: '$parametersString {}',
+        selectionOffset: blockSelectionOffset,
+      ));
+      suggestions.add(createSuggestion(
+        completion: expressionBuffer.toString(),
+        displayText: '$parametersString =>',
+        selectionOffset: expressionSelectionOffset,
+      ));
     }
-    return const <CompletionSuggestion>[];
   }
 
-  @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request) async {
-    this.request = request;
-    suggestions = <CompletionSuggestion>[];
-
-    var executable = request.target.executableElement;
-    if (executable == null) {
-      return const <CompletionSuggestion>[];
-    }
-
-    _addSuggestions(executable.parameters);
-    return suggestions;
-  }
-
-  void _addDefaultParamSuggestions(Iterable<ParameterElement> parameters,
-      [bool appendComma = false]) {
-    bool appendColon = !_isInNamedExpression(request);
-    Iterable<String> namedArgs = _namedArgs(request);
-    for (ParameterElement parameter in parameters) {
-      if (parameter.isNamed) {
-        _addNamedParameterSuggestion(
-            namedArgs, parameter, appendColon, appendComma);
+  /// Return `true` if the completion target is at the end of the list of
+  /// arguments.
+  bool _isAppendingToArgList() {
+    if (argumentList != null) {
+      var entity = request.target.entity;
+      if (entity == argumentList.rightParenthesis) {
+        return true;
+      }
+      if (argumentList.arguments.isNotEmpty &&
+          argumentList.arguments.last == entity) {
+        return entity is SimpleIdentifier;
       }
     }
+    return false;
   }
 
-  void _addNamedParameterSuggestion(List<String> namedArgs,
-      ParameterElement parameter, bool appendColon, bool appendComma) {
-    String name = parameter.name;
-    String type = parameter.type?.getDisplayString(withNullability: false);
-    if (name != null && name.isNotEmpty && !namedArgs.contains(name)) {
-      String completion = name;
-      if (appendColon) {
-        completion += ': ';
-      }
-      int selectionOffset = completion.length;
-
-      // Optionally add Flutter child widget details.
-      Element element = parameter.enclosingElement;
-      if (element is ConstructorElement) {
-        var flutter = Flutter.of(request.result);
-        if (flutter.isWidget(element.enclosingElement)) {
-          DefaultArgument defaultValue =
-              getDefaultStringParameterValue(parameter);
-          // TODO(devoncarew): Should we remove the check here? We would then
-          // suggest values for param types like closures.
-          if (defaultValue != null && defaultValue.text == '<Widget>[]') {
-            int completionLength = completion.length;
-            completion += defaultValue.text;
-            if (defaultValue.cursorPosition != null) {
-              selectionOffset = completionLength + defaultValue.cursorPosition;
-            }
-          }
+  /// Return `true` if the completion target is the label for a named argument.
+  bool _isEditingNamedArgLabel() {
+    if (argumentList != null) {
+      var entity = request.target.entity;
+      if (entity is NamedExpression) {
+        int offset = request.offset;
+        if (entity.offset < offset && offset < entity.end) {
+          return true;
         }
       }
-
-      if (appendComma) {
-        completion += ',';
-      }
-
-      final int relevance = parameter.hasRequired
-          ? DART_RELEVANCE_NAMED_PARAMETER_REQUIRED
-          : DART_RELEVANCE_NAMED_PARAMETER;
-
-      CompletionSuggestion suggestion = CompletionSuggestion(
-          CompletionSuggestionKind.NAMED_ARGUMENT,
-          relevance,
-          completion,
-          selectionOffset,
-          0,
-          false,
-          false,
-          parameterName: name,
-          parameterType: type);
-      if (parameter is FieldFormalParameterElement) {
-        _setDocumentation(suggestion, parameter.field?.documentationComment);
-        suggestion.element = convertElement(parameter);
-      }
-
-      suggestions.add(suggestion);
     }
+    return false;
   }
 
-  void _addSuggestions(Iterable<ParameterElement> parameters) {
-    if (parameters == null || parameters.isEmpty) {
-      return;
-    }
-    Iterable<ParameterElement> requiredParam =
-        parameters.where((ParameterElement p) => p.isRequiredPositional);
-    int requiredCount = requiredParam.length;
-    // TODO(jwren): _isAppendingToArgList can be split into two cases (with and
-    // without preceded), then _isAppendingToArgList,
-    // _isInsertingToArgListWithNoSynthetic and
-    // _isInsertingToArgListWithSynthetic could be formatted into a single
-    // method which returns some enum with 5+ cases.
-    if (_isEditingNamedArgLabel(request) || _isAppendingToArgList(request)) {
-      if (requiredCount == 0 || requiredCount < _argCount(request)) {
-        bool addTrailingComma =
-            !_isFollowedByAComma(request) && _isInFlutterCreation(request);
-        _addDefaultParamSuggestions(parameters, addTrailingComma);
-      }
-    } else if (_isInsertingToArgListWithNoSynthetic(request)) {
-      _addDefaultParamSuggestions(parameters, true);
-    } else if (_isInsertingToArgListWithSynthetic(request)) {
-      _addDefaultParamSuggestions(parameters, !_isFollowedByAComma(request));
-    } else {
-      final argument = request.target.containingNode;
-      if (argument is NamedExpression) {
-        final type = argument.staticParameterElement?.type;
-        final closureSuggestions =
-            buildClosureSuggestions(request, argument, type);
-        suggestions.addAll(closureSuggestions);
-      }
-    }
-  }
-
-  bool _isFollowedByAComma(DartCompletionRequest request) {
+  bool _isFollowedByAComma() {
     // new A(^); NO
     // new A(one: 1, ^); NO
     // new A(^ , one: 1); YES
@@ -315,15 +267,71 @@
         !token.next.isSynthetic;
   }
 
-  bool _isInFlutterCreation(DartCompletionRequest request) {
+  bool _isInFlutterCreation() {
     var flutter = Flutter.of(request.result);
-    AstNode containingNode = request?.target?.containingNode;
+    var containingNode = request.target?.containingNode;
     InstanceCreationExpression newExpr = containingNode != null
         ? flutter.identifyNewExpression(containingNode.parent)
         : null;
     return newExpr != null && flutter.isWidgetCreation(newExpr);
   }
 
+  /// Return `true` if the [request] is inside of a [NamedExpression] name.
+  bool _isInNamedExpression() {
+    var entity = request.target.entity;
+    if (entity is NamedExpression) {
+      Label name = entity.name;
+      return name.offset < request.offset && request.offset < name.end;
+    }
+    return false;
+  }
+
+  /// Return `true` if the completion target is in the middle or beginning of
+  /// the list of named arguments and is not preceded by a comma. This method
+  /// assumes that [_isAppendingToArgList] has been called and returned `false`.
+  bool _isInsertingToArgListWithNoSynthetic() {
+    if (argumentList != null) {
+      var entity = request.target.entity;
+      return entity is NamedExpression;
+    }
+    return false;
+  }
+
+  /// Return `true` if the completion target is in the middle or beginning of
+  /// the list of named parameters and is preceded by a comma. This method
+  /// assumes that both [_isAppendingToArgList] and
+  /// [_isInsertingToArgListWithNoSynthetic] have been called and both returned
+  /// `false`.
+  bool _isInsertingToArgListWithSynthetic() {
+    if (argumentList != null) {
+      var entity = request.target.entity;
+      if (entity is SimpleIdentifier) {
+        int argIndex = request.target.argIndex;
+        // if the next argument is a NamedExpression, then we are in the named
+        // parameter list, guard first against end of list
+        if (argumentList.arguments.length == argIndex + 1 ||
+            argumentList.arguments.getRange(argIndex + 1, argIndex + 2).first
+                is NamedExpression) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  /// Return a list containing the currently specified named arguments.
+  List<String> _namedArgs() {
+    List<String> namedArgs = <String>[];
+    if (argumentList != null) {
+      for (var arg in argumentList.arguments) {
+        if (arg is NamedExpression) {
+          namedArgs.add(arg.name.label.name);
+        }
+      }
+    }
+    return namedArgs;
+  }
+
   /// If the given [comment] is not `null`, fill the [suggestion] documentation
   /// fields.
   static void _setDocumentation(
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
index b2c1cea..6220845 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
@@ -11,27 +11,23 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 
-/// A contributor for calculating `completion.getSuggestions` request results
-/// for the import combinators show and hide.
+/// A contributor that produces suggestions based on the members of a library
+/// when the completion is in a show or hide combinator of an import or export.
 class CombinatorContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
       DartCompletionRequest request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    AstNode node = request.target.containingNode;
+    var node = request.target.containingNode;
     if (node is! Combinator) {
       return const <CompletionSuggestion>[];
     }
-
-    // Build list of suggestions
+    // Build the list of suggestions.
     var directive = node.thisOrAncestorOfType<NamespaceDirective>();
     if (directive is NamespaceDirective) {
-      LibraryElement library = directive.uriElement;
+      var library = directive.uriElement as LibraryElement;
       if (library != null) {
-        LibraryElementSuggestionBuilder builder =
-            LibraryElementSuggestionBuilder(request.libraryElement,
-                CompletionSuggestionKind.IDENTIFIER, false, false);
+        var builder = LibraryElementSuggestionBuilder(
+            request, CompletionSuggestionKind.IDENTIFIER, false, false);
         for (var element in library.exportNamespace.definedNames.values) {
           element.accept(builder);
         }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
index 710ece0..6b47032 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
@@ -10,35 +10,35 @@
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 
-/// A contributor for calculating invocation / access suggestions
-/// `completion.getSuggestions` request results.
+/// A contributor that produces suggestions for field formal parameters that are
+/// based on the fields declared directly by the enclosing class that are not
+/// already initialized. More concretely, this class produces suggestions for
+/// expressions of the form `this.^` in a constructor's parameter list.
 class FieldFormalContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
       DartCompletionRequest request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    AstNode node = request.target.containingNode;
+    var node = request.target.containingNode;
     if (node is! FieldFormalParameter) {
       return const <CompletionSuggestion>[];
     }
 
-    ConstructorDeclaration constructor = node.thisOrAncestorOfType();
+    var constructor = node.thisOrAncestorOfType<ConstructorDeclaration>();
     if (constructor == null) {
       return const <CompletionSuggestion>[];
     }
 
-    // Compute the list of fields already referenced in the constructor
-    List<String> referencedFields = <String>[];
-    for (FormalParameter param in constructor.parameters.parameters) {
+    // Compute the list of fields already referenced in the constructor.
+    var referencedFields = <String>[];
+    for (var param in constructor.parameters.parameters) {
       if (param is DefaultFormalParameter &&
           param.parameter is FieldFormalParameter) {
         param = (param as DefaultFormalParameter).parameter;
       }
       if (param is FieldFormalParameter) {
-        SimpleIdentifier fieldId = param.identifier;
+        var fieldId = param.identifier;
         if (fieldId != null && fieldId != request.target.entity) {
-          String fieldName = fieldId.name;
+          var fieldName = fieldId.name;
           if (fieldName != null && fieldName.isNotEmpty) {
             referencedFields.add(fieldName);
           }
@@ -46,24 +46,26 @@
       }
     }
 
-    ClassDeclaration class_ = constructor.thisOrAncestorOfType();
-    if (class_ == null) {
+    var enclosingClass = constructor.thisOrAncestorOfType<ClassDeclaration>();
+    if (enclosingClass == null) {
       return const <CompletionSuggestion>[];
     }
 
-    // Add suggestions for fields that are not already referenced
-    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
-    for (ClassMember member in class_.members) {
+    // Add suggestions for fields that are not already referenced.
+    var relevance = request.useNewRelevance
+        ? Relevance.fieldFormalParameter
+        : DART_RELEVANCE_LOCAL_FIELD;
+    var suggestions = <CompletionSuggestion>[];
+    for (var member in enclosingClass.members) {
       if (member is FieldDeclaration && !member.isStatic) {
-        for (VariableDeclaration varDecl in member.fields.variables) {
-          SimpleIdentifier fieldId = varDecl.name;
+        for (var variable in member.fields.variables) {
+          var fieldId = variable.name;
           if (fieldId != null) {
-            String fieldName = fieldId.name;
+            var fieldName = fieldId.name;
             if (fieldName != null && fieldName.isNotEmpty) {
               if (!referencedFields.contains(fieldName)) {
-                CompletionSuggestion suggestion = createSuggestion(
-                    fieldId.staticElement,
-                    relevance: DART_RELEVANCE_LOCAL_FIELD);
+                var suggestion = createSuggestion(fieldId.staticElement,
+                    relevance: relevance);
                 if (suggestion != null) {
                   suggestions.add(suggestion);
                 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index baff745..8f4714f 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -403,6 +403,16 @@
   }
 
   @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    // If the cursor is at the beginning of the declaration, include the
+    // compilation unit keywords.  See dartbug.com/41039.
+    if (entity == node.returnType || entity == node.name) {
+      _addSuggestion(Keyword.DYNAMIC);
+      _addSuggestion(Keyword.VOID);
+    }
+  }
+
+  @override
   void visitFunctionExpression(FunctionExpression node) {
     if (entity == node.body) {
       FunctionBody body = node.body;
@@ -511,8 +521,7 @@
           _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH);
         }
       }
-    }
-    if (entity == node.returnType || entity == node.name) {
+    } else if (entity == node.returnType || entity == node.name) {
       // If the cursor is at the beginning of the declaration, include the class
       // body keywords.  See dartbug.com/41039.
       _addClassBodyKeywords();
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
index 8e4f443..4d4940e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
@@ -13,22 +13,21 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol
     show ElementKind;
-import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
 import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart'
     show LocalDeclarationVisitor;
 
-/// A contributor for calculating label suggestions.
+/// A contributor that produces suggestions based on the labels that are in
+/// scope. More concretely, this class produces completions in `break` and
+/// `continue` statements.
 class LabelContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
       DartCompletionRequest request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    OpType optype = (request as DartCompletionRequestImpl).opType;
+    var optype = (request as DartCompletionRequestImpl).opType;
 
     // Collect suggestions from the specific child [AstNode] that contains
     // the completion offset and all of its parents recursively.
-    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    var suggestions = <CompletionSuggestion>[];
     if (!optype.isPrefixed) {
       if (optype.includeStatementLabelSuggestions ||
           optype.includeCaseLabelSuggestions) {
@@ -95,7 +94,7 @@
   @override
   void declaredLabel(Label label, bool isCaseLabel) {
     if (isCaseLabel ? includeCaseLabels : includeStatementLabels) {
-      CompletionSuggestion suggestion = _addSuggestion(label.label);
+      var suggestion = _addSuggestion(label.label);
       if (suggestion != null) {
         suggestion.element = createLocalElement(
             request.source, protocol.ElementKind.LABEL, label.label,
@@ -141,11 +140,11 @@
 
   CompletionSuggestion _addSuggestion(SimpleIdentifier id) {
     if (id != null) {
-      String completion = id.name;
+      var completion = id.name;
       if (completion != null && completion.isNotEmpty && completion != '_') {
-        CompletionSuggestion suggestion = CompletionSuggestion(
+        var suggestion = CompletionSuggestion(
             CompletionSuggestionKind.IDENTIFIER,
-            DART_RELEVANCE_DEFAULT,
+            request.useNewRelevance ? Relevance.label : DART_RELEVANCE_DEFAULT,
             completion,
             completion.length,
             0,
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
index b1b4e17..181c43c 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
@@ -12,26 +12,26 @@
 import '../../../protocol_server.dart'
     show CompletionSuggestion, CompletionSuggestionKind;
 
-/// A contributor for calculating prefixed import library member suggestions
-/// `completion.getSuggestions` request results.
+/// A contributor that produces suggestions based on the members of a library
+/// when the library was imported using a prefix. More concretely, this class
+/// produces suggestions for expressions of the form `p.^`, where `p` is a
+/// prefix.
 class LibraryMemberContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
       DartCompletionRequest request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    // Determine if the target looks like a library prefix
-    Expression targetId = request.dotTarget;
+    // Determine if the target looks like a library prefix.
+    var targetId = request.dotTarget;
     if (targetId is SimpleIdentifier && !request.target.isCascade) {
-      Element elem = targetId.staticElement;
+      var elem = targetId.staticElement;
       if (elem is PrefixElement && !elem.isSynthetic) {
-        LibraryElement containingLibrary = request.libraryElement;
-        // Gracefully degrade if the library or directives
-        // could not be determined (e.g. detached part file or source change)
+        var containingLibrary = request.libraryElement;
+        // Gracefully degrade if the library or directives could not be
+        // determined (e.g. detached part file or source change).
         if (containingLibrary != null) {
-          List<ImportElement> imports = containingLibrary.imports;
+          var imports = containingLibrary.imports;
           if (imports != null) {
-            return _buildSuggestions(request, elem, containingLibrary, imports);
+            return _buildSuggestions(request, elem, imports);
           }
         }
       }
@@ -39,37 +39,35 @@
     return const <CompletionSuggestion>[];
   }
 
-  List<CompletionSuggestion> _buildSuggestions(
-      DartCompletionRequest request,
-      PrefixElement elem,
-      LibraryElement containingLibrary,
-      List<ImportElement> imports) {
-    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
-    for (ImportElement importElem in imports) {
+  List<CompletionSuggestion> _buildSuggestions(DartCompletionRequest request,
+      PrefixElement elem, List<ImportElement> imports) {
+    var parent = request.target.containingNode.parent;
+    var isConstructor = parent.parent is ConstructorName;
+    var typesOnly = parent is TypeName;
+    var instCreation = typesOnly && isConstructor;
+    var builder = LibraryElementSuggestionBuilder(
+        request, CompletionSuggestionKind.INVOCATION, typesOnly, instCreation);
+    for (var importElem in imports) {
       if (importElem.prefix?.name == elem.name) {
-        LibraryElement library = importElem.importedLibrary;
+        var library = importElem.importedLibrary;
         if (library != null) {
-          // Suggest elements from the imported library
-          AstNode parent = request.target.containingNode.parent;
-          bool isConstructor = parent.parent is ConstructorName;
-          bool typesOnly = parent is TypeName;
-          bool instCreation = typesOnly && isConstructor;
-          LibraryElementSuggestionBuilder builder =
-              LibraryElementSuggestionBuilder(containingLibrary,
-                  CompletionSuggestionKind.INVOCATION, typesOnly, instCreation);
+          // Suggest elements from the imported library.
           for (var element in importElem.namespace.definedNames.values) {
             element.accept(builder);
           }
-          suggestions.addAll(builder.suggestions);
-
-          // If the import is 'deferred' then suggest 'loadLibrary'
+          // If the import is 'deferred' then suggest 'loadLibrary'.
           if (importElem.isDeferred) {
-            FunctionElement loadLibFunct = library.loadLibraryFunction;
-            suggestions.add(createSuggestion(loadLibFunct));
+            var function = library.loadLibraryFunction;
+            var useNewRelevance = request.useNewRelevance;
+            var relevance = useNewRelevance
+                ? Relevance.loadLibrary
+                : DART_RELEVANCE_DEFAULT;
+            builder.suggestions.add(createSuggestion(function,
+                relevance: relevance, useNewRelevance: useNewRelevance));
           }
         }
       }
     }
-    return suggestions;
+    return builder.suggestions;
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
index a6ce544..8ecdc2d 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
@@ -11,32 +11,39 @@
 import '../../../protocol_server.dart'
     show CompletionSuggestion, CompletionSuggestionKind;
 
-/// A contributor for calculating prefixed import library member suggestions
-/// `completion.getSuggestions` request results.
+/// A contributor that produces suggestions based on the prefixes defined on
+/// import directives.
 class LibraryPrefixContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
       DartCompletionRequest request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (!request.includeIdentifiers) {
       return const <CompletionSuggestion>[];
     }
 
-    List<ImportElement> imports = request.libraryElement.imports;
+    var imports = request.libraryElement.imports;
     if (imports == null) {
       return const <CompletionSuggestion>[];
     }
 
-    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    // TODO(brianwilkerson) The code below will result in duplication if two or
+    //  more imports use the same prefix. Might not be worth fixing. The one
+    //  potential complication is if the library is displayed with the prefix,
+    //  in which case not having one per library could be confusing.
+    var useNewRelevance = request.useNewRelevance;
+    var suggestions = <CompletionSuggestion>[];
     for (ImportElement element in imports) {
-      String completion = element.prefix?.name;
+      var completion = element.prefix?.name;
       if (completion != null && completion.isNotEmpty) {
-        LibraryElement libElem = element.importedLibrary;
-        if (libElem != null) {
-          CompletionSuggestion suggestion = createSuggestion(libElem,
+        var libraryElement = element.importedLibrary;
+        if (libraryElement != null) {
+          var relevance =
+              useNewRelevance ? Relevance.prefix : DART_RELEVANCE_DEFAULT;
+          var suggestion = createSuggestion(libraryElement,
               completion: completion,
-              kind: CompletionSuggestionKind.IDENTIFIER);
+              kind: CompletionSuggestionKind.IDENTIFIER,
+              relevance: relevance,
+              useNewRelevance: useNewRelevance);
           if (suggestion != null) {
             suggestions.add(suggestion);
           }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
index 6aafcdd..5a0c30d 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
@@ -8,32 +8,32 @@
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
 
-/// A contributor for calculating named constructor suggestions
-/// such as suggesting `bar` in `new Foo.bar()`.
+/// A contributor that produces suggestions based on the named constructors
+/// defined on a given class. More concretely, this class produces suggestions
+/// for expressions of the form `C.^` or `C<E>.^`, where `C` is the name of a
+/// class.
 class NamedConstructorContributor extends DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
       DartCompletionRequest request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    AstNode node = request.target.containingNode;
-    LibraryElement libElem = request.libraryElement;
-    if (libElem == null) {
+    var node = request.target.containingNode;
+    var libraryElement = request.libraryElement;
+    if (libraryElement == null) {
       return const <CompletionSuggestion>[];
     }
 
     // Build the list of suggestions
     if (node is ConstructorName) {
-      TypeName typeName = node.type;
+      var typeName = node.type;
       if (typeName != null) {
-        DartType type = typeName.type;
+        var type = typeName.type;
         if (type != null) {
-          Element classElem = type.element;
-          if (classElem is ClassElement) {
-            return _buildSuggestions(libElem, classElem);
+          var element = type.element;
+          if (element is ClassElement) {
+            return _buildSuggestions(
+                libraryElement, element, request.useNewRelevance);
           }
         }
       }
@@ -42,16 +42,22 @@
   }
 
   List<CompletionSuggestion> _buildSuggestions(
-      LibraryElement libElem, ClassElement classElem) {
-    bool isLocalClassDecl = classElem.library == libElem;
-    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
-    for (ConstructorElement elem in classElem.constructors) {
-      if (isLocalClassDecl || !elem.isPrivate) {
-        String name = elem.name;
+      LibraryElement libElem, ClassElement classElem, bool useNewRelevance) {
+    var isLocalClassDecl = classElem.library == libElem;
+    var suggestions = <CompletionSuggestion>[];
+    for (var constructor in classElem.constructors) {
+      if (isLocalClassDecl || !constructor.isPrivate) {
+        var name = constructor.name;
         if (name != null) {
-          CompletionSuggestion s = createSuggestion(elem, completion: name);
-          if (s != null) {
-            suggestions.add(s);
+          var relevance = useNewRelevance
+              ? Relevance.namedConstructor
+              : DART_RELEVANCE_DEFAULT;
+          var suggestion = createSuggestion(constructor,
+              completion: name,
+              relevance: relevance,
+              useNewRelevance: useNewRelevance);
+          if (suggestion != null) {
+            suggestions.add(suggestion);
           }
         }
       }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index cda9b55..c270a1a 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -168,36 +168,56 @@
   }
 }
 
-/// This class creates suggestions based upon top-level elements.
+/// This class creates suggestions based on top-level elements.
 class LibraryElementSuggestionBuilder extends SimpleElementVisitor<void>
     with ElementSuggestionBuilder {
-  @override
-  final LibraryElement containingLibrary;
+  /// The completion request for which suggestions are being built.
+  final DartCompletionRequest request;
+
   @override
   final CompletionSuggestionKind kind;
+
   final bool typesOnly;
+
   final bool instCreation;
 
+  /// Return `true` if the new relevance scores should be produced.
+  final bool useNewRelevance;
+
   LibraryElementSuggestionBuilder(
-      this.containingLibrary, this.kind, this.typesOnly, this.instCreation);
+      this.request, this.kind, this.typesOnly, this.instCreation)
+      : useNewRelevance = request.useNewRelevance;
+
+  @override
+  LibraryElement get containingLibrary => request.libraryElement;
 
   @override
   void visitClassElement(ClassElement element) {
     if (instCreation) {
       element.visitChildren(this);
     } else {
-      addSuggestion(element);
+      // TODO(brianwilkerson) Determine whether this should be based on features
+      //  (such as the kind of the element) or a constant.
+      var relevance = useNewRelevance ? 750 : DART_RELEVANCE_DEFAULT;
+      addSuggestion(element,
+          relevance: relevance, useNewRelevance: useNewRelevance);
     }
   }
 
   @override
   void visitConstructorElement(ConstructorElement element) {
     if (instCreation) {
-      ClassElement classElem = element.enclosingElement;
+      var classElem = element.enclosingElement;
       if (classElem != null) {
-        String prefix = classElem.name;
+        var prefix = classElem.name;
         if (prefix != null && prefix.isNotEmpty) {
-          addSuggestion(element, prefix: prefix);
+          // TODO(brianwilkerson) Determine whether this should be based on features
+          //  (such as the kind of the element) or a constant.
+          var relevance = useNewRelevance ? 750 : DART_RELEVANCE_DEFAULT;
+          addSuggestion(element,
+              prefix: prefix,
+              relevance: relevance,
+              useNewRelevance: useNewRelevance);
         }
       }
     }
@@ -206,35 +226,59 @@
   @override
   void visitExtensionElement(ExtensionElement element) {
     if (!instCreation) {
-      addSuggestion(element);
+      // TODO(brianwilkerson) Determine whether this should be based on features
+      //  (such as the kind of the element) or a constant.
+      var relevance = useNewRelevance ? 750 : DART_RELEVANCE_DEFAULT;
+      addSuggestion(element,
+          relevance: relevance, useNewRelevance: useNewRelevance);
     }
   }
 
   @override
   void visitFunctionElement(FunctionElement element) {
     if (!typesOnly) {
-      int relevance = element.library == containingLibrary
-          ? DART_RELEVANCE_LOCAL_FUNCTION
-          : DART_RELEVANCE_DEFAULT;
-      addSuggestion(element, relevance: relevance);
+      int relevance;
+      if (useNewRelevance) {
+        // TODO(brianwilkerson) Determine whether this should be based on
+        //  features (such as the kind of the element) or a constant.
+        relevance = element.library == containingLibrary ? 800 : 750;
+      } else {
+        relevance = element.library == containingLibrary
+            ? DART_RELEVANCE_LOCAL_FUNCTION
+            : DART_RELEVANCE_DEFAULT;
+      }
+      addSuggestion(element,
+          relevance: relevance, useNewRelevance: useNewRelevance);
     }
   }
 
   @override
   void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
     if (!instCreation) {
-      addSuggestion(element);
+      // TODO(brianwilkerson) Determine whether this should be based on features
+      //  (such as the kind of the element) or a constant.
+      var relevance = useNewRelevance ? 750 : DART_RELEVANCE_DEFAULT;
+      addSuggestion(element,
+          relevance: relevance, useNewRelevance: useNewRelevance);
     }
   }
 
   @override
   void visitPropertyAccessorElement(PropertyAccessorElement element) {
     if (!typesOnly) {
-      PropertyInducingElement variable = element.variable;
-      int relevance = variable.library == containingLibrary
-          ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
-          : DART_RELEVANCE_DEFAULT;
-      addSuggestion(variable, relevance: relevance);
+      var variable = element.variable;
+      int relevance;
+      if (useNewRelevance) {
+        // TODO(brianwilkerson) Determine whether this should be based on
+        //  features (such as the kind of the element) or a constant.
+        relevance = variable.library == containingLibrary ? 800 : 750;
+      } else {
+        relevance = variable.library == containingLibrary
+            ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
+            : DART_RELEVANCE_DEFAULT;
+      }
+      addSuggestion(variable,
+          relevance: relevance, useNewRelevance: useNewRelevance);
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index ff48c48..c30a0aa 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -16,6 +16,7 @@
     show LspAnalysisServer;
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analysis_server/src/server/http_server.dart';
+import 'package:analysis_server/src/server/sdk_configuration.dart';
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_ranking.dart';
 import 'package:analysis_server/src/socket_server.dart';
@@ -1418,6 +1419,19 @@
 
     buf.writeln('</div>');
 
+    // SDK configuration overrides.
+    SdkConfiguration sdkConfig = server.options.configurationOverrides;
+    if (sdkConfig?.hasAnyOverrides == true) {
+      buf.writeln('<div class="columns">');
+
+      buf.writeln('<div class="column one-half">');
+      h3('Configuration Overrides');
+      buf.writeln('<pre><code>${sdkConfig.displayString}</code></pre><br>');
+      buf.writeln('</div>');
+
+      buf.writeln('</div>');
+    }
+
     List<String> lines = site.lastPrintedLines;
     if (lines.isNotEmpty) {
       h3('Debug output');
diff --git a/pkg/analysis_server/test/integration/linter/lint_names_test.dart b/pkg/analysis_server/test/integration/linter/lint_names_test.dart
index ee12579..8548ffe 100644
--- a/pkg/analysis_server/test/integration/linter/lint_names_test.dart
+++ b/pkg/analysis_server/test/integration/linter/lint_names_test.dart
@@ -76,7 +76,6 @@
     var parser = Parser(
       stringSource,
       errorListener,
-      languageVersion: scanner.languageVersion,
       featureSet: featureSet,
     );
     var cu = parser.parseCompilationUnit(startToken);
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index 9247aa3..e1aa7f1 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -338,6 +338,23 @@
     );
   }
 
+  Future<void> test_ArgumentList_closureParam() async {
+    addTestSource(r'''
+void f({void Function(int a, {int b, int c}) closure}) {}
+
+void main() {
+  f(closure: ^);
+}
+''');
+    await computeSuggestions();
+
+    assertSuggest(
+      '(a, {b, c}) => ,',
+      relevance: DART_RELEVANCE_HIGH,
+      selectionOffset: 15,
+    );
+  }
+
   Future<void> test_ArgumentList_closureParameterOptionalNamed() async {
     addTestSource(r'''
 void f({void Function(int a, {int b, int c}) closure}) {}
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index 1827123..39f4986 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -1283,6 +1283,18 @@
         pseudoKeywords: ['await', 'yield', 'yield*']);
   }
 
+  Future<void> test_function_body_inUnit_return_with_header() async {
+    addTestSource('/// comment\n ^ foo() {}}');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.DYNAMIC, Keyword.VOID]);
+  }
+
+  Future<void> test_function_body_inUnit_return_with_header_prefix() async {
+    addTestSource('/// comment\n d^ foo() {}}');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.DYNAMIC, Keyword.VOID]);
+  }
+
   Future<void> test_function_body_inUnit_sync_star() async {
     addTestSource('main() sync* {n^}');
     await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
index 3e6ea08..eb674bd2 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
@@ -12,7 +12,7 @@
 
 void main() {
   defineReflectiveSuite(() {
-//    defineReflectiveTests(LibraryMemberContributorTest);
+    defineReflectiveTests(LibraryMemberContributorTest);
     defineReflectiveTests(LibraryMemberContributorWithExtensionMethodsTest);
   });
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/arglist_parameter_relevance_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/arglist_parameter_relevance_test.dart
deleted file mode 100644
index 9b11de9..0000000
--- a/pkg/analysis_server/test/services/completion/dart/relevance/arglist_parameter_relevance_test.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer_plugin/utilities/completion/relevance.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../completion_contributor_util.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(ArglistParameterRelevanceTest);
-  });
-}
-
-@reflectiveTest
-class ArglistParameterRelevanceTest extends DartCompletionManagerTest {
-  Future<void> test_closureParam() async {
-    addTestSource(r'''
-void f({void Function(int a, {int b, int c}) closure}) {}
-
-void main() {
-  f(closure: ^);
-}
-''');
-    await computeSuggestions();
-
-    assertSuggest(
-      '(a, {b, c}) => ,',
-      // todo (pq): replace w/ a test of relative relevance
-      relevance: DART_RELEVANCE_HIGH,
-      selectionOffset: 15,
-    );
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart b/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart
index 79a5bbf..052307d 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/completion_relevance.dart
@@ -5,15 +5,16 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../../client/completion_driver_test.dart';
 
-@reflectiveTest
 class CompletionRelevanceTest extends AbstractCompletionDriverTest {
+  List<String> get enabledExperiments => [];
+
   @override
-  AnalysisServerOptions get serverOptions =>
-      AnalysisServerOptions()..useNewRelevance = true;
+  AnalysisServerOptions get serverOptions => AnalysisServerOptions()
+    ..enabledExperiments = enabledExperiments
+    ..useNewRelevance = true;
 
   @override
   bool get supportsAvailableSuggestions => true;
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_relevance_test.dart b/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_relevance_test.dart
new file mode 100644
index 0000000..21fdd4d
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/named_argument_relevance_test.dart
@@ -0,0 +1,65 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/test_utilities/package_mixin.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'completion_relevance.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(NamedArgumentRelevanceTest);
+    defineReflectiveTests(NamedArgumentRelevanceWithNnbdTest);
+  });
+}
+
+@reflectiveTest
+class NamedArgumentRelevanceTest extends CompletionRelevanceTest
+    with PackageMixin {
+  @override
+  Map<String, List<Folder>> packageMap = {};
+
+  @override
+  void setUp() {
+    super.setUp();
+    newFile('$projectPath/.packages', content: '''
+meta:${toUri('/.pub-cache/meta/lib')}
+project:${toUri('$projectPath/lib')}
+''');
+  }
+
+  Future<void> test_requiredAnnotation() async {
+    addMetaPackage();
+    await addTestFile('''
+import 'package:meta/meta.dart';
+
+void f({int a, @required int b}) {}
+
+void g() => f(^);
+''');
+    assertOrder([
+      suggestionWith(completion: 'b: '),
+      suggestionWith(completion: 'a: '),
+    ]);
+  }
+}
+
+@reflectiveTest
+class NamedArgumentRelevanceWithNnbdTest extends NamedArgumentRelevanceTest {
+  @override
+  List<String> get enabledExperiments => ['non-nullable'];
+
+  Future<void> test_required() async {
+    await addTestFile('''
+void f({int a = 0, required int b}) {}
+
+void g() => f(^);
+''');
+    assertOrder([
+      suggestionWith(completion: 'b: '),
+      suggestionWith(completion: 'a: '),
+    ]);
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/relevance/test_all.dart b/pkg/analysis_server/test/services/completion/dart/relevance/test_all.dart
index c0235e1..9a09a5b 100644
--- a/pkg/analysis_server/test/services/completion/dart/relevance/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/relevance/test_all.dart
@@ -4,18 +4,18 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'arglist_parameter_relevance_test.dart' as arglist_parameters;
 import 'bool_assignment_relevance_test.dart' as bool_assignments;
 import 'deprecated_member_relevance_test.dart' as deprecated_members;
 import 'instance_member_relevance_test.dart' as instance_member_relevance;
+import 'named_argument_relevance_test.dart' as named_argument_relevance;
 import 'static_member_relevance_test.dart' as static_member_relevance;
 
 void main() {
   defineReflectiveSuite(() {
-    arglist_parameters.main();
     bool_assignments.main();
     deprecated_members.main();
     instance_member_relevance.main();
+    named_argument_relevance.main();
     static_member_relevance.main();
   });
 }
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
index af7a168..0a5ec52 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
@@ -290,8 +290,8 @@
     }
   }
 
-  void assertTraceEntry(
-      UnitInfo unit, TraceEntryInfo entryInfo, String function, int offset) {
+  void assertTraceEntry(UnitInfo unit, TraceEntryInfo entryInfo,
+      String function, int offset, Object descriptionMatcher) {
     assert(offset >= 0);
     var lineInfo = LineInfo.fromContent(unit.content);
     var expectedLocation = lineInfo.getLocation(offset);
@@ -299,6 +299,7 @@
     expect(entryInfo.target.line, expectedLocation.lineNumber);
     expect(entryInfo.target.offset, expectedLocation.columnNumber);
     expect(entryInfo.function, function);
+    expect(entryInfo.description, descriptionMatcher);
   }
 
   Future<void> test_asExpression() async {
@@ -1417,13 +1418,14 @@
     assertDetail(detail: regions[1].details[0], offset: 12, length: 3);
 
     expect(regions[0].traces, hasLength(1));
-    var trace = regions[0].traces.single;
+    var trace = regions[0].traces.first;
     expect(trace.description, 'Nullability reason');
     var entries = trace.entries;
-    expect(entries, hasLength(1));
+    expect(entries, hasLength(2));
     // Entry 0 is the nullability of the type of A.m.
     // TODO(srawlins): "A" is probably incorrect here. Should be "A.m".
-    assertTraceEntry(unit, entries[0], 'A', unit.content.indexOf('int?'));
+    assertTraceEntry(unit, entries[0], 'A', unit.content.indexOf('int?'),
+        contains('explicit type'));
   }
 
   Future<void> test_parameter_named_omittedInCall() async {
@@ -1785,11 +1787,19 @@
     var trace = region.traces.single;
     expect(trace.description, 'Non-nullability reason');
     var entries = trace.entries;
-    expect(entries, hasLength(2));
+    expect(entries, hasLength(3));
     // Entry 0 is the nullability of f's argument
-    assertTraceEntry(unit, entries[0], 'f', unit.content.indexOf('int'));
+    assertTraceEntry(unit, entries[0], 'f', unit.content.indexOf('int'),
+        contains('parameter 0 of f'));
     // Entry 1 is the edge from f's argument to never, due to the `/*!*/` hint.
-    assertTraceEntry(unit, entries[1], 'f', unit.content.indexOf('int'));
+    assertTraceEntry(unit, entries[1], 'f', unit.content.indexOf('int'),
+        'explicitly hinted to be non-nullable');
+    // Entry 2 is the "never" node.
+    // TODO(paulberry): this node provides no additional useful information and
+    // shouldn't be included in the trace.
+    expect(entries[2].description, 'never');
+    expect(entries[2].function, null);
+    expect(entries[2].target, null);
   }
 
   Future<void> test_trace_nullableType() async {
@@ -1818,20 +1828,28 @@
     var trace = region.traces.single;
     expect(trace.description, 'Nullability reason');
     var entries = trace.entries;
-    expect(entries, hasLength(5));
+    expect(entries, hasLength(6));
     // Entry 0 is the nullability of f's argument
-    assertTraceEntry(
-        unit, entries[0], 'f', unit.content.indexOf('int? i) {} // f'));
+    assertTraceEntry(unit, entries[0], 'f',
+        unit.content.indexOf('int? i) {} // f'), contains('parameter 0 of f'));
     // Entry 1 is the edge from g's argument to f's argument, due to g's call to
     // f.
-    assertTraceEntry(unit, entries[1], 'g', unit.content.indexOf('i);'));
-    // Entry 2 is the nullability of g's argument
     assertTraceEntry(
-        unit, entries[2], 'g', unit.content.indexOf('int? i) { // g'));
+        unit, entries[1], 'g', unit.content.indexOf('i);'), 'data flow');
+    // Entry 2 is the nullability of g's argument
+    assertTraceEntry(unit, entries[2], 'g',
+        unit.content.indexOf('int? i) { // g'), contains('parameter 0 of g'));
     // Entry 3 is the edge from null to g's argument, due to h's call to g.
-    assertTraceEntry(unit, entries[3], 'h', unit.content.indexOf('null'));
+    assertTraceEntry(
+        unit, entries[3], 'h', unit.content.indexOf('null'), 'data flow');
     // Entry 4 is the nullability of the null literal.
-    assertTraceEntry(unit, entries[4], 'h', unit.content.indexOf('null'));
+    assertTraceEntry(unit, entries[4], 'h', unit.content.indexOf('null'),
+        contains('null literal'));
+    // Entry 5 is the edge from always to null.
+    // TODO(paulberry): this edge provides no additional useful information and
+    // shouldn't be included in the trace.
+    assertTraceEntry(unit, entries[5], 'h', unit.content.indexOf('null'),
+        'literal expression');
   }
 
   Future<void> test_trace_nullCheck() async {
@@ -1845,11 +1863,16 @@
     var trace = region.traces.single;
     expect(trace.description, 'Nullability reason');
     var entries = trace.entries;
-    expect(entries, hasLength(1));
+    expect(entries, hasLength(2));
     // Entry 0 is the nullability of the type of i.
     // TODO(paulberry): -1 is a bug.
-    assertTraceEntry(unit, entries[0], 'f', unit.content.indexOf('int?') - 1);
+    assertTraceEntry(unit, entries[0], 'f', unit.content.indexOf('int?') - 1,
+        contains('parameter 0 of f'));
     // Entry 1 is the edge from always to the type of i.
+    // TODO(paulberry): this edge provides no additional useful information and
+    // shouldn't be included in the trace.
+    assertTraceEntry(unit, entries[1], 'f', unit.content.indexOf('int?') - 1,
+        'explicitly hinted to be nullable');
   }
 
   Future<void> test_trace_nullCheck_notNullableReason() async {
@@ -1883,19 +1906,26 @@
     var trace = region.traces[1];
     expect(trace.description, 'Non-nullability reason');
     var entries = trace.entries;
-    expect(entries, hasLength(4));
+    expect(entries, hasLength(5));
     // Entry 0 is the nullability of g's argument
-    assertTraceEntry(
-        unit, entries[0], 'g', unit.content.indexOf('int  i) { // g'));
+    assertTraceEntry(unit, entries[0], 'g',
+        unit.content.indexOf('int  i) { // g'), contains('parameter 0 of g'));
     // Entry 1 is the edge from g's argument to f's argument, due to g's call to
     // f.
-    assertTraceEntry(
-        unit, entries[1], 'g', unit.content.indexOf('i); // call f'));
+    assertTraceEntry(unit, entries[1], 'g',
+        unit.content.indexOf('i); // call f'), 'data flow');
     // Entry 2 is the nullability of f's argument
-    assertTraceEntry(
-        unit, entries[2], 'f', unit.content.indexOf('int  i) { // f'));
+    assertTraceEntry(unit, entries[2], 'f',
+        unit.content.indexOf('int  i) { // f'), contains('parameter 0 of f'));
     // Entry 3 is the edge f's argument to never, due to the assert.
-    assertTraceEntry(unit, entries[3], 'f', unit.content.indexOf('assert'));
+    assertTraceEntry(unit, entries[3], 'f', unit.content.indexOf('assert'),
+        'value asserted to be non-null');
+    // Entry 4 is the "never" node.
+    // TODO(paulberry): this node provides no additional useful information and
+    // shouldn't be included in the trace.
+    expect(entries[4].description, 'never');
+    expect(entries[4].function, null);
+    expect(entries[4].target, null);
   }
 
   Future<void> test_trace_substitutionNode() async {
diff --git a/pkg/analysis_server/test/src/server/sdk_configuration_test.dart b/pkg/analysis_server/test/src/server/sdk_configuration_test.dart
new file mode 100644
index 0000000..043c90a
--- /dev/null
+++ b/pkg/analysis_server/test/src/server/sdk_configuration_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:analysis_server/src/server/sdk_configuration.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+
+void main() {
+  group('SdkConfiguration', () {
+    Directory tempDir;
+
+    tearDown(() {
+      tempDir?.deleteSync(recursive: true);
+    });
+
+    test('readFromSdk', () {
+      expect(SdkConfiguration.readFromSdk(), isNotNull);
+    });
+
+    test("custom settings file doesn't exist", () {
+      tempDir = Directory.systemTemp.createTempSync('SdkConfiguration');
+      File file = File(path.join(tempDir.path, 'config.json'));
+
+      expect(() {
+        SdkConfiguration.readFromFile(file);
+      }, throwsA(TypeMatcher<String>()));
+    });
+
+    test('is not configured', () {
+      tempDir = Directory.systemTemp.createTempSync('SdkConfiguration');
+      File file = File(path.join(tempDir.path, 'config.json'));
+      file.writeAsStringSync('''
+{}
+''');
+
+      SdkConfiguration config = SdkConfiguration.readFromFile(file);
+
+      expect(config.hasAnyOverrides, isFalse);
+      expect(config.analyticsId, isNull);
+      expect(config.analyticsForceEnabled, isNull);
+      expect(config.crashReportingId, isNull);
+      expect(config.crashReportingForceEnabled, isNull);
+      expect(config.mlModelPath, isNull);
+    });
+
+    test('is configured', () {
+      tempDir = Directory.systemTemp.createTempSync('SdkConfiguration');
+      File file = File(path.join(tempDir.path, 'config.json'));
+      file.writeAsStringSync('''
+{
+  "server.analytics.id": "aaaa-1234",
+  "server.analytics.forceEnabled": true,
+
+  "server.crash.reporting.id": "Test_crash_id",
+  "server.crash.reporting.forceEnabled": true,
+
+  "server.ml.model.path": "/foo/bar/baz.ml"
+}
+''');
+
+      SdkConfiguration config = SdkConfiguration.readFromFile(file);
+
+      expect(config.hasAnyOverrides, isTrue);
+      expect(config.analyticsId, 'aaaa-1234');
+      expect(config.analyticsForceEnabled, isTrue);
+      expect(config.crashReportingId, 'Test_crash_id');
+      expect(config.crashReportingForceEnabled, isTrue);
+      expect(config.mlModelPath, '/foo/bar/baz.ml');
+    });
+  });
+}
diff --git a/pkg/analysis_server/test/src/server/test_all.dart b/pkg/analysis_server/test/src/server/test_all.dart
new file mode 100644
index 0000000..cf5da10
--- /dev/null
+++ b/pkg/analysis_server/test/src/server/test_all.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'sdk_configuration_test.dart' as sdk_configuration;
+
+void main() {
+  sdk_configuration.main();
+}
diff --git a/pkg/analysis_server/test/src/test_all.dart b/pkg/analysis_server/test/src/test_all.dart
index 85107e0..2f1638e 100644
--- a/pkg/analysis_server/test/src/test_all.dart
+++ b/pkg/analysis_server/test/src/test_all.dart
@@ -11,6 +11,7 @@
 import 'flutter/test_all.dart' as flutter;
 import 'lsp/test_all.dart' as lsp;
 import 'plugin/test_all.dart' as plugin;
+import 'server/test_all.dart' as server;
 import 'services/test_all.dart' as services;
 import 'utilities/test_all.dart' as utilities;
 
@@ -23,6 +24,7 @@
     flutter.main();
     lsp.main();
     plugin.main();
+    server.main();
     services.main();
     utilities.main();
   }, name: 'src');
diff --git a/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart b/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
index 92f4e26..6c1f9e5 100644
--- a/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
@@ -1882,6 +1882,10 @@
     if (parameterType == null || parameterType.isDynamic) {
       return;
     }
+    if (parameterType is FunctionType) {
+      data.recordTypeMatch('function typed parameter',
+          argument is FunctionExpression ? 'closure' : 'non-closure');
+    }
     var context = _argumentListContext(argument.parent);
     var argumentType = argument.staticType;
     if (argumentType != null) {
diff --git a/pkg/analysis_server/tool/nnbd_migration/generate_resources.dart b/pkg/analysis_server/tool/nnbd_migration/generate_resources.dart
index 064b050..cee1414 100644
--- a/pkg/analysis_server/tool/nnbd_migration/generate_resources.dart
+++ b/pkg/analysis_server/tool/nnbd_migration/generate_resources.dart
@@ -10,13 +10,17 @@
 import 'dart:io';
 import 'dart:math' as math;
 
+import 'package:args/args.dart';
 import 'package:crypto/crypto.dart';
 import 'package:path/path.dart' as path;
 
 void main(List<String> args) async {
-  if (args.isEmpty) {
-    // this is valid
-  } else if (args.length != 1 || args.first != '--verify') {
+  var argParser = ArgParser()
+    ..addFlag('verify', negatable: false)
+    ..addFlag('dev', negatable: false)
+    ..addFlag('help', negatable: false);
+  var argResults = argParser.parse(args);
+  if (argResults['help'] == true) {
     fail('''
 usage: dart pkg/analysis_server/tool/nnbd_migration/generate_resources.dart [--verify]
 
@@ -34,12 +38,13 @@
     fail('Please run this tool from the root of the sdk repo.');
   }
 
-  bool verify = args.isNotEmpty && args.first == '--verify';
+  bool verify = argResults['verify'];
+  bool dev = argResults['dev'];
 
   if (verify) {
     verifyResourcesGDartGenerated();
   } else {
-    await compileWebFrontEnd();
+    await compileWebFrontEnd(devMode: dev);
 
     print('');
 
@@ -81,15 +86,13 @@
   return lines.join('\n');
 }
 
-void compileWebFrontEnd() async {
+void compileWebFrontEnd({bool devMode = false}) async {
   String sdkBinDir = path.dirname(Platform.resolvedExecutable);
   String dart2jsPath = path.join(sdkBinDir, 'dart2js');
 
-  const minified = true;
-
   // dart2js -m -o output source
   Process process = await Process.start(dart2jsPath, [
-    if (minified) '-m',
+    devMode ? '-O1' : '-m',
     '--no-frequency-based-minification',
     '-o',
     javascriptOutput.path,
diff --git a/pkg/analysis_server_client/test/server_test.dart b/pkg/analysis_server_client/test/server_test.dart
index b6fe443..308a4c8 100644
--- a/pkg/analysis_server_client/test/server_test.dart
+++ b/pkg/analysis_server_client/test/server_test.dart
@@ -97,7 +97,7 @@
       final mockout = StreamController<List<int>>();
       process.stdout = mockout.stream;
       process.stderr = _noMessage();
-      process.exitCode = Future.delayed(const Duration(seconds: 1));
+      process.exitCode = Future.delayed(const Duration(seconds: 1), () => 0);
 
       server.listenToOutput();
       await server.stop(timeLimit: const Duration(milliseconds: 10));
diff --git a/pkg/analyzer/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
index 61b5ffb..ddb8fae 100644
--- a/pkg/analyzer/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -127,7 +127,6 @@
   var parser = Parser(
     source,
     errorCollector,
-    languageVersion: scanner.languageVersion,
     featureSet: featureSet,
   );
   var unit = parser.parseDirectives(token);
@@ -155,7 +154,6 @@
   var parser = Parser(
     source,
     errorCollector,
-    languageVersion: scanner.languageVersion,
     featureSet: featureSet,
   )..parseFunctionBodies = parseFunctionBodies;
   var unit = parser.parseCompilationUnit(token)
diff --git a/pkg/analyzer/lib/dart/analysis/utilities.dart b/pkg/analyzer/lib/dart/analysis/utilities.dart
index 8164d29..c2aec9e 100644
--- a/pkg/analyzer/lib/dart/analysis/utilities.dart
+++ b/pkg/analyzer/lib/dart/analysis/utilities.dart
@@ -121,7 +121,6 @@
   var parser = Parser(
     source,
     errorCollector,
-    languageVersion: scanner.languageVersion,
     featureSet: scanner.featureSet,
   );
   var unit = parser.parseCompilationUnit(token);
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 3c9248b..83e9d9c 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -1237,9 +1237,12 @@
   /// resynthesized from a summary.
   FeatureSet get featureSet;
 
+  @Deprecated("Use languageVersionToken")
+  LanguageVersion get languageVersion;
+
   /// The language version override specified for this compilation unit using a
   /// token like '// @dart = 2.7', or `null` if no override is specified.
-  LanguageVersion get languageVersion;
+  LanguageVersionToken get languageVersionToken;
 
   /// Return the line information for this compilation unit.
   LineInfo get lineInfo;
diff --git a/pkg/analyzer/lib/dart/ast/ast_factory.dart b/pkg/analyzer/lib/dart/ast/ast_factory.dart
index 7d2ea31..d324d7a 100644
--- a/pkg/analyzer/lib/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/dart/ast/ast_factory.dart
@@ -5,7 +5,6 @@
 import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/language_version.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:meta/meta.dart';
 
@@ -166,8 +165,7 @@
       List<Directive> directives,
       List<CompilationUnitMember> declarations,
       @required Token endToken,
-      @required FeatureSet featureSet,
-      LanguageVersion languageVersion});
+      @required FeatureSet featureSet});
 
   /// Returns a newly created conditional expression.
   ConditionalExpression conditionalExpression(
diff --git a/pkg/analyzer/lib/dart/ast/language_version.dart b/pkg/analyzer/lib/dart/ast/language_version.dart
index 14932f7..07cbb0f 100644
--- a/pkg/analyzer/lib/dart/ast/language_version.dart
+++ b/pkg/analyzer/lib/dart/ast/language_version.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 /// The language version override specified for a compilation unit.
+@Deprecated("Use unit.languageVersionToken instead")
 class LanguageVersion {
   final int major;
   final int minor;
diff --git a/pkg/analyzer/lib/dart/ast/token.dart b/pkg/analyzer/lib/dart/ast/token.dart
index 8cb6ef9..a6f61ef 100644
--- a/pkg/analyzer/lib/dart/ast/token.dart
+++ b/pkg/analyzer/lib/dart/ast/token.dart
@@ -5,4 +5,4 @@
 /// Defines the tokens that are produced by the scanner, used by the parser, and
 /// referenced from the [AST structure](ast.dart).
 export 'package:_fe_analyzer_shared/src/scanner/token.dart'
-    show Keyword, Token, TokenType;
+    show Keyword, Token, TokenType, LanguageVersionToken;
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index 412d5ce..7903c31 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -103,8 +103,6 @@
 
   @override
   Future<List<int>> getModificationTimes(List<Source> sources) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return sources.map((source) {
       String path = source.fullName;
       return _pathToTimestamp[path] ?? -1;
diff --git a/pkg/analyzer/lib/file_system/overlay_file_system.dart b/pkg/analyzer/lib/file_system/overlay_file_system.dart
index f8ec96b..d1e636a 100644
--- a/pkg/analyzer/lib/file_system/overlay_file_system.dart
+++ b/pkg/analyzer/lib/file_system/overlay_file_system.dart
@@ -60,8 +60,6 @@
 
   @override
   Future<List<int>> getModificationTimes(List<Source> sources) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return sources.map((source) {
       String path = source.fullName;
       return _overlayModificationStamps[path] ??
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index b6d6eca..105cec6 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -100,8 +100,6 @@
 
   @override
   Future<List<int>> getModificationTimes(List<Source> sources) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     List<String> paths = sources.map((source) => source.fullName).toList();
     return _pathsToTimes(paths);
   }
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 5a3f02a..ef9ae37 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -555,9 +555,10 @@
   /// This method does not use analysis priorities, and must not be used in
   /// interactive analysis, such as Analysis Server or its plugins.
   Future<ErrorsResult> getErrors(String path) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     _throwIfNotAbsolutePath(path);
+    if (!_fsState.hasUri(path)) {
+      return null;
+    }
 
     // Ask the analysis result without unit, so return cached errors.
     // If no cached analysis result, it will be computed.
@@ -905,8 +906,6 @@
   /// produced through the [results] stream (just because it is not a fully
   /// resolved unit).
   Future<ParsedUnitResult> parseFile(String path) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     return parseFileSync(path);
   }
 
@@ -930,8 +929,6 @@
 
   @override
   Future<void> performWork() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (_fileTracker.verifyChangedFilesIfNeeded()) {
       return;
     }
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 5d9e1e5..e831c4f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -536,7 +536,6 @@
     return astFactory.compilationUnit(
       beginToken: token,
       endToken: token,
-      languageVersion: null,
       featureSet: _featureSet,
     )..lineInfo = LineInfo(const <int>[0]);
   }
@@ -599,7 +598,6 @@
     Parser parser = Parser(
       source,
       errorListener,
-      languageVersion: scanner.languageVersion,
       featureSet: scanner.featureSet,
       useFasta: useFasta,
     );
diff --git a/pkg/analyzer/lib/src/dart/analysis/mutex.dart b/pkg/analyzer/lib/src/dart/analysis/mutex.dart
index 75f1571..938f6a2 100644
--- a/pkg/analyzer/lib/src/dart/analysis/mutex.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/mutex.dart
@@ -24,8 +24,6 @@
   ///
   /// Returns a [Future] that will be completed when the lock has been acquired.
   Future<void> acquire() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     while (_lock != null) {
       await _lock.future;
     }
@@ -34,8 +32,6 @@
 
   /// Run the given [criticalSection] with acquired mutex.
   Future<T> guard<T>(Future<T> Function() criticalSection) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     await acquire();
     try {
       return await criticalSection();
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 09d57b4..c2f4f13 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -38,8 +38,6 @@
    * Returns class or mixin members with the given [name].
    */
   Future<List<Element>> classMembers(String name) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     List<Element> elements = <Element>[];
 
     void addElement(Element element) {
@@ -70,8 +68,6 @@
    */
   Future<List<SearchResult>> references(
       Element element, SearchedFiles searchedFiles) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (element == null) {
       return const <SearchResult>[];
     }
@@ -123,8 +119,6 @@
    */
   Future<List<SearchResult>> subTypes(
       ClassElement type, SearchedFiles searchedFiles) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (type == null) {
       return const <SearchResult>[];
     }
@@ -178,8 +172,6 @@
    * Returns top-level elements with names matching the given [regExp].
    */
   Future<List<Element>> topLevelElements(RegExp regExp) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     List<Element> elements = <Element>[];
 
     void addElement(Element element) {
@@ -211,8 +203,6 @@
    */
   Future<List<SearchResult>> unresolvedMemberReferences(
       String name, SearchedFiles searchedFiles) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (name == null) {
       return const <SearchResult>[];
     }
@@ -250,8 +240,6 @@
       Element element,
       SearchedFiles searchedFiles,
       Map<IndexRelationKind, SearchResultKind> relationToResultKind) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     // Prepare the element name.
     String name = element.displayName;
     if (element is ConstructorElement) {
@@ -294,8 +282,6 @@
       Element element,
       Map<IndexRelationKind, SearchResultKind> relationToResultKind,
       String file) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     AnalysisDriverUnitIndex index = await _driver.getIndex(file);
     if (index != null) {
       _IndexRequest request = _IndexRequest(index);
@@ -309,16 +295,12 @@
   }
 
   Future<CompilationUnitElement> _getUnitElement(String file) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     UnitElementResult result = await _driver.getUnitElement(file);
     return result?.element;
   }
 
   Future<List<SearchResult>> _searchReferences(
       Element element, SearchedFiles searchedFiles) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     List<SearchResult> results = <SearchResult>[];
     await _addResults(results, element, searchedFiles,
         const {IndexRelationKind.IS_REFERENCED_BY: SearchResultKind.REFERENCE});
@@ -327,8 +309,6 @@
 
   Future<List<SearchResult>> _searchReferences_CompilationUnit(
       CompilationUnitElement element) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     String path = element.source.fullName;
 
     // If the path is not known, then the file is not referenced.
@@ -357,8 +337,6 @@
 
   Future<List<SearchResult>> _searchReferences_Field(
       PropertyInducingElement field, SearchedFiles searchedFiles) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     List<SearchResult> results = <SearchResult>[];
     PropertyAccessorElement getter = field.getter;
     PropertyAccessorElement setter = field.setter;
@@ -393,8 +371,6 @@
 
   Future<List<SearchResult>> _searchReferences_Getter(
       PropertyAccessorElement getter, SearchedFiles searchedFiles) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     List<SearchResult> results = <SearchResult>[];
     await _addResults(results, getter, searchedFiles, const {
       IndexRelationKind.IS_REFERENCED_BY: SearchResultKind.REFERENCE,
@@ -405,8 +381,6 @@
 
   Future<List<SearchResult>> _searchReferences_Import(
       ImportElement element, SearchedFiles searchedFiles) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     String path = element.source.fullName;
     if (!searchedFiles.add(path, this)) {
       return const <SearchResult>[];
@@ -427,8 +401,6 @@
 
   Future<List<SearchResult>> _searchReferences_Library(
       LibraryElement element, SearchedFiles searchedFiles) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     String path = element.source.fullName;
     if (!searchedFiles.add(path, this)) {
       return const <SearchResult>[];
@@ -456,8 +428,6 @@
 
   Future<List<SearchResult>> _searchReferences_Local(Element element,
       bool Function(AstNode n) isRootNode, SearchedFiles searchedFiles) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     String path = element.source.fullName;
     if (!searchedFiles.add(path, this)) {
       return const <SearchResult>[];
@@ -491,8 +461,6 @@
 
   Future<List<SearchResult>> _searchReferences_Parameter(
       ParameterElement parameter, SearchedFiles searchedFiles) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     List<SearchResult> results = <SearchResult>[];
     results.addAll(await _searchReferences_Local(
       parameter,
@@ -510,8 +478,6 @@
 
   Future<List<SearchResult>> _searchReferences_Prefix(
       PrefixElement element, SearchedFiles searchedFiles) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     String path = element.source.fullName;
     if (!searchedFiles.add(path, this)) {
       return const <SearchResult>[];
@@ -865,8 +831,6 @@
       int elementId,
       Map<IndexRelationKind, SearchResultKind> relationToResultKind,
       Future<CompilationUnitElement> Function() getEnclosingUnitElement) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     // Find the first usage of the element.
     int i = _findFirstOccurrence(index.usedElements, elementId);
     if (i == -1) {
@@ -938,8 +902,6 @@
       String name,
       Map<IndexRelationKind, SearchResultKind> relationToResultKind,
       Future<CompilationUnitElement> Function() getEnclosingUnitElement) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     // Find the name identifier.
     int nameId = getStringId(name);
     if (nameId == -1) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index 148a0ab..066e416 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -60,8 +60,6 @@
   @Deprecated('Use LibraryElement.typeProvider')
   @override
   Future<TypeProvider> get typeProvider async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     _checkConsistency();
     if (_typeProvider == null) {
       LibraryElement coreLibrary = await _driver.getLibraryByUri('dart:core');
@@ -78,8 +76,6 @@
   @Deprecated('Use LibraryElement.typeSystem')
   @override
   Future<TypeSystemImpl> get typeSystem async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     _checkConsistency();
     if (_typeSystem == null) {
       var typeProvider = await this.typeProvider;
@@ -115,8 +111,6 @@
 
   @override
   Future<LibraryElement> getLibraryByUri(String uri) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     _checkConsistency();
     var libraryElement = _uriToLibraryCache[uri];
     if (libraryElement == null) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/status.dart b/pkg/analyzer/lib/src/dart/analysis/status.dart
index 084ea20..c6fd7a7 100644
--- a/pkg/analyzer/lib/src/dart/analysis/status.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/status.dart
@@ -43,8 +43,6 @@
    * Return a [Future] that completes when [notify] is called at least once.
    */
   Future<void> get signal async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     await _completer.future;
     _completer = Completer<void>();
   }
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 5d2bfe9..5e1f4a5 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -2026,7 +2026,22 @@
   LineInfo lineInfo;
 
   @override
-  final LanguageVersion languageVersion;
+  LanguageVersion get languageVersion {
+    final token = languageVersionToken;
+    return LanguageVersion(token.major, token.minor);
+  }
+
+  @override
+  LanguageVersionToken get languageVersionToken {
+    CommentToken comment = beginToken.precedingComments;
+    while (comment != null) {
+      if (comment is LanguageVersionToken) {
+        return comment;
+      }
+      comment = comment.next;
+    }
+    return null;
+  }
 
   @override
   final FeatureSet featureSet;
@@ -2042,7 +2057,6 @@
       List<Directive> directives,
       List<CompilationUnitMember> declarations,
       this.endToken,
-      this.languageVersion,
       this.featureSet) {
     _scriptTag = _becomeParentOf(scriptTag);
     _directives = NodeListImpl<Directive>(this, directives);
diff --git a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
index 01d66fa..90ee4ec 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast_factory.dart
@@ -6,7 +6,6 @@
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/ast_factory.dart';
-import 'package:analyzer/dart/ast/language_version.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:meta/meta.dart';
@@ -186,10 +185,9 @@
           List<Directive> directives,
           List<CompilationUnitMember> declarations,
           Token endToken,
-          FeatureSet featureSet,
-          LanguageVersion languageVersion}) =>
+          FeatureSet featureSet}) =>
       CompilationUnitImpl(beginToken, scriptTag, directives, declarations,
-          endToken, languageVersion, featureSet);
+          endToken, featureSet);
 
   @override
   ConditionalExpression conditionalExpression(
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 9f6863e..0da70e2 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -286,7 +286,6 @@
         directives: cloneNodeList(node.directives),
         declarations: cloneNodeList(node.declarations),
         endToken: cloneToken(node.endToken),
-        languageVersion: node.languageVersion,
         featureSet: node.featureSet);
     clone.lineInfo = node.lineInfo;
     return clone;
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index c74a46d..0409d1a 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -108,7 +108,6 @@
     Parser parser = Parser(
       source,
       errorListener,
-      languageVersion: scanner.languageVersion,
       featureSet: scanner.featureSet,
       useFasta: useFasta,
     );
diff --git a/pkg/analyzer/lib/src/dart/scanner/scanner.dart b/pkg/analyzer/lib/src/dart/scanner/scanner.dart
index bdcc724..859db3f 100644
--- a/pkg/analyzer/lib/src/dart/scanner/scanner.dart
+++ b/pkg/analyzer/lib/src/dart/scanner/scanner.dart
@@ -8,7 +8,6 @@
 import 'package:_fe_analyzer_shared/src/scanner/token.dart'
     show Token, TokenType;
 import 'package:analyzer/dart/analysis/features.dart';
-import 'package:analyzer/dart/ast/language_version.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
@@ -72,7 +71,7 @@
    */
   bool enableNonNullable = false;
 
-  LanguageVersion _languageVersion;
+  fasta.LanguageVersionToken _languageVersion;
 
   FeatureSet _featureSet;
 
@@ -114,7 +113,7 @@
    * The language version override specified for this compilation unit using a
    * token like '// @dart = 2.7', or `null` if no override is specified.
    */
-  LanguageVersion get languageVersion => _languageVersion;
+  fasta.LanguageVersionToken get languageVersion => _languageVersion;
 
   set preserveComments(bool preserveComments) {
     this._preserveComments = preserveComments;
@@ -199,10 +198,7 @@
   void _languageVersionChanged(
       fasta.Scanner scanner, fasta.LanguageVersionToken languageVersion) {
     if (languageVersion.major >= 0 && languageVersion.minor >= 0) {
-      _languageVersion = LanguageVersion(
-        languageVersion.major,
-        languageVersion.minor,
-      );
+      _languageVersion = languageVersion;
       if (_featureSet != null) {
         _featureSet = _featureSet.restrictToVersion(
             Version(languageVersion.major, languageVersion.minor, 0));
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 7eb47a4..770d6be 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -50,7 +50,6 @@
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/ast_factory.dart' show AstFactory;
-import 'package:analyzer/dart/ast/language_version.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart' as standard;
 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType;
 import 'package:analyzer/error/listener.dart';
@@ -127,13 +126,10 @@
   /// `true` if variance behavior is enabled
   final bool enableVariance;
 
-  /// The language version override, `null` if not such token.
-  LanguageVersion _languageVersion;
-
   final FeatureSet _featureSet;
 
   AstBuilder(ErrorReporter errorReporter, this.fileUri, this.isFullAst,
-      this._languageVersion, this._featureSet,
+      this._featureSet,
       [Uri uri])
       : this.errorReporter = FastaErrorReporter(errorReporter),
         this.enableNonNullable = _featureSet.isEnabled(Feature.non_nullable),
@@ -959,7 +955,6 @@
         directives: directives,
         declarations: declarations,
         endToken: endToken,
-        languageVersion: _languageVersion,
         featureSet: _featureSet) as CompilationUnitImpl;
     push(unit);
   }
@@ -2733,6 +2728,10 @@
     assert(optional(']', rightBracket));
     debugEvent("IndexedExpression");
 
+    if (!enableNonNullable) {
+      reportErrorIfNullableType(question);
+    }
+
     Expression index = pop();
     Expression target = pop();
     if (target == null) {
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index dd79471..028e2b2a 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -15,7 +15,6 @@
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' as fasta;
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/language_version.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/error.dart';
@@ -202,12 +201,10 @@
   /// Initialize a newly created parser to parse tokens in the given [_source]
   /// and to report any errors that are found to the given [_errorListener].
   factory Parser(Source source, AnalysisErrorListener errorListener,
-      {bool useFasta,
-      LanguageVersion languageVersion,
-      @required FeatureSet featureSet}) {
+      {bool useFasta, @required FeatureSet featureSet}) {
     featureSet ??= FeatureSet.fromEnableFlags([]);
     if (useFasta ?? Parser.useFasta) {
-      return _Parser2(source, errorListener, languageVersion, featureSet,
+      return _Parser2(source, errorListener, featureSet,
           allowNativeClause: true);
     } else {
       return Parser.withoutFasta(source, errorListener, featureSet: featureSet);
@@ -1904,7 +1901,6 @@
           return astFactory.compilationUnit(
             beginToken: eof,
             endToken: eof,
-            languageVersion: null,
             featureSet: _featureSet,
           );
         }
@@ -1961,7 +1957,6 @@
       directives: directives,
       declarations: declarations,
       endToken: _currentToken,
-      languageVersion: null,
       featureSet: _featureSet,
     );
   }
@@ -2418,7 +2413,6 @@
           scriptTag: scriptTag,
           directives: directives,
           endToken: _currentToken,
-          languageVersion: null,
           featureSet: _featureSet,
         );
       }
@@ -2428,7 +2422,6 @@
       scriptTag: scriptTag,
       directives: directives,
       endToken: _currentToken,
-      languageVersion: null,
       featureSet: _featureSet,
     );
   }
diff --git a/pkg/analyzer/lib/src/generated/parser_fasta.dart b/pkg/analyzer/lib/src/generated/parser_fasta.dart
index 3287a18..8f9706b 100644
--- a/pkg/analyzer/lib/src/generated/parser_fasta.dart
+++ b/pkg/analyzer/lib/src/generated/parser_fasta.dart
@@ -24,11 +24,10 @@
   final AstBuilder astBuilder;
 
   ParserAdapter(this.currentToken, ErrorReporter errorReporter, Uri fileUri,
-      LanguageVersion languageVersion, FeatureSet featureSet,
+      FeatureSet featureSet,
       {bool allowNativeClause = false})
       : fastaParser = fasta.Parser(null),
-        astBuilder = AstBuilder(
-            errorReporter, fileUri, true, languageVersion, featureSet) {
+        astBuilder = AstBuilder(errorReporter, fileUri, true, featureSet) {
     fastaParser.listener = astBuilder;
     astBuilder.parser = fastaParser;
     astBuilder.allowNativeClause = allowNativeClause;
@@ -379,23 +378,21 @@
   @override
   bool enableUriInPartOf = true;
 
-  factory _Parser2(Source source, AnalysisErrorListener errorListener,
-      LanguageVersion languageVersion, FeatureSet featureSet,
+  factory _Parser2(
+      Source source, AnalysisErrorListener errorListener, FeatureSet featureSet,
       {bool allowNativeClause = false}) {
     var errorReporter = ErrorReporter(
       errorListener,
       source,
       isNonNullableByDefault: featureSet.isEnabled(Feature.non_nullable),
     );
-    return _Parser2._(
-        source, errorReporter, source.uri, languageVersion, featureSet,
+    return _Parser2._(source, errorReporter, source.uri, featureSet,
         allowNativeClause: allowNativeClause);
   }
 
   _Parser2._(this._source, ErrorReporter errorReporter, Uri fileUri,
-      LanguageVersion languageVersion, FeatureSet featureSet,
-      {bool allowNativeClause = false})
-      : super(null, errorReporter, fileUri, languageVersion, featureSet,
+      FeatureSet featureSet, {bool allowNativeClause = false})
+      : super(null, errorReporter, fileUri, featureSet,
             allowNativeClause: allowNativeClause);
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index 4cc3de6..2b9b822 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -4,7 +4,6 @@
 
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/language_version.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -293,14 +292,12 @@
           directives: directives ?? <Directive>[],
           declarations: declarations ?? <CompilationUnitMember>[],
           endToken: TokenFactory.tokenFromType(TokenType.EOF),
-          languageVersion: null,
           featureSet: null);
 
   static CompilationUnit compilationUnit9(
           {String scriptTag,
           List<Directive> directives,
           List<CompilationUnitMember> declarations,
-          LanguageVersion languageVersion,
           FeatureSet featureSet}) =>
       astFactory.compilationUnit(
           beginToken: TokenFactory.tokenFromType(TokenType.EOF),
@@ -309,7 +306,6 @@
           directives: directives ?? <Directive>[],
           declarations: declarations ?? <CompilationUnitMember>[],
           endToken: TokenFactory.tokenFromType(TokenType.EOF),
-          languageVersion: languageVersion,
           featureSet: featureSet);
 
   static ConditionalExpression conditionalExpression(Expression condition,
diff --git a/pkg/analyzer/lib/src/generated/utilities_general.dart b/pkg/analyzer/lib/src/generated/utilities_general.dart
index 78b9432..a3d4531 100644
--- a/pkg/analyzer/lib/src/generated/utilities_general.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_general.dart
@@ -261,8 +261,6 @@
 
   @override
   Future<E> makeCurrentWhileAsync<E>(Future<E> Function() f) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     PerformanceTag prevTag = makeCurrent();
     try {
       return await f();
diff --git a/pkg/analyzer/lib/src/lint/linter.dart b/pkg/analyzer/lib/src/lint/linter.dart
index ccd0f72..93ca7de 100644
--- a/pkg/analyzer/lib/src/lint/linter.dart
+++ b/pkg/analyzer/lib/src/lint/linter.dart
@@ -85,8 +85,6 @@
   DartLinter(this.options, {this.reporter = const PrintingReporter()});
 
   Future<Iterable<AnalysisErrorInfo>> lintFiles(List<File> files) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     List<AnalysisErrorInfo> errors = [];
     final lintDriver = LintDriver(options);
     errors.addAll(await lintDriver.analyze(files.where((f) => isDartFile(f))));
@@ -703,8 +701,6 @@
 
   @override
   Future<Iterable<AnalysisErrorInfo>> lintFiles(List<File> files) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     List<AnalysisErrorInfo> errors = [];
     final lintDriver = LintDriver(options);
     errors.addAll(await lintDriver.analyze(files.where((f) => isDartFile(f))));
diff --git a/pkg/analyzer/lib/src/lint/project.dart b/pkg/analyzer/lib/src/lint/project.dart
index 4866a43..4b4f1ae 100644
--- a/pkg/analyzer/lib/src/lint/project.dart
+++ b/pkg/analyzer/lib/src/lint/project.dart
@@ -88,8 +88,6 @@
   /// used.
   static Future<DartProject> create(AnalysisDriver driver, List<Source> sources,
       {Directory dir}) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     DartProject project = DartProject._(driver, sources, dir: dir);
     await project._apiModel._calculate();
     return project;
@@ -124,8 +122,6 @@
   }
 
   _calculate() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (sources == null || sources.isEmpty) {
       return;
     }
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 4e1d249..7b5a767 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -358,7 +358,6 @@
         directives: _readNodeList(data.compilationUnit_directives),
         declarations: _readNodeList(data.compilationUnit_declarations),
         endToken: null,
-        languageVersion: null,
         featureSet: null);
   }
 
diff --git a/pkg/analyzer/test/dart/analysis/utilities_test.dart b/pkg/analyzer/test/dart/analysis/utilities_test.dart
index 15fcd19..137eac3 100644
--- a/pkg/analyzer/test/dart/analysis/utilities_test.dart
+++ b/pkg/analyzer/test/dart/analysis/utilities_test.dart
@@ -214,7 +214,7 @@
       featureSet: FeatureSet.fromEnableFlags([]),
     );
 
-    var languageVersion = result.unit.languageVersion;
+    var languageVersion = result.unit.languageVersionToken;
     expect(languageVersion.major, 2);
     expect(languageVersion.minor, 7);
   }
@@ -229,7 +229,7 @@
       featureSet: FeatureSet.fromEnableFlags([]),
     );
 
-    expect(result.unit.languageVersion, isNull);
+    expect(result.unit.languageVersionToken, isNull);
   }
 
   test_parseString_lineInfo() {
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
index a01453f..9e8c8a9 100644
--- a/pkg/analyzer/test/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -741,7 +741,6 @@
       _unit = Parser(
         source,
         listener,
-        languageVersion: scanner.languageVersion,
         featureSet: featureSet,
         useFasta: true,
       ).parseCompilationUnit(tokens);
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index ed796bf..e39ef3c 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -10,12 +10,12 @@
     show ErrorToken;
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' as fasta;
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
-    show LanguageVersionToken, ScannerConfiguration, ScannerResult, scanString;
+    show ScannerConfiguration, ScannerResult, scanString;
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/language_version.dart';
 import 'package:analyzer/dart/ast/token.dart' as analyzer;
-import 'package:analyzer/dart/ast/token.dart' show Token, TokenType;
+import 'package:analyzer/dart/ast/token.dart'
+    show Token, TokenType, LanguageVersionToken;
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart' show ErrorReporter;
 import 'package:analyzer/src/dart/ast/ast.dart';
@@ -1962,9 +1962,7 @@
 
   @override
   void createParser(String content,
-      {int expectedEndOffset,
-      LanguageVersion languageVersion,
-      FeatureSet featureSet}) {
+      {int expectedEndOffset, FeatureSet featureSet}) {
     featureSet ??= FeatureSet.forTesting();
     var result = scanString(content,
         configuration: featureSet.isEnabled(Feature.non_nullable)
@@ -1972,7 +1970,7 @@
             : ScannerConfiguration.classic,
         includeComments: true);
     _fastaTokens = result.tokens;
-    _parserProxy = ParserProxy(_fastaTokens, languageVersion, featureSet,
+    _parserProxy = ParserProxy(_fastaTokens, featureSet,
         allowNativeClause: allowNativeClause,
         expectedEndOffset: expectedEndOffset);
   }
@@ -2083,7 +2081,7 @@
 
   CompilationUnit parseCompilationUnit2(
       String content, GatheringErrorListener listener,
-      {LanguageVersion languageVersion, FeatureSet featureSet}) {
+      {LanguageVersionToken languageVersion, FeatureSet featureSet}) {
     featureSet ??= FeatureSet.forTesting();
     var source = StringSource(content, 'parser_test_StringSource.dart');
 
@@ -2109,8 +2107,8 @@
       isNonNullableByDefault: false,
     );
     fasta.Parser parser = fasta.Parser(null);
-    AstBuilder astBuilder = AstBuilder(
-        errorReporter, source.uri, true, languageVersion, featureSet);
+    AstBuilder astBuilder =
+        AstBuilder(errorReporter, source.uri, true, featureSet);
     parser.listener = astBuilder;
     astBuilder.parser = parser;
     astBuilder.allowNativeClause = allowNativeClause;
@@ -2936,6 +2934,12 @@
     expect(expression.operator.lexeme, '?.');
   }
 
+  void test_indexExpression_nullable_disabled() {
+    parseCompilationUnit('main(a) { a?[0]; }',
+        errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 11, 1)],
+        featureSet: preNonNullable);
+  }
+
   void test_is_nullable() {
     CompilationUnit unit =
         parseCompilationUnit('main() { x is String? ? (x + y) : z; }');
@@ -3514,8 +3518,7 @@
    * Creates a [ParserProxy] which is prepared to begin parsing at the given
    * Fasta token.
    */
-  factory ParserProxy(analyzer.Token firstToken,
-      LanguageVersion languageVersion, FeatureSet featureSet,
+  factory ParserProxy(analyzer.Token firstToken, FeatureSet featureSet,
       {bool allowNativeClause = false, int expectedEndOffset}) {
     TestSource source = TestSource();
     var errorListener = GatheringErrorListener(checkRanges: true);
@@ -3524,22 +3527,16 @@
       source,
       isNonNullableByDefault: false,
     );
-    return ParserProxy._(firstToken, errorReporter, null, errorListener,
-        languageVersion, featureSet,
+    return ParserProxy._(
+        firstToken, errorReporter, null, errorListener, featureSet,
         allowNativeClause: allowNativeClause,
         expectedEndOffset: expectedEndOffset);
   }
 
-  ParserProxy._(
-      analyzer.Token firstToken,
-      ErrorReporter errorReporter,
-      Uri fileUri,
-      this._errorListener,
-      LanguageVersion languageVersion,
-      FeatureSet featureSet,
-      {bool allowNativeClause = false,
-      this.expectedEndOffset})
-      : super(firstToken, errorReporter, fileUri, languageVersion, featureSet,
+  ParserProxy._(analyzer.Token firstToken, ErrorReporter errorReporter,
+      Uri fileUri, this._errorListener, FeatureSet featureSet,
+      {bool allowNativeClause = false, this.expectedEndOffset})
+      : super(firstToken, errorReporter, fileUri, featureSet,
             allowNativeClause: allowNativeClause) {
     _eventListener = ForwardingTestListener(astBuilder);
     fastaParser.listener = _eventListener;
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 7469fd0..13bbfd1 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -9,7 +9,6 @@
     show ScannerResult, scanString;
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/language_version.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
@@ -115,7 +114,6 @@
   void createParser(
     String content, {
     int expectedEndOffset,
-    LanguageVersion languageVersion,
     FeatureSet featureSet,
   });
 
@@ -9476,7 +9474,7 @@
   void createParser(
     String content, {
     int expectedEndOffset,
-    LanguageVersion languageVersion,
+    LanguageVersionToken languageVersion,
     FeatureSet featureSet,
   }) {
     Source source = TestSource();
@@ -9488,7 +9486,6 @@
     parser = Parser(
       source,
       listener,
-      languageVersion: languageVersion,
       featureSet: featureSet,
     );
     parser.allowNativeClause = allowNativeClause;
@@ -9623,7 +9620,6 @@
     Parser parser = Parser(
       source,
       listener,
-      languageVersion: null,
       featureSet: FeatureSet.forTesting(),
     );
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
@@ -9652,7 +9648,6 @@
     Parser parser = Parser(
       source,
       listener,
-      languageVersion: null,
       featureSet: FeatureSet.forTesting(),
     );
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
@@ -9993,7 +9988,6 @@
     Parser parser = Parser(
       source,
       listener,
-      languageVersion: null,
       featureSet: FeatureSet.forTesting(),
     );
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
@@ -10024,7 +10018,6 @@
     Parser parser = Parser(
       source,
       listener,
-      languageVersion: null,
       featureSet: FeatureSet.forTesting(),
     );
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
@@ -12425,7 +12418,6 @@
       Parser(
         NonExistingSource.unknown,
         null,
-        languageVersion: null,
         featureSet: FeatureSet.forTesting(),
       ),
       isNotNull,
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 1ece9e3..9f11614 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -1187,7 +1187,6 @@
     Parser parser = Parser(
       NonExistingSource.unknown,
       listener,
-      languageVersion: scanner.languageVersion,
       featureSet: featureSet,
     );
     CompilationUnit unit = parser.parseCompilationUnit(token);
diff --git a/pkg/analyzer/test/id_tests/inheritance_test.dart b/pkg/analyzer/test/id_tests/inheritance_test.dart
index 2f2c9e6..00d45f8 100644
--- a/pkg/analyzer/test/id_tests/inheritance_test.dart
+++ b/pkg/analyzer/test/id_tests/inheritance_test.dart
@@ -12,6 +12,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/dart/analysis/testing_data.dart';
+import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
 import 'package:analyzer/src/util/ast_data_extractor.dart';
 
 import '../util/id_testing_helper.dart';
@@ -60,6 +61,8 @@
 }
 
 class _InheritanceDataExtractor extends AstDataExtractor<String> {
+  final inheritance = InheritanceManager3();
+
   _InheritanceDataExtractor(Uri uri, Map<Id, ActualData<String>> actualMap)
       : super(uri, actualMap);
 
@@ -75,42 +78,7 @@
   void computeForClass(Declaration node, Id id) {
     super.computeForClass(node, id);
     if (node is ClassDeclaration) {
-      var cls = node.declaredElement;
-
-      var getterNames = <Name>{};
-      var setterNames = <Name>{};
-      var methodNames = <Name>{};
-
-      void collectMembers(InterfaceType type) {
-        for (var element in type.accessors) {
-          if (element.isGetter) {
-            getterNames.add(Name(element));
-          }
-          if (element.isSetter) {
-            setterNames.add(Name(element, isSetter: true));
-          }
-          var getter = element.declaration.correspondingGetter != null
-              ? element.correspondingGetter
-              : null;
-          if (getter != null) {
-            getterNames.add(Name(getter));
-          }
-          var setter = element.declaration.correspondingSetter != null
-              ? element.correspondingSetter
-              : null;
-          if (setter != null) {
-            setterNames.add(Name(setter, isSetter: true));
-          }
-        }
-        for (var method in type.methods) {
-          methodNames.add(Name(method));
-        }
-      }
-
-      collectMembers(cls.thisType);
-      for (var supertype in cls.allSupertypes) {
-        collectMembers(supertype);
-      }
+      var element = node.declaredElement;
 
       void registerMember(
           MemberId id, int offset, Object object, DartType type) {
@@ -118,44 +86,34 @@
             type.getDisplayString(withNullability: true), object);
       }
 
-      for (var getterName in getterNames) {
-        var getter =
-            cls.thisType.lookUpGetter2(getterName.text, getterName.library);
-        if (getter != null) {
-          ClassElement enclosingClass = getter.enclosingElement;
-          if (enclosingClass.isDartCoreObject) continue;
-          var id = MemberId.internal(getterName.text, className: cls.name);
-          var offset =
-              enclosingClass == cls ? getter.nameOffset : cls.nameOffset;
-          registerMember(id, offset, getter, getter.returnType);
-        }
-      }
+      var interface = inheritance.getInterface(element.thisType);
+      for (var name in interface.map.keys) {
+        var executable = interface.map[name];
 
-      for (var setterName in setterNames) {
-        var setter =
-            cls.thisType.lookUpSetter2(setterName.text, setterName.library);
-        if (setter != null) {
-          ClassElement enclosingClass = setter.enclosingElement;
-          if (enclosingClass.isDartCoreObject) continue;
-          var id =
-              MemberId.internal('${setterName.text}=', className: cls.name);
-          var offset =
-              enclosingClass == cls ? setter.nameOffset : cls.nameOffset;
-          registerMember(id, offset, setter, setter.type.parameters.first.type);
-        }
-      }
+        ClassElement enclosingClass = executable.enclosingElement;
+        if (enclosingClass.isDartCoreObject) continue;
 
-      for (var methodName in methodNames) {
-        var method =
-            cls.thisType.lookUpMethod2(methodName.text, methodName.library);
-        if (method != null) {
-          ClassElement enclosingClass = method.enclosingElement;
-          if (enclosingClass.isDartCoreObject) continue;
-          var id = MemberId.internal(methodName.text, className: cls.name);
-          var offset =
-              enclosingClass == cls ? method.nameOffset : cls.nameOffset;
-          registerMember(id, offset, method, method.type);
+        var id = MemberId.internal(
+          name.name,
+          className: element.name,
+        );
+
+        var offset = enclosingClass == element
+            ? executable.nameOffset
+            : element.nameOffset;
+
+        DartType type;
+        if (executable is MethodElement) {
+          type = executable.type;
+        } else if (executable is PropertyAccessorElement) {
+          if (executable.isGetter) {
+            type = executable.returnType;
+          } else {
+            type = executable.parameters.first.type;
+          }
         }
+
+        registerMember(id, offset, executable, type);
       }
     }
   }
@@ -191,39 +149,3 @@
   }
   return sb.toString();
 }
-
-class Name {
-  final String text;
-  final bool isPrivate;
-  final LibraryElement library;
-
-  Name.internal(this.text, this.isPrivate, this.library);
-
-  factory Name(Element element, {bool isSetter = false}) {
-    String name = element.name;
-    if (isSetter) {
-      if (!name.endsWith('=')) {
-        throw UnsupportedError("Unexpected setter name '$name'");
-      }
-      name = name.substring(0, name.length - 1);
-    }
-    return Name.internal(name, element.isPrivate, element.library);
-  }
-
-  @override
-  int get hashCode => isPrivate
-      ? text.hashCode * 13 + library.hashCode * 17
-      : text.hashCode * 13;
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    return other is Name &&
-        text == other.text &&
-        isPrivate == other.isPrivate &&
-        (!isPrivate || library == other.library);
-  }
-
-  @override
-  String toString() => isPrivate ? '${library.name}::$text' : text;
-}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index a4f0f10..45376fd 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -1620,7 +1620,7 @@
 ''');
 
     var result = await driver.getResult(path);
-    var languageVersion = result.unit.languageVersion;
+    var languageVersion = result.unit.languageVersionToken;
     expect(languageVersion.major, 2);
     expect(languageVersion.minor, 7);
   }
@@ -2208,7 +2208,7 @@
 ''');
 
     var parseResult = driver.parseFileSync(path);
-    var languageVersion = parseResult.unit.languageVersion;
+    var languageVersion = parseResult.unit.languageVersionToken;
     expect(languageVersion.major, 2);
     expect(languageVersion.minor, 7);
   }
@@ -2221,7 +2221,7 @@
 ''');
 
     var parseResult = driver.parseFileSync(path);
-    expect(parseResult.unit.languageVersion, isNull);
+    expect(parseResult.unit.languageVersionToken, isNull);
   }
 
   test_parseFileSync_notAbsolutePath() async {
diff --git a/pkg/analyzer/test/src/dart/ast/ast_test.dart b/pkg/analyzer/test/src/dart/ast/ast_test.dart
index 79c11db..e9d3ce2 100644
--- a/pkg/analyzer/test/src/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/ast_test.dart
@@ -14,6 +14,7 @@
 
 main() {
   defineReflectiveSuite(() {
+    defineReflectiveTests(CompilationUnitImplTest);
     defineReflectiveTests(ExpressionImplTest);
     defineReflectiveTests(InstanceCreationExpressionImplTest);
     defineReflectiveTests(IntegerLiteralImplTest);
@@ -21,6 +22,62 @@
 }
 
 @reflectiveTest
+class CompilationUnitImplTest extends ParserTestCase {
+  String testSource;
+  CompilationUnitImpl testUnit;
+
+  void parse(String source) {
+    testSource = source;
+    testUnit = parseCompilationUnit(source);
+  }
+
+  test_languageVersionComment_none() {
+    parse('''
+void main() {}
+''');
+    expect(testUnit.languageVersionToken, null);
+  }
+
+  test_languageVersionComment_none_onlyNormalComment() {
+    parse('''
+// A normal comment.
+void main() {}
+''');
+    expect(testUnit.languageVersionToken, null);
+  }
+
+  test_languageVersionComment_firstComment() {
+    parse('''
+// @dart=2.6
+void main() {}
+''');
+    expect(
+        testUnit.languageVersionToken, testUnit.beginToken.precedingComments);
+  }
+
+  test_languageVersionComment_secondComment() {
+    parse('''
+// A normal comment.
+// @dart=2.6
+void main() {}
+''');
+    expect(testUnit.languageVersionToken,
+        testUnit.beginToken.precedingComments.next);
+  }
+
+  test_languageVersionComment_thirdComment() {
+    parse('''
+// A normal comment.
+// Another normal comment.
+// @dart=2.6
+void main() {}
+''');
+    expect(testUnit.languageVersionToken,
+        testUnit.beginToken.precedingComments.next.next);
+  }
+}
+
+@reflectiveTest
 class ExpressionImplTest extends ParserTestCase {
   String testSource;
   CompilationUnitImpl testUnit;
diff --git a/pkg/analyzer/test/src/dart/ast/parse_base.dart b/pkg/analyzer/test/src/dart/ast/parse_base.dart
index 19ca5e7..1583c73 100644
--- a/pkg/analyzer/test/src/dart/ast/parse_base.dart
+++ b/pkg/analyzer/test/src/dart/ast/parse_base.dart
@@ -37,7 +37,6 @@
     var parser = Parser(
       source,
       errorListener,
-      languageVersion: scanner.languageVersion,
       featureSet: featureSet,
       useFasta: useFasta,
     );
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart
index b00bbab..0ca414d 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart
@@ -211,4 +211,20 @@
 
   @override
   bool get typeToStringWithNullability => true;
+
+  test_optOut_returnType_expressionBody_Null() async {
+    newFile('/test/lib/a.dart', content: r'''
+void foo(Map<String, String> Function() f) {}
+''');
+    await resolveTestCode('''
+// @dart = 2.5
+import 'a.dart';
+
+void main() {
+  foo(() => null);
+}
+''');
+    var element = findNode.functionExpression('() =>').declaredElement;
+    assertType(element.returnType, 'Null*');
+  }
 }
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index 7253a77..f7ce160 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -31,7 +31,6 @@
   Parser parser = Parser(
     NonExistingSource.unknown,
     AnalysisErrorListener.NULL_LISTENER,
-    languageVersion: scanner.languageVersion,
     featureSet: scanner.featureSet,
   );
   CompilationUnit unit = parser.parseCompilationUnit(token);
diff --git a/pkg/analyzer_cli/test/utils.dart b/pkg/analyzer_cli/test/utils.dart
index 778e42f..a7c3640 100644
--- a/pkg/analyzer_cli/test/utils.dart
+++ b/pkg/analyzer_cli/test/utils.dart
@@ -18,7 +18,9 @@
 String get packageRoot {
   // If the package root directory is specified on the command line using
   // -DpkgRoot=..., use it.
-  var pkgRootVar = const String.fromEnvironment('pkgRoot');
+  var pkgRootVar = const bool.hasEnvironment('pkgRoot')
+      ? const String.fromEnvironment('pkgRoot')
+      : null;
   if (pkgRootVar != null) {
     var path = pathos.join(Directory.current.path, pkgRootVar);
     if (!path.endsWith(pathos.separator)) path += pathos.separator;
diff --git a/pkg/analyzer_cli/tool/perf.dart b/pkg/analyzer_cli/tool/perf.dart
index 5685be8..c2fbccd 100644
--- a/pkg/analyzer_cli/tool/perf.dart
+++ b/pkg/analyzer_cli/tool/perf.dart
@@ -86,7 +86,6 @@
   var parser = Parser(
     source,
     AnalysisErrorListener.NULL_LISTENER,
-    languageVersion: null,
     featureSet: FeatureSet.fromEnableFlags([]),
   );
   return parser.parseDirectives(token);
@@ -121,7 +120,6 @@
   var parser = Parser(
     source,
     AnalysisErrorListener.NULL_LISTENER,
-    languageVersion: null,
     featureSet: FeatureSet.fromEnableFlags([]),
   );
   return parser.parseCompilationUnit(token);
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart b/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
index 0c585f9..4eb87d5 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
@@ -43,10 +43,38 @@
   /// type but isn't explicitly implemented in the type hierarchy.
   static const int callFunction = 200;
 
+  /// The relevance used when suggesting a closure corresponding to a
+  /// function-typed parameter in an argument list.
+  static const int closure = 900;
+
+  /// The relevance used when suggesting a field as a field formal parameter.
+  static const int fieldFormalParameter = 1000;
+
+  /// The relevance used when suggesting a label.
+  static const int label = 1000;
+
+  /// The relevance used when suggesting the `loadLibrary` function from a
+  /// deferred imported library.
+  static const int loadLibrary = 200;
+
   /// The relevance used when suggesting a member of a class or extension and
   /// there are no features that can be used to provide a relevance score.
   static const int member = 500;
 
+  /// The relevance used when suggesting a named argument corresponding to a
+  /// named parameter that is not required.
+  static const int namedArgument = 900;
+
+  /// The relevance used when suggesting a named constructor.
+  static const int namedConstructor = 1000;
+
   /// The relevance used when suggesting an override of an inherited member.
   static const int override = 750;
+
+  /// The relevance used when suggesting a prefix from an import directive.
+  static const int prefix = 50;
+
+  /// The relevance used when suggesting a named argument corresponding to a
+  /// named parameter that is required.
+  static const int requiredNamedArgument = 950;
 }
diff --git a/pkg/compiler/lib/src/kernel/kernel_impact.dart b/pkg/compiler/lib/src/kernel/kernel_impact.dart
index 21e7bb6..7e1739f 100644
--- a/pkg/compiler/lib/src/kernel/kernel_impact.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_impact.dart
@@ -457,7 +457,7 @@
         new StaticUse.staticInvoke(target, callStructure, typeArguments));
 
     if (typeArguments.length != 1) return;
-    DartType matchedType = typeArguments.first;
+    DartType matchedType = dartTypes.eraseLegacy(typeArguments.first);
 
     if (matchedType is! InterfaceType) return;
     InterfaceType interfaceType = matchedType;
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index ffc588d..bd8c171 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -4040,8 +4040,8 @@
 
     // The type should be a single type name.
     ir.DartType type = types.first;
-    DartType typeValue = localsHandler
-        .substInContext(_elementMap.getDartType(type).withoutNullability);
+    DartType typeValue = dartTypes.eraseLegacy(
+        localsHandler.substInContext(_elementMap.getDartType(type)));
     if (typeValue is! InterfaceType) return false;
     InterfaceType interfaceType = typeValue;
     if (!dartTypes.treatAsRawType(interfaceType)) return false;
diff --git a/pkg/dartdev/analysis_options.yaml b/pkg/dartdev/analysis_options.yaml
index bafc960..0f9f6b8 100644
--- a/pkg/dartdev/analysis_options.yaml
+++ b/pkg/dartdev/analysis_options.yaml
@@ -10,5 +10,6 @@
 linter:
   rules:
     - directives_ordering
+    - prefer_relative_imports
     - prefer_single_quotes
     - unnecessary_brace_in_string_interps
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index d9cfeb2..0b34601 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -11,6 +11,7 @@
 import 'src/commands/create.dart';
 import 'src/commands/format.dart';
 import 'src/commands/pub.dart';
+import 'src/commands/run.dart';
 import 'src/commands/test.dart';
 import 'src/core.dart';
 
@@ -29,6 +30,7 @@
     addCommand(FormatCommand(verbose: verbose));
     addCommand(MigrateCommand(logProvider: () => log, hidden: !verbose));
     addCommand(PubCommand(verbose: verbose));
+    addCommand(RunCommand(verbose: verbose));
     addCommand(TestCommand(verbose: verbose));
   }
 
diff --git a/pkg/dartdev/lib/src/commands/pub.dart b/pkg/dartdev/lib/src/commands/pub.dart
index 1b24c65..d7970bc 100644
--- a/pkg/dartdev/lib/src/commands/pub.dart
+++ b/pkg/dartdev/lib/src/commands/pub.dart
@@ -15,11 +15,11 @@
 
   final ArgParser argParser = ArgParser.allowAnything();
 
-  /// Override [printUsage] for invocations of 'dart help pub' which won't
-  /// execute [run] below.  Without this, the 'dart help pub' reports the
-  /// command pub with no commands or flags.
   @override
   void printUsage() {
+    // Override [printUsage] for invocations of 'dart help pub' which won't
+    // execute [run] below.  Without this, the 'dart help pub' reports the
+    // command pub with no commands or flags.
     final command = sdk.pub;
     final args = ['help'];
 
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
new file mode 100644
index 0000000..b4e202e
--- /dev/null
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:args/args.dart';
+
+import '../core.dart';
+import '../sdk.dart';
+
+class RunCommand extends DartdevCommand<int> {
+  final ArgParser argParser = ArgParser.allowAnything();
+
+  RunCommand({bool verbose = false}) : super('run', '''
+Run a Dart app or package.
+
+dart run <file path>   run the specified Dart file
+dart run package:foo   run the Dart file specified by some <package>:<executable>''');
+
+  @override
+  String get invocation => '${super.invocation} <dart file | package target>';
+
+  @override
+  void printUsage() {
+    // Override [printUsage] for invocations of 'dart help run' which won't
+    // execute [run] below.  Without this, the 'dart help run' reports the
+    // command pub with no commands or flags.
+    final command = sdk.dart;
+    final args = ['--help'];
+
+    log.trace('$command ${args.first}');
+
+    // Call 'dart --help'
+    // Process.runSync(..) is used since [printUsage] is not an async method,
+    // and we want to guarantee that the result (the help text for the console)
+    // is printed before command exits.
+    final result = Process.runSync(command, args);
+    stderr.write(result.stderr);
+    stdout.write(result.stdout);
+  }
+
+  @override
+  FutureOr<int> run() async {
+    // the command line arguments after 'run'
+    final args = argResults.arguments;
+
+    // TODO(jwren) Implement support for pubspec executables, see
+    //  https://dart.dev/tools/pub/pubspec#executables
+
+    // Starting in ProcessStartMode.inheritStdio mode means the child process
+    // can detect support for ansi chars.
+    var process = await Process.start(sdk.dart, args,
+        mode: ProcessStartMode.inheritStdio);
+    return process.exitCode;
+  }
+}
diff --git a/pkg/dartdev/lib/src/commands/test.dart b/pkg/dartdev/lib/src/commands/test.dart
index a9ffa42..278cc91 100644
--- a/pkg/dartdev/lib/src/commands/test.dart
+++ b/pkg/dartdev/lib/src/commands/test.dart
@@ -11,7 +11,8 @@
 import '../sdk.dart';
 
 class TestCommand extends DartdevCommand<int> {
-  TestCommand({bool verbose = false}) : super('test', 'todo: .');
+  TestCommand({bool verbose = false})
+      : super('test', 'Runs tests in this project.');
 
   final ArgParser argParser = ArgParser.allowAnything();
 
@@ -50,7 +51,7 @@
 In order to run tests, you need to add a dependency on package:test in your
 pubspec.yaml file:
 
-${ansi.emphasized('dev_dependencies:\n  test: any')}
+${ansi.emphasized('dev_dependencies:\n  test: ^1.0.0')}
 
 See https://pub.dev/packages/test#-installing-tab- for more information on
 adding package:test, and https://dart.dev/guides/testing for general
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
index 96626ea..67820a5 100644
--- a/pkg/dartdev/test/commands/flag_test.dart
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -9,9 +9,32 @@
 import '../utils.dart';
 
 void main() {
+  group('command', command);
   group('flag', help);
 }
 
+void command() {
+  // For each command description, assert that the values are not empty, don't
+  // have trailing white space and end with a period.
+  test('description formatting', () {
+    DartdevRunner([]).commands.forEach((String commandKey, Command command) {
+      expect(commandKey, isNotEmpty);
+      expect(command.description, isNotEmpty);
+      expect(command.description.split('\n').first, endsWith('.'));
+      expect(command.description.trim(), equals(command.description));
+    });
+  });
+
+  // Assert that all found usageLineLengths are the same and null
+  test('argParser usageLineLength isNull', () {
+    DartdevRunner([]).commands.forEach((String commandKey, Command command) {
+      if (command.argParser != null) {
+        expect(command.argParser.usageLineLength, isNull);
+      }
+    });
+  });
+}
+
 void help() {
   TestProject p;
 
@@ -48,15 +71,4 @@
     expect(result.exitCode, 0);
     expect(result.stdout, contains('migrate '));
   });
-
-  // For each command description, assert that the values are not empty, don't
-  // have trailing white space and end with a period.
-  test('description formatting', () {
-    DartdevRunner([]).commands.forEach((String commandKey, Command command) {
-      expect(commandKey, isNotEmpty);
-      expect(command.description, isNotEmpty);
-      expect(command.description, endsWith('.'));
-      expect(command.description.trim(), equals(command.description));
-    });
-  });
 }
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
new file mode 100644
index 0000000..3699c92
--- /dev/null
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:test/test.dart';
+
+import '../utils.dart';
+
+void main() {
+  group('run', run);
+}
+
+void run() {
+  TestProject p;
+
+  tearDown(() => p?.dispose());
+
+  test('--help', () {
+    p = project();
+    var result = p.runSync('run', ['--help']);
+
+    expect(result.stdout, isEmpty);
+    expect(result.stderr, contains('Executes the Dart script'));
+    expect(result.stderr, contains('Common VM flags:'));
+    expect(result.exitCode, 0);
+  });
+
+  test("'Hello World'", () {
+    p = project(mainSrc: "void main() { print('Hello World'); }");
+    ProcessResult result = p.runSync('run', [p.relativeFilePath]);
+
+    expect(result.stdout, contains('Hello World'));
+    expect(result.stderr, isEmpty);
+    expect(result.exitCode, 0);
+  });
+
+  test('no such file', () {
+    p = project(mainSrc: "void main() { print('Hello World'); }");
+    ProcessResult result =
+        p.runSync('run', ['no/such/file/' + p.relativeFilePath]);
+
+    expect(result.stderr, isNotEmpty);
+    expect(result.exitCode, isNot(0));
+  });
+}
diff --git a/pkg/dartdev/test/commands/test_test.dart b/pkg/dartdev/test/commands/test_test.dart
index 1b390ff..e1e9b5c 100644
--- a/pkg/dartdev/test/commands/test_test.dart
+++ b/pkg/dartdev/test/commands/test_test.dart
@@ -43,12 +43,6 @@
         'In order to run tests, you need to add a dependency on package:test',
       ),
     );
-    expect(
-      result.stdout,
-      contains(
-        'dev_dependencies:\n  test: any',
-      ),
-    );
   }, skip: 'https://github.com/dart-lang/sdk/issues/40854');
 
   test('has dependency', () {
diff --git a/pkg/dartdev/test/test_all.dart b/pkg/dartdev/test/test_all.dart
index 4b9ccaa..ae71878 100644
--- a/pkg/dartdev/test/test_all.dart
+++ b/pkg/dartdev/test/test_all.dart
@@ -11,6 +11,7 @@
 import 'commands/help_test.dart' as help;
 import 'commands/migrate_test.dart' as migrate;
 import 'commands/pub_test.dart' as pub;
+import 'commands/run_test.dart' as run;
 import 'commands/test_test.dart' as test;
 import 'core_test.dart' as core;
 import 'sdk_test.dart' as sdk;
@@ -25,6 +26,7 @@
     help.main();
     migrate.main();
     pub.main();
+    run.main();
     test.main();
     core.main();
     sdk.main();
diff --git a/pkg/dev_compiler/lib/src/kernel/type_table.dart b/pkg/dev_compiler/lib/src/kernel/type_table.dart
index 0c704de..ee44a72 100644
--- a/pkg/dev_compiler/lib/src/kernel/type_table.dart
+++ b/pkg/dev_compiler/lib/src/kernel/type_table.dart
@@ -63,16 +63,23 @@
 
   bool isNamed(DartType type) => _names.containsKey(type);
 
+  /// A name for a type made of JS identifier safe characters.
+  ///
+  /// 'L' and 'N' are prepended to a type name to represent a legacy or nullable
+  /// flavor of a type.
   String _typeString(DartType type, {bool flat = false}) {
+    var nullability = type.nullability == Nullability.legacy
+        ? 'L'
+        : type.nullability == Nullability.nullable ? 'N' : '';
     if (type is InterfaceType) {
-      var name = type.classNode.name;
+      var name = '${type.classNode.name}$nullability';
       var typeArgs = type.typeArguments;
       if (typeArgs == null) return name;
       if (typeArgs.every((p) => p == const DynamicType())) return name;
       return "${name}Of${typeArgs.map(_typeString).join("\$")}";
     }
     if (type is TypedefType) {
-      var name = type.typedefNode.name;
+      var name = '${type.typedefNode.name}$nullability';
       var typeArgs = type.typeArguments;
       if (typeArgs == null) return name;
       if (typeArgs.every((p) => p == const DynamicType())) return name;
@@ -91,12 +98,13 @@
       } else if (count == 0) {
         paramList = 'Void';
       }
-      return '${paramList}To${rType}';
+      return '${paramList}To$nullability$rType';
     }
-    if (type is TypeParameterType) return type.parameter.name;
-    if (type == const DynamicType()) return 'dynamic';
-    if (type == const VoidType()) return 'void';
-    if (type == const BottomType()) return 'bottom';
+    if (type is TypeParameterType) return '${type.parameter.name}$nullability';
+    if (type is DynamicType) return 'dynamic';
+    if (type is VoidType) return 'void';
+    if (type is NeverType) return 'Never$nullability';
+    if (type is BottomType) return 'bottom';
     return 'invalid';
   }
 
diff --git a/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
index 93731df..b091933 100644
--- a/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
+++ b/pkg/dev_compiler/tool/dart2js_nnbd_sdk_error_golden.txt
@@ -1,10 +1,10 @@
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1637|7|5|Superinterfaces don't have a valid override for '&': int.& (int Function(int)), JSNumber.& (num Function(num)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1637|7|5|Superinterfaces don't have a valid override for '<<': int.<< (int Function(int)), JSNumber.<< (num Function(num)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1637|7|5|Superinterfaces don't have a valid override for '>>': int.>> (int Function(int)), JSNumber.>> (num Function(num)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1637|7|5|Superinterfaces don't have a valid override for '\|': int.\| (int Function(int)), JSNumber.\| (num Function(num)).
-ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1637|7|5|Superinterfaces don't have a valid override for '^': int.^ (int Function(int)), JSNumber.^ (num Function(num)).
-ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1654|28|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1656|27|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1659|17|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1664|18|1|The operator '&' isn't defined for the type 'JSInt'.
-ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1664|44|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1631|7|5|Superinterfaces don't have a valid override for '&': int.& (int Function(int)), JSNumber.& (num Function(num)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1631|7|5|Superinterfaces don't have a valid override for '<<': int.<< (int Function(int)), JSNumber.<< (num Function(num)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1631|7|5|Superinterfaces don't have a valid override for '>>': int.>> (int Function(int)), JSNumber.>> (num Function(num)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1631|7|5|Superinterfaces don't have a valid override for '\|': int.\| (int Function(int)), JSNumber.\| (num Function(num)).
+ERROR|COMPILE_TIME_ERROR|INCONSISTENT_INHERITANCE|lib/_internal/js_runtime/lib/interceptors.dart|1631|7|5|Superinterfaces don't have a valid override for '^': int.^ (int Function(int)), JSNumber.^ (num Function(num)).
+ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1648|28|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1650|27|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1653|17|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1658|18|1|The operator '&' isn't defined for the type 'JSInt'.
+ERROR|STATIC_TYPE_WARNING|UNDEFINED_OPERATOR|lib/_internal/js_runtime/lib/interceptors.dart|1658|44|1|The operator '&' isn't defined for the type 'JSInt'.
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 580753b..2c97d0b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1561,8 +1561,8 @@
     Expression expression = popForValue();
     if (expression is Cascade) {
       push(expression);
-      push(_createReadOnlyVariableAccess(
-          expression.variable, token, expression.fileOffset, null));
+      push(_createReadOnlyVariableAccess(expression.variable, token,
+          expression.fileOffset, null, ReadOnlyAccessKind.LetVariable));
     } else {
       bool isNullAware = optional('?..', token);
       if (isNullAware && !libraryBuilder.isNonNullableByDefault) {
@@ -1572,8 +1572,8 @@
           forest.createVariableDeclarationForValue(expression);
       push(new Cascade(variable, isNullAware: isNullAware)
         ..fileOffset = expression.fileOffset);
-      push(_createReadOnlyVariableAccess(
-          variable, token, expression.fileOffset, null));
+      push(_createReadOnlyVariableAccess(variable, token, expression.fileOffset,
+          null, ReadOnlyAccessKind.LetVariable));
     }
   }
 
@@ -1908,9 +1908,13 @@
   /// using [token] and [charOffset] for offset information and [name]
   /// for `ExpressionGenerator._plainNameForRead`.
   ReadOnlyAccessGenerator _createReadOnlyVariableAccess(
-      VariableDeclaration variable, Token token, int charOffset, String name) {
+      VariableDeclaration variable,
+      Token token,
+      int charOffset,
+      String name,
+      ReadOnlyAccessKind kind) {
     return new ReadOnlyAccessGenerator(
-        this, token, createVariableGet(variable, charOffset), name);
+        this, token, createVariableGet(variable, charOffset), name, kind);
   }
 
   /// Look up [name] in [scope] using [token] as location information (both to
@@ -1993,7 +1997,14 @@
       }
       VariableDeclaration variable = variableBuilder.variable;
       if (!variableBuilder.isAssignable) {
-        return _createReadOnlyVariableAccess(variable, token, charOffset, name);
+        return _createReadOnlyVariableAccess(
+            variable,
+            token,
+            charOffset,
+            name,
+            variableBuilder.isConst
+                ? ReadOnlyAccessKind.ConstVariable
+                : ReadOnlyAccessKind.FinalVariable);
       } else {
         return new VariableUseGenerator(this, token, variable);
       }
@@ -4339,8 +4350,8 @@
     debugEvent("ThisExpression");
     if (context.isScopeReference && isDeclarationInstanceContext) {
       if (extensionThis != null) {
-        push(_createReadOnlyVariableAccess(
-            extensionThis, token, offsetForToken(token), 'this'));
+        push(_createReadOnlyVariableAccess(extensionThis, token,
+            offsetForToken(token), 'this', ReadOnlyAccessKind.ExtensionThis));
       } else {
         push(new ThisAccessGenerator(this, token, inInitializer,
             inFieldInitializer, inLateFieldInitializer));
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index a5d05ad..02bcfc4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -2900,7 +2900,16 @@
 
   TypeUseGenerator(ExpressionGeneratorHelper helper, Token token,
       this.declaration, String targetName)
-      : super(helper, token, null, targetName);
+      : super(
+            helper,
+            token,
+            null,
+            targetName,
+            // TODO(johnniwinther): InvalidTypeDeclarationBuilder is currently
+            // misused for import conflict.
+            declaration is InvalidTypeDeclarationBuilder
+                ? ReadOnlyAccessKind.InvalidDeclaration
+                : ReadOnlyAccessKind.TypeLiteral);
 
   @override
   String get _debugName => "TypeUseGenerator";
@@ -3100,6 +3109,16 @@
   }
 }
 
+enum ReadOnlyAccessKind {
+  ConstVariable,
+  FinalVariable,
+  ExtensionThis,
+  LetVariable,
+  TypeLiteral,
+  ParenthesizedExpression,
+  InvalidDeclaration,
+}
+
 /// [ReadOnlyAccessGenerator] represents the subexpression whose prefix is the
 /// name of final local variable, final parameter, or catch clause variable or
 /// `this` in an instance method in an extension declaration.
@@ -3132,10 +3151,10 @@
 
   Expression expression;
 
-  VariableDeclaration value;
+  final ReadOnlyAccessKind kind;
 
   ReadOnlyAccessGenerator(ExpressionGeneratorHelper helper, Token token,
-      this.expression, this.targetName)
+      this.expression, this.targetName, this.kind)
       : super(helper, token);
 
   @override
@@ -3149,6 +3168,38 @@
 
   Expression _createRead() => expression;
 
+  Expression _makeInvalidWrite(Expression value) {
+    switch (kind) {
+      case ReadOnlyAccessKind.ConstVariable:
+        assert(targetName != null);
+        return _helper.buildProblem(
+            templateCannotAssignToConstVariable.withArguments(targetName),
+            fileOffset,
+            lengthForToken(token));
+      case ReadOnlyAccessKind.FinalVariable:
+        assert(targetName != null);
+        return _helper.buildProblem(
+            templateCannotAssignToFinalVariable.withArguments(targetName),
+            fileOffset,
+            lengthForToken(token));
+      case ReadOnlyAccessKind.ExtensionThis:
+        return _helper.buildProblem(messageCannotAssignToExtensionThis,
+            fileOffset, lengthForToken(token));
+      case ReadOnlyAccessKind.TypeLiteral:
+        return _helper.buildProblem(messageCannotAssignToTypeLiteral,
+            fileOffset, lengthForToken(token));
+      case ReadOnlyAccessKind.ParenthesizedExpression:
+        return _helper.buildProblem(
+            messageCannotAssignToParenthesizedExpression,
+            fileOffset,
+            lengthForToken(token));
+      case ReadOnlyAccessKind.LetVariable:
+      case ReadOnlyAccessKind.InvalidDeclaration:
+        break;
+    }
+    return super._makeInvalidWrite(value);
+  }
+
   @override
   Expression buildAssignment(Expression value, {bool voidContext: false}) {
     return _makeInvalidWrite(value);
@@ -3205,8 +3256,8 @@
     printNodeOn(expression, sink, syntheticNames: syntheticNames);
     sink.write(", plainNameForRead: ");
     sink.write(targetName);
-    sink.write(", value: ");
-    printNodeOn(value, sink, syntheticNames: syntheticNames);
+    sink.write(", kind: ");
+    sink.write(kind);
   }
 }
 
@@ -4437,7 +4488,8 @@
 class ParenthesizedExpressionGenerator extends ReadOnlyAccessGenerator {
   ParenthesizedExpressionGenerator(
       ExpressionGeneratorHelper helper, Token token, Expression expression)
-      : super(helper, token, expression, null);
+      : super(helper, token, expression, null,
+            ReadOnlyAccessKind.ParenthesizedExpression);
 
   @override
   Expression buildSimpleRead() => expression;
@@ -4448,11 +4500,6 @@
 
   String get _debugName => "ParenthesizedExpressionGenerator";
 
-  Expression _makeInvalidWrite(Expression value) {
-    return _helper.buildProblem(messageCannotAssignToParenthesizedExpression,
-        fileOffset, lengthForToken(token));
-  }
-
   /* Expression | Generator */ buildPropertyAccess(
       IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
     if (send is SendAccessGenerator) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index b053237..c237248 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -5876,7 +5876,7 @@
 
   Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
     Expression rhs = inferrer.ensureAssignable(
-        greatestClosure(inferrer.coreTypes, variableSet.variable.type),
+        greatestClosure(variableSet.variable.type, inferrer.bottomType),
         rhsType,
         variableSet.value,
         errorTemplate: templateForInLoopElementTypeNotAssignable,
@@ -5936,7 +5936,7 @@
   @override
   Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
     Expression rhs = inferrer.ensureAssignable(
-        greatestClosure(inferrer.coreTypes, _writeType), rhsType, _rhs,
+        greatestClosure(_writeType, inferrer.bottomType), rhsType, _rhs,
         errorTemplate: templateForInLoopElementTypeNotAssignable,
         isVoidAllowed: true);
 
@@ -5970,7 +5970,7 @@
   @override
   Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
     Expression rhs = inferrer.ensureAssignable(
-        greatestClosure(inferrer.coreTypes, _writeType),
+        greatestClosure(_writeType, inferrer.bottomType),
         rhsType,
         superPropertySet.value,
         errorTemplate: templateForInLoopElementTypeNotAssignable,
@@ -5995,7 +5995,7 @@
   @override
   Expression inferAssignment(TypeInferrerImpl inferrer, DartType rhsType) {
     Expression rhs = inferrer.ensureAssignable(
-        greatestClosure(inferrer.coreTypes, staticSet.target.setterType),
+        greatestClosure(staticSet.target.setterType, inferrer.bottomType),
         rhsType,
         staticSet.value,
         errorTemplate: templateForInLoopElementTypeNotAssignable,
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 2970f25..9a328fc 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -155,7 +155,7 @@
       DartType returnContext, bool needToInferReturnType) {
     assert(returnContext != null);
     DartType declaredReturnType =
-        greatestClosure(inferrer.coreTypes, returnContext);
+        greatestClosure(returnContext, inferrer.bottomType);
     bool isAsync = asyncMarker == AsyncMarker.Async ||
         asyncMarker == AsyncMarker.AsyncStar;
     bool isGenerator = asyncMarker == AsyncMarker.SyncStar ||
@@ -280,7 +280,7 @@
         if (!identical(statement.expression, expression)) {
           statement.expression = expression..parent = statement;
           // Not assignable, use the expectation.
-          type = greatestClosure(inferrer.coreTypes, returnOrYieldContext);
+          type = greatestClosure(returnOrYieldContext, inferrer.bottomType);
         }
       }
       DartType unwrappedType = type;
@@ -326,7 +326,7 @@
     node.expression = expression..parent = node;
     DartType type = expressionResult.inferredType;
     if (!identical(expressionResult.expression, expression)) {
-      type = greatestClosure(inferrer.coreTypes, expectedType);
+      type = greatestClosure(expectedType, inferrer.bottomType);
     }
     if (_needToInferReturnType) {
       DartType unwrappedType = type;
@@ -356,7 +356,7 @@
         returnOrYieldContext, SubtypeCheckMode.withNullabilities)) {
       // If the inferred return type isn't a subtype of the context, we use the
       // context.
-      inferredType = greatestClosure(inferrer.coreTypes, returnOrYieldContext);
+      inferredType = greatestClosure(returnOrYieldContext, inferrer.bottomType);
     }
 
     inferredType = _wrapAsyncOrGenerator(
@@ -581,6 +581,10 @@
 
   NnbdMode get nnbdMode => library.loader.nnbdMode;
 
+  DartType get bottomType => isNonNullableByDefault
+      ? const NeverType(Nullability.nonNullable)
+      : engine.coreTypes.nullType;
+
   DartType computeNullable(DartType type) {
     if (type == coreTypes.nullType || type is NeverType) {
       return coreTypes.nullType;
@@ -723,7 +727,7 @@
     if (isTopLevel) return expression;
 
     fileOffset ??= expression.fileOffset;
-    contextType = greatestClosure(coreTypes, contextType);
+    contextType = greatestClosure(contextType, bottomType);
 
     DartType initialContextType = contextType;
     if (isReturnFromAsync &&
@@ -2148,8 +2152,12 @@
     }
     if (inferenceNeeded) {
       if (isConst && typeContext != null) {
-        typeContext =
-            new TypeVariableEliminator(coreTypes).substituteType(typeContext);
+        typeContext = new TypeVariableEliminator(
+                bottomType,
+                isNonNullableByDefault
+                    ? coreTypes.objectNullableRawType
+                    : coreTypes.objectLegacyRawType)
+            .substituteType(typeContext);
       }
       inferredTypes = new List<DartType>.filled(
           calleeTypeParameters.length, const UnknownType());
@@ -2483,8 +2491,9 @@
         if (formalTypesFromContext[i] == coreTypes.nullType) {
           inferredType = coreTypes.objectRawType(library.nullable);
         } else if (formalTypesFromContext[i] != null) {
-          inferredType = greatestClosure(coreTypes,
-              substitution.substituteType(formalTypesFromContext[i]));
+          inferredType = greatestClosure(
+              substitution.substituteType(formalTypesFromContext[i]),
+              bottomType);
         } else {
           inferredType = const DynamicType();
         }
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
index 0ec091b..75e3d42 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE.md file.
 
 import 'package:kernel/ast.dart' hide MapEntry;
-import 'package:kernel/core_types.dart' show CoreTypes;
 import 'package:kernel/src/replacement_visitor.dart';
 
 import 'type_schema.dart' show UnknownType;
@@ -21,8 +20,14 @@
 ///
 /// Note that the greatest closure of a type schema is always a supertype of any
 /// type which matches the schema.
-DartType greatestClosure(CoreTypes coreTypes, DartType schema) =>
-    _TypeSchemaEliminationVisitor.run(coreTypes, false, schema);
+DartType greatestClosure(DartType schema, DartType bottomType) {
+  assert(bottomType == const NeverType(Nullability.nonNullable) ||
+      bottomType is InterfaceType &&
+          bottomType.classNode.enclosingLibrary.importUri.scheme == "dart" &&
+          bottomType.classNode.enclosingLibrary.importUri.path == "core" &&
+          bottomType.classNode.name == "Null");
+  return _TypeSchemaEliminationVisitor.run(false, schema, bottomType);
+}
 
 /// Returns the least closure of the given type [schema] with respect to `?`.
 ///
@@ -37,8 +42,14 @@
 ///
 /// Note that the least closure of a type schema is always a subtype of any type
 /// which matches the schema.
-DartType leastClosure(CoreTypes coreTypes, DartType schema) =>
-    _TypeSchemaEliminationVisitor.run(coreTypes, true, schema);
+DartType leastClosure(DartType schema, DartType bottomType) {
+  assert(bottomType == const NeverType(Nullability.nonNullable) ||
+      bottomType is InterfaceType &&
+          bottomType.classNode.enclosingLibrary.importUri.scheme == "dart" &&
+          bottomType.classNode.enclosingLibrary.importUri.path == "core" &&
+          bottomType.classNode.name == "Null");
+  return _TypeSchemaEliminationVisitor.run(true, schema, bottomType);
+}
 
 /// Visitor that computes least and greatest closures of a type schema.
 ///
@@ -46,12 +57,11 @@
 /// type, otherwise it returns the result of substituting `?` with `Null` or
 /// `Object`, as appropriate.
 class _TypeSchemaEliminationVisitor extends ReplacementVisitor {
-  final DartType nullType;
+  final DartType bottomType;
 
   bool isLeastClosure;
 
-  _TypeSchemaEliminationVisitor(CoreTypes coreTypes, this.isLeastClosure)
-      : nullType = coreTypes.nullType;
+  _TypeSchemaEliminationVisitor(this.isLeastClosure, this.bottomType);
 
   void changeVariance() {
     isLeastClosure = !isLeastClosure;
@@ -60,7 +70,7 @@
   @override
   DartType defaultDartType(DartType node) {
     if (node is UnknownType) {
-      return isLeastClosure ? nullType : const DynamicType();
+      return isLeastClosure ? bottomType : const DynamicType();
     }
     return null;
   }
@@ -69,9 +79,9 @@
   /// resulting type.  If the schema contains no instances of `?`, the original
   /// schema object is returned to avoid unnecessary allocation.
   static DartType run(
-      CoreTypes coreTypes, bool isLeastClosure, DartType schema) {
+      bool isLeastClosure, DartType schema, DartType bottomType) {
     _TypeSchemaEliminationVisitor visitor =
-        new _TypeSchemaEliminationVisitor(coreTypes, isLeastClosure);
+        new _TypeSchemaEliminationVisitor(isLeastClosure, bottomType);
     DartType result = schema.accept(visitor);
     assert(visitor.isLeastClosure == isLeastClosure);
     return result ?? schema;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index da733e7..c0a489b 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -11,6 +11,7 @@
         InterfaceType,
         Library,
         NamedType,
+        NeverType,
         Nullability,
         Procedure,
         TypeParameter,
@@ -218,7 +219,13 @@
 
     if (!isEmptyContext(returnContextType)) {
       if (isConst) {
-        returnContextType = new TypeVariableEliminator(coreTypes)
+        returnContextType = new TypeVariableEliminator(
+                clientLibrary.isNonNullableByDefault
+                    ? const NeverType(Nullability.nonNullable)
+                    : nullType,
+                clientLibrary.isNonNullableByDefault
+                    ? objectNullableRawType
+                    : objectLegacyRawType)
             .substituteType(returnContextType);
       }
       gatherer.trySubtypeMatch(declaredReturnType, returnContextType);
@@ -412,8 +419,10 @@
   /// If [isContravariant] is `true`, then we are solving for a contravariant
   /// type parameter which means we choose the upper bound rather than the
   /// lower bound for normally covariant type parameters.
-  DartType solveTypeConstraint(TypeConstraint constraint,
+  DartType solveTypeConstraint(TypeConstraint constraint, DartType bottomType,
       {bool grounded: false, bool isContravariant: false}) {
+    assert(bottomType == const NeverType(Nullability.nonNullable) ||
+        bottomType == coreTypes.nullType);
     if (!isContravariant) {
       // Prefer the known bound, if any.
       if (isKnown(constraint.lower)) return constraint.lower;
@@ -423,11 +432,11 @@
       // e.g. `Iterable<?>`
       if (constraint.lower is! UnknownType) {
         return grounded
-            ? leastClosure(coreTypes, constraint.lower)
+            ? leastClosure(constraint.lower, bottomType)
             : constraint.lower;
       } else {
         return grounded
-            ? greatestClosure(coreTypes, constraint.upper)
+            ? greatestClosure(constraint.upper, bottomType)
             : constraint.upper;
       }
     } else {
@@ -439,11 +448,11 @@
       // e.g. `Iterable<?>`
       if (constraint.upper is! UnknownType) {
         return grounded
-            ? greatestClosure(coreTypes, constraint.upper)
+            ? greatestClosure(constraint.upper, bottomType)
             : constraint.upper;
       } else {
         return grounded
-            ? leastClosure(coreTypes, constraint.lower)
+            ? leastClosure(constraint.lower, bottomType)
             : constraint.lower;
       }
     }
@@ -475,13 +484,22 @@
       addUpperBound(constraint, extendsConstraint, clientLibrary);
     }
 
-    return solveTypeConstraint(constraint,
-        grounded: true, isContravariant: isContravariant);
+    return solveTypeConstraint(
+        constraint,
+        clientLibrary.isNonNullableByDefault
+            ? const NeverType(Nullability.nonNullable)
+            : nullType,
+        grounded: true,
+        isContravariant: isContravariant);
   }
 
   DartType _inferTypeParameterFromContext(TypeConstraint constraint,
       DartType extendsConstraint, Library clientLibrary) {
-    DartType t = solveTypeConstraint(constraint);
+    DartType t = solveTypeConstraint(
+        constraint,
+        clientLibrary.isNonNullableByDefault
+            ? const NeverType(Nullability.nonNullable)
+            : nullType);
     if (!isKnown(t)) {
       return t;
     }
@@ -496,21 +514,24 @@
     if (extendsConstraint != null) {
       constraint = constraint.clone();
       addUpperBound(constraint, extendsConstraint, clientLibrary);
-      return solveTypeConstraint(constraint);
+      return solveTypeConstraint(
+          constraint,
+          clientLibrary.isNonNullableByDefault
+              ? const NeverType(Nullability.nonNullable)
+              : nullType);
     }
     return t;
   }
 }
 
 class TypeVariableEliminator extends Substitution {
-  final CoreTypes _coreTypes;
+  final DartType bottomType;
+  final DartType topType;
 
-  // TODO(dmitryas): Instead of a CoreTypes object pass null and an Object type
-  // explicitly, with the suitable nullability on the latter.
-  TypeVariableEliminator(this._coreTypes);
+  TypeVariableEliminator(this.bottomType, this.topType);
 
   @override
   DartType getSubstitute(TypeParameter parameter, bool upperBound) {
-    return upperBound ? _coreTypes.nullType : _coreTypes.objectLegacyRawType;
+    return upperBound ? bottomType : topType;
   }
 }
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index c88c6a6..3c0f84e 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -38,8 +38,12 @@
 BuiltInIdentifierInDeclaration/example: Fail
 BytecodeLimitExceededTooManyArguments/analyzerCode: Fail
 BytecodeLimitExceededTooManyArguments/example: Fail
+CannotAssignToConstVariable/analyzerCode: Fail
+CannotAssignToExtensionThis/analyzerCode: Fail
+CannotAssignToFinalVariable/analyzerCode: Fail
 CannotAssignToParenthesizedExpression/example: Fail
 CannotAssignToSuper/example: Fail
+CannotAssignToTypeLiteral/analyzerCode: Fail
 CannotReadPackagesFile/analyzerCode: Fail
 CannotReadPackagesFile/example: Fail
 CannotReadSdkSpecification/analyzerCode: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index a2740b1..9625838 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -4028,3 +4028,34 @@
   script: |
     class A extends Object with Function {}
 
+CannotAssignToFinalVariable:
+  template: "Can't assign to the final variable '#name'."
+  script: |
+     main() {
+       final int i = 0;
+       i = 42;
+     }
+
+CannotAssignToConstVariable:
+  template: "Can't assign to the const variable '#name'."
+  script: |
+    main() {
+      const int i = 0;
+      i = 42;
+    }
+
+CannotAssignToExtensionThis:
+  template: "Can't assign to 'this'."
+  script: |
+    extension E on String {
+      method() {
+        this = "";
+      }
+    }
+
+CannotAssignToTypeLiteral:
+  template: "Can't assign to a type literal."
+  script: |
+    main() {
+      Object = String;
+    }
diff --git a/pkg/front_end/test/deps_test.dart b/pkg/front_end/test/deps_test.dart
index 31c05e9..6360a93 100644
--- a/pkg/front_end/test/deps_test.dart
+++ b/pkg/front_end/test/deps_test.dart
@@ -32,6 +32,9 @@
   "third_party/pkg_tested/package_config/lib/src/packages_file.dart",
   "third_party/pkg_tested/package_config/lib/src/util.dart",
 
+  // TODO(johnniwinther): Fix to allow dependency of package:package_config.
+  "third_party/pkg_tested/package_config/lib/src/util_io.dart",
+
   // TODO(CFE-team): This file should not be included.
   // The package isn't even in pubspec.yaml.
   "pkg/meta/lib/meta.dart",
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
index cb074d6..6158ba6 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -184,11 +184,13 @@
             helper, token, prefixUseGenerator, generator));
     check(
         "ReadOnlyAccessGenerator(offset: 4, expression: expression,"
-        " plainNameForRead: foo, value: null)",
-        new ReadOnlyAccessGenerator(helper, token, expression, "foo"));
+        " plainNameForRead: foo, kind: ReadOnlyAccessKind.FinalVariable)",
+        new ReadOnlyAccessGenerator(helper, token, expression, "foo",
+            ReadOnlyAccessKind.FinalVariable));
     check(
         "ParenthesizedExpressionGenerator(offset: 4, expression: expression,"
-        " plainNameForRead: null, value: null)",
+        " plainNameForRead: null, kind:"
+        " ReadOnlyAccessKind.ParenthesizedExpression)",
         new ParenthesizedExpressionGenerator(helper, token, expression));
     check("TypeUseGenerator(offset: 4, declaration: T, plainNameForRead: foo)",
         new TypeUseGenerator(helper, token, declaration, "foo"));
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
new file mode 100644
index 0000000..b177855
--- /dev/null
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_nnbd_test.dart
@@ -0,0 +1,159 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:front_end/src/fasta/type_inference/type_schema.dart';
+import 'package:front_end/src/fasta/type_inference/type_schema_elimination.dart'
+    as typeSchemaElimination;
+import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(TypeSchemaEliminationTest);
+  });
+}
+
+@reflectiveTest
+class TypeSchemaEliminationTest {
+  static const DartType unknownType = const UnknownType();
+
+  CoreTypes coreTypes = new _MockCoreTypes();
+
+  DartType get dynamicType => const DynamicType();
+
+  DartType get nullType => coreTypes.nullType;
+
+  DartType greatestClosure(DartType schema) {
+    return typeSchemaElimination.greatestClosure(
+        schema, const NeverType(Nullability.nonNullable));
+  }
+
+  DartType leastClosure(DartType schema) {
+    return typeSchemaElimination.leastClosure(
+        schema, const NeverType(Nullability.nonNullable));
+  }
+
+  void test_greatestClosure_contravariant() {
+    expect(
+        greatestClosure(new FunctionType(
+                [unknownType], dynamicType, Nullability.legacy))
+            .leakingDebugToString(),
+        '(Never) →* dynamic');
+    expect(
+        greatestClosure(new FunctionType([], dynamicType, Nullability.legacy,
+                namedParameters: [new NamedType('foo', unknownType)]))
+            .leakingDebugToString(),
+        '({foo: Never}) →* dynamic');
+  }
+
+  void test_greatestClosure_contravariant_contravariant() {
+    expect(
+        greatestClosure(new FunctionType([
+          new FunctionType([unknownType], dynamicType, Nullability.legacy)
+        ], dynamicType, Nullability.legacy))
+            .leakingDebugToString(),
+        '((dynamic) →* dynamic) →* dynamic');
+  }
+
+  void test_greatestClosure_covariant() {
+    expect(
+        greatestClosure(new FunctionType([], unknownType, Nullability.legacy))
+            .leakingDebugToString(),
+        '() →* dynamic');
+    expect(
+        greatestClosure(new InterfaceType(
+                coreTypes.listClass, Nullability.legacy, [unknownType]))
+            .leakingDebugToString(),
+        'dart.core::List<dynamic>*');
+  }
+
+  void test_greatestClosure_function_multipleUnknown() {
+    expect(
+        greatestClosure(new FunctionType(
+            [unknownType, unknownType], unknownType, Nullability.legacy,
+            namedParameters: [
+              new NamedType('a', unknownType),
+              new NamedType('b', unknownType)
+            ])).leakingDebugToString(),
+        '(Never, Never, {a: Never, b: Never}) →* dynamic');
+  }
+
+  void test_greatestClosure_simple() {
+    expect(greatestClosure(unknownType).leakingDebugToString(), 'dynamic');
+  }
+
+  void test_leastClosure_contravariant() {
+    expect(
+        leastClosure(new FunctionType(
+                [unknownType], dynamicType, Nullability.legacy))
+            .leakingDebugToString(),
+        '(dynamic) →* dynamic');
+    expect(
+        leastClosure(new FunctionType([], dynamicType, Nullability.legacy,
+                namedParameters: [new NamedType('foo', unknownType)]))
+            .leakingDebugToString(),
+        '({foo: dynamic}) →* dynamic');
+  }
+
+  void test_leastClosure_contravariant_contravariant() {
+    expect(
+        leastClosure(new FunctionType([
+          new FunctionType([unknownType], dynamicType, Nullability.legacy)
+        ], dynamicType, Nullability.legacy))
+            .leakingDebugToString(),
+        '((Never) →* dynamic) →* dynamic');
+  }
+
+  void test_leastClosure_covariant() {
+    expect(
+        leastClosure(new FunctionType([], unknownType, Nullability.legacy))
+            .leakingDebugToString(),
+        '() →* Never');
+    expect(
+        leastClosure(new InterfaceType(
+                coreTypes.listClass, Nullability.legacy, [unknownType]))
+            .leakingDebugToString(),
+        'dart.core::List<Never>*');
+  }
+
+  void test_leastClosure_function_multipleUnknown() {
+    expect(
+        leastClosure(new FunctionType(
+            [unknownType, unknownType], unknownType, Nullability.legacy,
+            namedParameters: [
+              new NamedType('a', unknownType),
+              new NamedType('b', unknownType)
+            ])).leakingDebugToString(),
+        '(dynamic, dynamic, {a: dynamic, b: dynamic}) →* Never');
+  }
+
+  void test_leastClosure_simple() {
+    expect(leastClosure(unknownType).leakingDebugToString(), 'Never');
+  }
+}
+
+class _MockCoreTypes implements CoreTypes {
+  @override
+  final Class listClass = new Class(name: 'List');
+
+  @override
+  final Class nullClass = new Class(name: 'Null');
+
+  @override
+  final Class objectClass = new Class(name: 'Object');
+
+  @override
+  InterfaceType nullType;
+
+  _MockCoreTypes() {
+    nullType = new InterfaceType(
+        nullClass, Nullability.nullable, const <DynamicType>[]);
+    new Library(Uri.parse('dart:core'),
+        name: 'dart.core', classes: [listClass, nullClass, objectClass]);
+  }
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
index d08c6e5..c21fee9 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart
@@ -28,11 +28,13 @@
 
   DartType get objectType => coreTypes.objectLegacyRawType;
 
-  DartType greatestClosure(DartType schema) =>
-      typeSchemaElimination.greatestClosure(coreTypes, schema);
+  DartType greatestClosure(DartType schema) {
+    return typeSchemaElimination.greatestClosure(schema, nullType);
+  }
 
-  DartType leastClosure(DartType schema) =>
-      typeSchemaElimination.leastClosure(coreTypes, schema);
+  DartType leastClosure(DartType schema) {
+    return typeSchemaElimination.leastClosure(schema, nullType);
+  }
 
   void test_greatestClosure_contravariant() {
     expect(
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
index bf27d78..306c52f 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_nnbd_test.dart
@@ -39,6 +39,8 @@
 
   Class get objectClass => coreTypes.objectClass;
 
+  DartType get bottomType => const NeverType(Nullability.nonNullable);
+
   /// Converts the [text] representation of a type into a type.
   ///
   /// If [environment] is passed it's used to resolve the type terms in [text].
@@ -1051,60 +1053,72 @@
     // TODO(dmitryas): Test for various nullabilities.
 
     // Solve(? <: T <: ?) => ?
-    expect(env.solveTypeConstraint(_makeConstraint()), new UnknownType());
+    expect(env.solveTypeConstraint(_makeConstraint(), bottomType),
+        new UnknownType());
 
     // Solve(? <: T <: ?, grounded) => dynamic
-    expect(env.solveTypeConstraint(_makeConstraint(), grounded: true),
+    expect(
+        env.solveTypeConstraint(_makeConstraint(), bottomType, grounded: true),
         new DynamicType());
 
     // Solve(A <: T <: ?) => A
     expect(
-        env.solveTypeConstraint(_makeConstraint(lower: toType("A<dynamic>*"))),
+        env.solveTypeConstraint(
+            _makeConstraint(lower: toType("A<dynamic>*")), bottomType),
         toType("A<dynamic>*"));
 
     // Solve(A <: T <: ?, grounded) => A
     expect(
-        env.solveTypeConstraint(_makeConstraint(lower: toType("A<dynamic>*")),
+        env.solveTypeConstraint(
+            _makeConstraint(lower: toType("A<dynamic>*")), bottomType,
             grounded: true),
         toType("A<dynamic>*"));
 
     // Solve(A<?>* <: T <: ?) => A<?>*
     expect(
-        env.solveTypeConstraint(_makeConstraint(lower: toType("A<unknown>*"))),
+        env.solveTypeConstraint(
+            _makeConstraint(lower: toType("A<unknown>*")), bottomType),
         toType("A<unknown>*"));
 
-    // Solve(A<?>* <: T <: ?, grounded) => A<Null>*
+    // Solve(A<?>* <: T <: ?, grounded) => A<Never>*
     expect(
-        env.solveTypeConstraint(_makeConstraint(lower: toType("A<unknown>*")),
+        env.solveTypeConstraint(
+            _makeConstraint(lower: toType("A<unknown>*")), bottomType,
             grounded: true),
-        toType("A<Null>*"));
+        toType("A<Never>*"));
 
     // Solve(? <: T <: A*) => A*
     expect(
-        env.solveTypeConstraint(_makeConstraint(upper: toType("A<dynamic>*"))),
+        env.solveTypeConstraint(
+            _makeConstraint(upper: toType("A<dynamic>*")), bottomType),
         toType("A<dynamic>*"));
 
     // Solve(? <: T <: A*, grounded) => A*
     expect(
-        env.solveTypeConstraint(_makeConstraint(upper: toType("A<dynamic>*")),
+        env.solveTypeConstraint(
+            _makeConstraint(upper: toType("A<dynamic>*")), bottomType,
             grounded: true),
         toType("A<dynamic>*"));
 
     // Solve(? <: T <: A<?>*) => A<?>*
     expect(
-        env.solveTypeConstraint(_makeConstraint(upper: toType("A<unknown>*"))),
+        env.solveTypeConstraint(
+            _makeConstraint(upper: toType("A<unknown>*")), bottomType),
         toType("A<unknown>*"));
 
     // Solve(? <: T <: A<?>*, grounded) => A<dynamic>*
     expect(
-        env.solveTypeConstraint(_makeConstraint(upper: toType("A<unknown>*")),
+        env.solveTypeConstraint(
+            _makeConstraint(upper: toType("A<unknown>*")), bottomType,
             grounded: true),
         toType("A<dynamic>*"));
 
     // Solve(B* <: T <: A*) => B*
     expect(
-        env.solveTypeConstraint(_makeConstraint(
-            lower: toType("B<dynamic>*"), upper: toType("A<dynamic>*"))),
+        env.solveTypeConstraint(
+            _makeConstraint(
+                lower: toType("B<dynamic>*"), upper: toType("A<dynamic>*")),
+            bottomType),
         toType("B<dynamic>*"));
 
     // Solve(B* <: T <: A*, grounded) => B*
@@ -1112,13 +1126,16 @@
         env.solveTypeConstraint(
             _makeConstraint(
                 lower: toType("B<dynamic>*"), upper: toType("A<dynamic>*")),
+            bottomType,
             grounded: true),
         toType("B<dynamic>*"));
 
     // Solve(B<?>* <: T <: A*) => A*
     expect(
-        env.solveTypeConstraint(_makeConstraint(
-            lower: toType("B<unknown>*"), upper: toType("A<dynamic>*"))),
+        env.solveTypeConstraint(
+            _makeConstraint(
+                lower: toType("B<unknown>*"), upper: toType("A<dynamic>*")),
+            bottomType),
         toType("A<dynamic>*"));
 
     // Solve(B<?>* <: T <: A*, grounded) => A*
@@ -1126,13 +1143,16 @@
         env.solveTypeConstraint(
             _makeConstraint(
                 lower: toType("B<unknown>*"), upper: toType("A<dynamic>*")),
+            bottomType,
             grounded: true),
         toType("A<dynamic>*"));
 
     // Solve(B* <: T <: A<?>*) => B*
     expect(
-        env.solveTypeConstraint(_makeConstraint(
-            lower: toType("B<dynamic>*"), upper: toType("A<unknown>*"))),
+        env.solveTypeConstraint(
+            _makeConstraint(
+                lower: toType("B<dynamic>*"), upper: toType("A<unknown>*")),
+            bottomType),
         toType("B<dynamic>*"));
 
     // Solve(B* <: T <: A<?>*, grounded) => B*
@@ -1140,22 +1160,26 @@
         env.solveTypeConstraint(
             _makeConstraint(
                 lower: toType("B<dynamic>*"), upper: toType("A<unknown>*")),
+            bottomType,
             grounded: true),
         toType("B<dynamic>*"));
 
     // Solve(B<?>* <: T <: A<?>*) => B<?>*
     expect(
-        env.solveTypeConstraint(_makeConstraint(
-            lower: toType("B<unknown>*"), upper: toType("A<unknown>*"))),
+        env.solveTypeConstraint(
+            _makeConstraint(
+                lower: toType("B<unknown>*"), upper: toType("A<unknown>*")),
+            bottomType),
         toType("B<unknown>*"));
 
-    // Solve(B<?>* <: T <: A<?>*, grounded) => B<Null>*
+    // Solve(B<?>* <: T <: A<?>*, grounded) => B<Never>*
     expect(
         env.solveTypeConstraint(
             _makeConstraint(
                 lower: toType("B<unknown>*"), upper: toType("A<unknown>*")),
+            bottomType,
             grounded: true),
-        toType("B<Null>*"));
+        toType("B<Never>*"));
   }
 
   void test_typeConstraint_default() {
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
index 485fe51..c1c1468 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
@@ -26,8 +26,6 @@
 
   static const VoidType voidType = const VoidType();
 
-  static const BottomType bottomType = const BottomType();
-
   final testLib = new Library(Uri.parse('org-dartlang:///test.dart'));
 
   Component component;
@@ -60,6 +58,8 @@
 
   InterfaceType get objectType => coreTypes.objectLegacyRawType;
 
+  DartType get bottomType => nullType;
+
   void test_addLowerBound() {
     var A = coreTypes.legacyRawType(_addClass(_class('A')));
     var B = coreTypes.legacyRawType(
@@ -91,14 +91,16 @@
     env.addUpperBound(typeConstraint, B, testLib);
     expect(typeConstraint.upper, same(B));
     env.addUpperBound(typeConstraint, C, testLib);
-    expect(typeConstraint.upper, same(bottomType));
+    expect(typeConstraint.upper, new BottomType());
   }
 
   void test_glb_bottom() {
     var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
     var env = _makeEnv();
-    expect(env.getStandardLowerBound(bottomType, A, testLib), same(bottomType));
-    expect(env.getStandardLowerBound(A, bottomType, testLib), same(bottomType));
+    expect(env.getStandardLowerBound(new BottomType(), A, testLib),
+        new BottomType());
+    expect(env.getStandardLowerBound(A, new BottomType(), testLib),
+        new BottomType());
   }
 
   void test_glb_function() {
@@ -229,7 +231,7 @@
                 namedParameters: [new NamedType('a', A)]),
             new FunctionType([B], voidType, Nullability.legacy),
             testLib),
-        same(bottomType));
+        new BottomType());
     // GLB(({a: A}) -> void, ([B]) -> void) = bottom
     expect(
         env.getStandardLowerBound(
@@ -238,7 +240,7 @@
             new FunctionType([B], voidType, Nullability.legacy,
                 requiredParameterCount: 0),
             testLib),
-        same(bottomType));
+        new BottomType());
   }
 
   void test_glb_identical() {
@@ -283,7 +285,7 @@
     var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
     var B = coreTypes.rawType(_addClass(_class('B')), Nullability.legacy);
     var env = _makeEnv();
-    expect(env.getStandardLowerBound(A, B, testLib), same(bottomType));
+    expect(env.getStandardLowerBound(A, B, testLib), new BottomType());
   }
 
   void test_inferGenericFunctionOrType() {
@@ -605,14 +607,14 @@
     var T = new TypeParameterType(new TypeParameter('T'), Nullability.legacy);
     T.parameter.bound = _list(T);
     var U = new TypeParameterType(new TypeParameter('U'), Nullability.legacy);
-    U.parameter.bound = _list(bottomType);
+    U.parameter.bound = _list(new BottomType());
     var env = _makeEnv();
     // LUB(T, T) = T
     expect(env.getStandardUpperBound(T, T, testLib), same(T));
     // LUB(T, List<Bottom>) = LUB(List<Object>, List<Bottom>) = List<Object>
-    expect(env.getStandardUpperBound(T, _list(bottomType), testLib),
+    expect(env.getStandardUpperBound(T, _list(new BottomType()), testLib),
         _list(objectType));
-    expect(env.getStandardUpperBound(_list(bottomType), T, testLib),
+    expect(env.getStandardUpperBound(_list(new BottomType()), T, testLib),
         _list(objectType));
     // LUB(T, U) = LUB(List<Object>, U) = LUB(List<Object>, List<Bottom>)
     // = List<Object>
@@ -634,20 +636,26 @@
         Nullability.legacy);
     var env = _makeEnv();
     // Solve(? <: T <: ?) => ?
-    expect(env.solveTypeConstraint(_makeConstraint()), same(unknownType));
+    expect(env.solveTypeConstraint(_makeConstraint(), bottomType),
+        same(unknownType));
     // Solve(? <: T <: ?, grounded) => dynamic
-    expect(env.solveTypeConstraint(_makeConstraint(), grounded: true),
+    expect(
+        env.solveTypeConstraint(_makeConstraint(), bottomType, grounded: true),
         dynamicType);
     // Solve(A <: T <: ?) => A
-    expect(env.solveTypeConstraint(_makeConstraint(lower: A)), A);
+    expect(env.solveTypeConstraint(_makeConstraint(lower: A), bottomType), A);
     // Solve(A <: T <: ?, grounded) => A
     expect(
-        env.solveTypeConstraint(_makeConstraint(lower: A), grounded: true), A);
+        env.solveTypeConstraint(_makeConstraint(lower: A), bottomType,
+            grounded: true),
+        A);
     // Solve(A<?> <: T <: ?) => A<?>
     expect(
-        env.solveTypeConstraint(_makeConstraint(
-            lower: new InterfaceType(
-                A.classNode, Nullability.legacy, [unknownType]))),
+        env.solveTypeConstraint(
+            _makeConstraint(
+                lower: new InterfaceType(
+                    A.classNode, Nullability.legacy, [unknownType])),
+            bottomType),
         new InterfaceType(A.classNode, Nullability.legacy, [unknownType]));
     // Solve(A<?> <: T <: ?, grounded) => A<Null>
     expect(
@@ -655,18 +663,23 @@
             _makeConstraint(
                 lower: new InterfaceType(
                     A.classNode, Nullability.legacy, [unknownType])),
+            bottomType,
             grounded: true),
         new InterfaceType(A.classNode, Nullability.legacy, [nullType]));
     // Solve(? <: T <: A) => A
-    expect(env.solveTypeConstraint(_makeConstraint(upper: A)), A);
+    expect(env.solveTypeConstraint(_makeConstraint(upper: A), bottomType), A);
     // Solve(? <: T <: A, grounded) => A
     expect(
-        env.solveTypeConstraint(_makeConstraint(upper: A), grounded: true), A);
+        env.solveTypeConstraint(_makeConstraint(upper: A), bottomType,
+            grounded: true),
+        A);
     // Solve(? <: T <: A<?>) => A<?>
     expect(
-        env.solveTypeConstraint(_makeConstraint(
-            upper: new InterfaceType(
-                A.classNode, Nullability.legacy, [unknownType]))),
+        env.solveTypeConstraint(
+            _makeConstraint(
+                upper: new InterfaceType(
+                    A.classNode, Nullability.legacy, [unknownType])),
+            bottomType),
         new InterfaceType(A.classNode, Nullability.legacy, [unknownType]));
     // Solve(? <: T <: A<?>, grounded) => A<dynamic>
     expect(
@@ -674,21 +687,27 @@
             _makeConstraint(
                 upper: new InterfaceType(
                     A.classNode, Nullability.legacy, [unknownType])),
+            bottomType,
             grounded: true),
         new InterfaceType(A.classNode, Nullability.legacy, [dynamicType]));
     // Solve(B <: T <: A) => B
-    expect(env.solveTypeConstraint(_makeConstraint(lower: B, upper: A)), B);
+    expect(
+        env.solveTypeConstraint(
+            _makeConstraint(lower: B, upper: A), bottomType),
+        B);
     // Solve(B <: T <: A, grounded) => B
     expect(
-        env.solveTypeConstraint(_makeConstraint(lower: B, upper: A),
+        env.solveTypeConstraint(_makeConstraint(lower: B, upper: A), bottomType,
             grounded: true),
         B);
     // Solve(B<?> <: T <: A) => A
     expect(
-        env.solveTypeConstraint(_makeConstraint(
-            lower: new InterfaceType(
-                B.classNode, Nullability.legacy, [unknownType]),
-            upper: A)),
+        env.solveTypeConstraint(
+            _makeConstraint(
+                lower: new InterfaceType(
+                    B.classNode, Nullability.legacy, [unknownType]),
+                upper: A),
+            bottomType),
         A);
     // Solve(B<?> <: T <: A, grounded) => A
     expect(
@@ -697,14 +716,17 @@
                 lower: new InterfaceType(
                     B.classNode, Nullability.legacy, [unknownType]),
                 upper: A),
+            bottomType,
             grounded: true),
         A);
     // Solve(B <: T <: A<?>) => B
     expect(
-        env.solveTypeConstraint(_makeConstraint(
-            lower: B,
-            upper: new InterfaceType(
-                A.classNode, Nullability.legacy, [unknownType]))),
+        env.solveTypeConstraint(
+            _makeConstraint(
+                lower: B,
+                upper: new InterfaceType(
+                    A.classNode, Nullability.legacy, [unknownType])),
+            bottomType),
         B);
     // Solve(B <: T <: A<?>, grounded) => B
     expect(
@@ -713,15 +735,18 @@
                 lower: B,
                 upper: new InterfaceType(
                     A.classNode, Nullability.legacy, [unknownType])),
+            bottomType,
             grounded: true),
         B);
     // Solve(B<?> <: T <: A<?>) => B<?>
     expect(
-        env.solveTypeConstraint(_makeConstraint(
-            lower: new InterfaceType(
-                B.classNode, Nullability.legacy, [unknownType]),
-            upper: new InterfaceType(
-                A.classNode, Nullability.legacy, [unknownType]))),
+        env.solveTypeConstraint(
+            _makeConstraint(
+                lower: new InterfaceType(
+                    B.classNode, Nullability.legacy, [unknownType]),
+                upper: new InterfaceType(
+                    A.classNode, Nullability.legacy, [unknownType])),
+            bottomType),
         new InterfaceType(B.classNode, Nullability.legacy, [unknownType]));
     // Solve(B<?> <: T <: A<?>) => B<Null>
     expect(
@@ -731,6 +756,7 @@
                     B.classNode, Nullability.legacy, [unknownType]),
                 upper: new InterfaceType(
                     A.classNode, Nullability.legacy, [unknownType])),
+            bottomType,
             grounded: true),
         new InterfaceType(B.classNode, Nullability.legacy, [nullType]));
   }
diff --git a/pkg/front_end/test/language_versioning/data/language_version_in_packages/lib/foo.dart b/pkg/front_end/test/language_versioning/data/language_version_in_packages/lib/foo.dart
index 0f5e6ce..6d45456 100644
--- a/pkg/front_end/test/language_versioning/data/language_version_in_packages/lib/foo.dart
+++ b/pkg/front_end/test/language_versioning/data/language_version_in_packages/lib/foo.dart
@@ -1,4 +1,4 @@
-/*library: languageVersion=2.8*/
+/*library: languageVersion=2.7*/
 
 String foo() {
   return "42";
diff --git a/pkg/front_end/test/language_versioning/data/specified_packages_02/foo1/foo.dart b/pkg/front_end/test/language_versioning/data/specified_packages_02/foo1/foo.dart
index bb0fb7c..2873e02 100644
--- a/pkg/front_end/test/language_versioning/data/specified_packages_02/foo1/foo.dart
+++ b/pkg/front_end/test/language_versioning/data/specified_packages_02/foo1/foo.dart
@@ -1,4 +1,4 @@
-/*library: languageVersion=2.8*/
+/*library: languageVersion=2.7*/
 
 int notNamedFoo() {
   return 42;
diff --git a/pkg/front_end/test/scanner_fasta_test.dart b/pkg/front_end/test/scanner_fasta_test.dart
index 10a6dc6..ea17792 100644
--- a/pkg/front_end/test/scanner_fasta_test.dart
+++ b/pkg/front_end/test/scanner_fasta_test.dart
@@ -755,10 +755,10 @@
 /// Scanner tests that exercise the Fasta scanner directly.
 @reflectiveTest
 class ScannerTest_Fasta_Direct extends ScannerTest_Fasta_Base {
-  LanguageVersionToken languageVersion;
+  fasta.LanguageVersionToken languageVersion;
 
   void languageVersionChanged(
-      Scanner scanner, LanguageVersionToken languageVersion) {
+      Scanner scanner, fasta.LanguageVersionToken languageVersion) {
     this.languageVersion = languageVersion;
   }
 
@@ -972,11 +972,11 @@
     token = token.precedingComments;
     while (token != null) {
       if (index == versionIndex) {
-        if (token is! LanguageVersionToken) {
+        if (token is! fasta.LanguageVersionToken) {
           fail('Expected version comment at index $index');
         }
       } else {
-        if (token is LanguageVersionToken) {
+        if (token is fasta.LanguageVersionToken) {
           fail('Did not expect version comment at index $index');
         }
       }
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 2e71a8a..c71b67c 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -1809,6 +1809,7 @@
 mismatch
 mismatches
 missing
+misused
 mix
 mixed
 mixes
diff --git a/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.strong.expect b/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.strong.expect
index 952e217..bc6bd68 100644
--- a/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.strong.expect
+++ b/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.strong.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general/assign_to_initializing_formal.dart:13:11: Error: Setter not found: 'x'.
+// pkg/front_end/testcases/general/assign_to_initializing_formal.dart:13:11: Error: Can't assign to the final variable 'x'.
 //           x = 3;
 //           ^
 //
@@ -16,7 +16,7 @@
   field dynamic y;
   constructor •(dynamic x) → self::A*
     : self::A::x = x, self::A::y = () → core::Null? {
-      invalid-expression "pkg/front_end/testcases/general/assign_to_initializing_formal.dart:13:11: Error: Setter not found: 'x'.
+      invalid-expression "pkg/front_end/testcases/general/assign_to_initializing_formal.dart:13:11: Error: Can't assign to the final variable 'x'.
           x = 3;
           ^";
     }, super core::Object::•()
diff --git a/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.strong.transformed.expect b/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.strong.transformed.expect
index 952e217..bc6bd68 100644
--- a/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/assign_to_initializing_formal.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general/assign_to_initializing_formal.dart:13:11: Error: Setter not found: 'x'.
+// pkg/front_end/testcases/general/assign_to_initializing_formal.dart:13:11: Error: Can't assign to the final variable 'x'.
 //           x = 3;
 //           ^
 //
@@ -16,7 +16,7 @@
   field dynamic y;
   constructor •(dynamic x) → self::A*
     : self::A::x = x, self::A::y = () → core::Null? {
-      invalid-expression "pkg/front_end/testcases/general/assign_to_initializing_formal.dart:13:11: Error: Setter not found: 'x'.
+      invalid-expression "pkg/front_end/testcases/general/assign_to_initializing_formal.dart:13:11: Error: Can't assign to the final variable 'x'.
           x = 3;
           ^";
     }, super core::Object::•()
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
index 70902fb..20225c7 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.expect
@@ -180,15 +180,15 @@
 //   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
 //                                                                               ^
 //
-// pkg/front_end/testcases/general/control_flow_collection_inference.dart:230:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general/control_flow_collection_inference.dart:230:14: Error: Can't assign to the final variable 'i'.
 //   <int>[for (i in <int>[1]) i];
 //              ^
 //
-// pkg/front_end/testcases/general/control_flow_collection_inference.dart:231:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general/control_flow_collection_inference.dart:231:14: Error: Can't assign to the final variable 'i'.
 //   <int>{for (i in <int>[1]) i, null};
 //              ^
 //
-// pkg/front_end/testcases/general/control_flow_collection_inference.dart:232:21: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general/control_flow_collection_inference.dart:232:21: Error: Can't assign to the final variable 'i'.
 // 	<String, int>{for (i in <int>[1]) "bar": i, "baz": null};
 // 	                   ^
 //
@@ -1991,7 +1991,7 @@
   block {
     final core::List<core::int*>* #t376 = <core::int*>[];
     for (final core::int* #t377 in <core::int*>[1]) {
-      invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:230:14: Error: Setter not found: 'i'.
+      invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:230:14: Error: Can't assign to the final variable 'i'.
   <int>[for (i in <int>[1]) i];
              ^";
       #t376.{core::List::add}(i);
@@ -2000,7 +2000,7 @@
   block {
     final core::Set<core::int*>* #t378 = col::LinkedHashSet::•<core::int*>();
     for (final core::int* #t379 in <core::int*>[1]) {
-      invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:231:14: Error: Setter not found: 'i'.
+      invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:231:14: Error: Can't assign to the final variable 'i'.
   <int>{for (i in <int>[1]) i, null};
              ^";
       #t378.{core::Set::add}(i);
@@ -2010,7 +2010,7 @@
   block {
     final core::Map<core::String*, core::int*>* #t380 = <core::String*, core::int*>{};
     for (final core::int* #t381 in <core::int*>[1]) {
-      invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:232:21: Error: Setter not found: 'i'.
+      invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:232:21: Error: Can't assign to the final variable 'i'.
 \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null};
 \t                   ^";
       #t380.{core::Map::[]=}("bar", i);
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
index 6dbb29f..1c89f63 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
@@ -180,15 +180,15 @@
 //   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
 //                                                                               ^
 //
-// pkg/front_end/testcases/general/control_flow_collection_inference.dart:230:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general/control_flow_collection_inference.dart:230:14: Error: Can't assign to the final variable 'i'.
 //   <int>[for (i in <int>[1]) i];
 //              ^
 //
-// pkg/front_end/testcases/general/control_flow_collection_inference.dart:231:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general/control_flow_collection_inference.dart:231:14: Error: Can't assign to the final variable 'i'.
 //   <int>{for (i in <int>[1]) i, null};
 //              ^
 //
-// pkg/front_end/testcases/general/control_flow_collection_inference.dart:232:21: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general/control_flow_collection_inference.dart:232:21: Error: Can't assign to the final variable 'i'.
 // 	<String, int>{for (i in <int>[1]) "bar": i, "baz": null};
 // 	                   ^
 //
@@ -2523,7 +2523,7 @@
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t377 = :sync-for-iterator.{core::Iterator::current};
               {
-                invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:230:14: Error: Setter not found: 'i'.
+                invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:230:14: Error: Can't assign to the final variable 'i'.
   <int>[for (i in <int>[1]) i];
              ^";
                 #t376.{core::List::add}(i);
@@ -2538,7 +2538,7 @@
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t379 = :sync-for-iterator.{core::Iterator::current};
               {
-                invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:231:14: Error: Setter not found: 'i'.
+                invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:231:14: Error: Can't assign to the final variable 'i'.
   <int>{for (i in <int>[1]) i, null};
              ^";
                 #t378.{core::Set::add}(i);
@@ -2554,7 +2554,7 @@
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t381 = :sync-for-iterator.{core::Iterator::current};
               {
-                invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:232:21: Error: Setter not found: 'i'.
+                invalid-expression "pkg/front_end/testcases/general/control_flow_collection_inference.dart:232:21: Error: Can't assign to the final variable 'i'.
 \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null};
 \t                   ^";
                 #t380.{core::Map::[]=}("bar", i);
diff --git a/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.expect b/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.expect
index 6916586..2f15de1 100644
--- a/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.expect
+++ b/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.expect
@@ -42,7 +42,7 @@
 //     for (var x, y in <int>[]) {
 //          ^^^
 //
-// pkg/front_end/testcases/general/for_in_without_declaration.dart:46:10: Error: Setter not found: 'constant'.
+// pkg/front_end/testcases/general/for_in_without_declaration.dart:46:10: Error: Can't assign to the const variable 'constant'.
 //     for (constant in []) {}
 //          ^^^^^^^^
 //
@@ -169,7 +169,7 @@
       }
     }
     for (final dynamic #t18 in <dynamic>[]) {
-      invalid-expression "pkg/front_end/testcases/general/for_in_without_declaration.dart:46:10: Error: Setter not found: 'constant'.
+      invalid-expression "pkg/front_end/testcases/general/for_in_without_declaration.dart:46:10: Error: Can't assign to the const variable 'constant'.
     for (constant in []) {}
          ^^^^^^^^";
     }
diff --git a/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.transformed.expect
index 0571257..e6b4f0c 100644
--- a/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/for_in_without_declaration.dart.strong.transformed.expect
@@ -42,7 +42,7 @@
 //     for (var x, y in <int>[]) {
 //          ^^^
 //
-// pkg/front_end/testcases/general/for_in_without_declaration.dart:46:10: Error: Setter not found: 'constant'.
+// pkg/front_end/testcases/general/for_in_without_declaration.dart:46:10: Error: Can't assign to the const variable 'constant'.
 //     for (constant in []) {}
 //          ^^^^^^^^
 //
@@ -276,7 +276,7 @@
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t18 = :sync-for-iterator.{core::Iterator::current};
         {
-          invalid-expression "pkg/front_end/testcases/general/for_in_without_declaration.dart:46:10: Error: Setter not found: 'constant'.
+          invalid-expression "pkg/front_end/testcases/general/for_in_without_declaration.dart:46:10: Error: Can't assign to the const variable 'constant'.
     for (constant in []) {}
          ^^^^^^^^";
         }
diff --git a/pkg/front_end/testcases/general/issue40242.dart b/pkg/front_end/testcases/general/issue40242.dart
new file mode 100644
index 0000000..afd8f73
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40242.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class C {}
+
+extension E on C {
+  errors() {
+    this = new C();
+  }
+}
+
+errors() {
+  final C c1 = new C();
+  c1 = new C();
+  C = Object;
+  C c2;
+  (c2) = new C();
+  const c3 = Object;
+  c3 = null;
+}
+
+main() {}
\ No newline at end of file
diff --git a/pkg/front_end/testcases/general/issue40242.dart.outline.expect b/pkg/front_end/testcases/general/issue40242.dart.outline.expect
new file mode 100644
index 0000000..8ca29ac
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40242.dart.outline.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self::C*
+    ;
+}
+extension E on self::C* {
+  method errors = self::E|errors;
+  tearoff errors = self::E|get#errors;
+}
+static method E|errors(final self::C* #this) → dynamic
+  ;
+static method E|get#errors(final self::C* #this) → () →* dynamic
+  return () → dynamic => self::E|errors(#this);
+static method errors() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/general/issue40242.dart.strong.expect b/pkg/front_end/testcases/general/issue40242.dart.strong.expect
new file mode 100644
index 0000000..3fb02b3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40242.dart.strong.expect
@@ -0,0 +1,60 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue40242.dart:9:5: Error: Can't assign to 'this'.
+//     this = new C();
+//     ^^^^
+//
+// pkg/front_end/testcases/general/issue40242.dart:15:3: Error: Can't assign to the final variable 'c1'.
+//   c1 = new C();
+//   ^^
+//
+// pkg/front_end/testcases/general/issue40242.dart:16:3: Error: Can't assign to a type literal.
+//   C = Object;
+//   ^
+//
+// pkg/front_end/testcases/general/issue40242.dart:18:6: Error: Can't assign to a parenthesized expression.
+//   (c2) = new C();
+//      ^
+//
+// pkg/front_end/testcases/general/issue40242.dart:20:3: Error: Can't assign to the const variable 'c3'.
+//   c3 = null;
+//   ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self::C*
+    : super core::Object::•()
+    ;
+}
+extension E on self::C* {
+  method errors = self::E|errors;
+  tearoff errors = self::E|get#errors;
+}
+static method E|errors(final self::C* #this) → dynamic {
+  invalid-expression "pkg/front_end/testcases/general/issue40242.dart:9:5: Error: Can't assign to 'this'.
+    this = new C();
+    ^^^^";
+}
+static method E|get#errors(final self::C* #this) → () →* dynamic
+  return () → dynamic => self::E|errors(#this);
+static method errors() → dynamic {
+  final self::C* c1 = new self::C::•();
+  invalid-expression "pkg/front_end/testcases/general/issue40242.dart:15:3: Error: Can't assign to the final variable 'c1'.
+  c1 = new C();
+  ^^";
+  invalid-expression "pkg/front_end/testcases/general/issue40242.dart:16:3: Error: Can't assign to a type literal.
+  C = Object;
+  ^";
+  self::C* c2;
+  invalid-expression "pkg/front_end/testcases/general/issue40242.dart:18:6: Error: Can't assign to a parenthesized expression.
+  (c2) = new C();
+     ^";
+  invalid-expression "pkg/front_end/testcases/general/issue40242.dart:20:3: Error: Can't assign to the const variable 'c3'.
+  c3 = null;
+  ^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue40242.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue40242.dart.strong.transformed.expect
new file mode 100644
index 0000000..3fb02b3
--- /dev/null
+++ b/pkg/front_end/testcases/general/issue40242.dart.strong.transformed.expect
@@ -0,0 +1,60 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/issue40242.dart:9:5: Error: Can't assign to 'this'.
+//     this = new C();
+//     ^^^^
+//
+// pkg/front_end/testcases/general/issue40242.dart:15:3: Error: Can't assign to the final variable 'c1'.
+//   c1 = new C();
+//   ^^
+//
+// pkg/front_end/testcases/general/issue40242.dart:16:3: Error: Can't assign to a type literal.
+//   C = Object;
+//   ^
+//
+// pkg/front_end/testcases/general/issue40242.dart:18:6: Error: Can't assign to a parenthesized expression.
+//   (c2) = new C();
+//      ^
+//
+// pkg/front_end/testcases/general/issue40242.dart:20:3: Error: Can't assign to the const variable 'c3'.
+//   c3 = null;
+//   ^^
+//
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → self::C*
+    : super core::Object::•()
+    ;
+}
+extension E on self::C* {
+  method errors = self::E|errors;
+  tearoff errors = self::E|get#errors;
+}
+static method E|errors(final self::C* #this) → dynamic {
+  invalid-expression "pkg/front_end/testcases/general/issue40242.dart:9:5: Error: Can't assign to 'this'.
+    this = new C();
+    ^^^^";
+}
+static method E|get#errors(final self::C* #this) → () →* dynamic
+  return () → dynamic => self::E|errors(#this);
+static method errors() → dynamic {
+  final self::C* c1 = new self::C::•();
+  invalid-expression "pkg/front_end/testcases/general/issue40242.dart:15:3: Error: Can't assign to the final variable 'c1'.
+  c1 = new C();
+  ^^";
+  invalid-expression "pkg/front_end/testcases/general/issue40242.dart:16:3: Error: Can't assign to a type literal.
+  C = Object;
+  ^";
+  self::C* c2;
+  invalid-expression "pkg/front_end/testcases/general/issue40242.dart:18:6: Error: Can't assign to a parenthesized expression.
+  (c2) = new C();
+     ^";
+  invalid-expression "pkg/front_end/testcases/general/issue40242.dart:20:3: Error: Can't assign to the const variable 'c3'.
+  c3 = null;
+  ^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.strong.expect b/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.strong.expect
index ec1126c..5ebdcbd 100644
--- a/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.strong.expect
+++ b/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.strong.expect
@@ -26,5 +26,5 @@
 static method main() → dynamic {}
 
 constants  {
-  #C1 = null
+  #C1 = 0
 }
diff --git a/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.strong.transformed.expect b/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.strong.transformed.expect
index ec1126c..5ebdcbd 100644
--- a/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/nested_implicit_const_with_env_var.dart.strong.transformed.expect
@@ -26,5 +26,5 @@
 static method main() → dynamic {}
 
 constants  {
-  #C1 = null
+  #C1 = 0
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.strong.expect b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.strong.expect
index 79dad5a..9f6e9be 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.strong.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.strong.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Setter not found: 'x'.
+// pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Can't assign to the final variable 'x'.
 //           x = 3;
 //           ^
 //
@@ -16,7 +16,7 @@
   field dynamic y;
   constructor •(dynamic x) → self::A*
     : self::A::x = x, self::A::y = () → core::Null? {
-      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Setter not found: 'x'.
+      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Can't assign to the final variable 'x'.
           x = 3;
           ^";
     }, super core::Object::•()
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.strong.transformed.expect
index 79dad5a..9f6e9be 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Setter not found: 'x'.
+// pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Can't assign to the final variable 'x'.
 //           x = 3;
 //           ^
 //
@@ -16,7 +16,7 @@
   field dynamic y;
   constructor •(dynamic x) → self::A*
     : self::A::x = x, self::A::y = () → core::Null? {
-      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Setter not found: 'x'.
+      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Can't assign to the final variable 'x'.
           x = 3;
           ^";
     }, super core::Object::•()
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.weak.expect
index 79dad5a..9f6e9be 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.weak.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Setter not found: 'x'.
+// pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Can't assign to the final variable 'x'.
 //           x = 3;
 //           ^
 //
@@ -16,7 +16,7 @@
   field dynamic y;
   constructor •(dynamic x) → self::A*
     : self::A::x = x, self::A::y = () → core::Null? {
-      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Setter not found: 'x'.
+      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Can't assign to the final variable 'x'.
           x = 3;
           ^";
     }, super core::Object::•()
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.weak.transformed.expect
index 79dad5a..9f6e9be 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart.weak.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Setter not found: 'x'.
+// pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Can't assign to the final variable 'x'.
 //           x = 3;
 //           ^
 //
@@ -16,7 +16,7 @@
   field dynamic y;
   constructor •(dynamic x) → self::A*
     : self::A::x = x, self::A::y = () → core::Null? {
-      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Setter not found: 'x'.
+      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/assign_to_initializing_formal.dart:15:11: Error: Can't assign to the final variable 'x'.
           x = 3;
           ^";
     }, super core::Object::•()
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.strong.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.strong.expect
index 2c46fb9..741f33f 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.strong.expect
@@ -180,15 +180,15 @@
 //   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
 //                                                                               ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Can't assign to the final variable 'i'.
 //   <int>[for (i in <int>[1]) i];
 //              ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Can't assign to the final variable 'i'.
 //   <int>{for (i in <int>[1]) i, null};
 //              ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Can't assign to the final variable 'i'.
 // 	<String, int>{for (i in <int>[1]) "bar": i, "baz": null};
 // 	                   ^
 //
@@ -1991,7 +1991,7 @@
   block {
     final core::List<core::int*>* #t376 = <core::int*>[];
     for (final core::int* #t377 in <core::int*>[1]) {
-      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Setter not found: 'i'.
+      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Can't assign to the final variable 'i'.
   <int>[for (i in <int>[1]) i];
              ^";
       #t376.{core::List::add}(i);
@@ -2000,7 +2000,7 @@
   block {
     final core::Set<core::int*>* #t378 = col::LinkedHashSet::•<core::int*>();
     for (final core::int* #t379 in <core::int*>[1]) {
-      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Setter not found: 'i'.
+      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Can't assign to the final variable 'i'.
   <int>{for (i in <int>[1]) i, null};
              ^";
       #t378.{core::Set::add}(i);
@@ -2010,7 +2010,7 @@
   block {
     final core::Map<core::String*, core::int*>* #t380 = <core::String*, core::int*>{};
     for (final core::int* #t381 in <core::int*>[1]) {
-      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Setter not found: 'i'.
+      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Can't assign to the final variable 'i'.
 \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null};
 \t                   ^";
       #t380.{core::Map::[]=}("bar", i);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.strong.transformed.expect
index dfec04b..4dce82d 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.strong.transformed.expect
@@ -180,15 +180,15 @@
 //   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
 //                                                                               ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Can't assign to the final variable 'i'.
 //   <int>[for (i in <int>[1]) i];
 //              ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Can't assign to the final variable 'i'.
 //   <int>{for (i in <int>[1]) i, null};
 //              ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Can't assign to the final variable 'i'.
 // 	<String, int>{for (i in <int>[1]) "bar": i, "baz": null};
 // 	                   ^
 //
@@ -2523,7 +2523,7 @@
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t377 = :sync-for-iterator.{core::Iterator::current};
               {
-                invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Setter not found: 'i'.
+                invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Can't assign to the final variable 'i'.
   <int>[for (i in <int>[1]) i];
              ^";
                 #t376.{core::List::add}(i);
@@ -2538,7 +2538,7 @@
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t379 = :sync-for-iterator.{core::Iterator::current};
               {
-                invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Setter not found: 'i'.
+                invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Can't assign to the final variable 'i'.
   <int>{for (i in <int>[1]) i, null};
              ^";
                 #t378.{core::Set::add}(i);
@@ -2554,7 +2554,7 @@
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t381 = :sync-for-iterator.{core::Iterator::current};
               {
-                invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Setter not found: 'i'.
+                invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Can't assign to the final variable 'i'.
 \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null};
 \t                   ^";
                 #t380.{core::Map::[]=}("bar", i);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.expect
index 2c46fb9..741f33f 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.expect
@@ -180,15 +180,15 @@
 //   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
 //                                                                               ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Can't assign to the final variable 'i'.
 //   <int>[for (i in <int>[1]) i];
 //              ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Can't assign to the final variable 'i'.
 //   <int>{for (i in <int>[1]) i, null};
 //              ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Can't assign to the final variable 'i'.
 // 	<String, int>{for (i in <int>[1]) "bar": i, "baz": null};
 // 	                   ^
 //
@@ -1991,7 +1991,7 @@
   block {
     final core::List<core::int*>* #t376 = <core::int*>[];
     for (final core::int* #t377 in <core::int*>[1]) {
-      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Setter not found: 'i'.
+      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Can't assign to the final variable 'i'.
   <int>[for (i in <int>[1]) i];
              ^";
       #t376.{core::List::add}(i);
@@ -2000,7 +2000,7 @@
   block {
     final core::Set<core::int*>* #t378 = col::LinkedHashSet::•<core::int*>();
     for (final core::int* #t379 in <core::int*>[1]) {
-      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Setter not found: 'i'.
+      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Can't assign to the final variable 'i'.
   <int>{for (i in <int>[1]) i, null};
              ^";
       #t378.{core::Set::add}(i);
@@ -2010,7 +2010,7 @@
   block {
     final core::Map<core::String*, core::int*>* #t380 = <core::String*, core::int*>{};
     for (final core::int* #t381 in <core::int*>[1]) {
-      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Setter not found: 'i'.
+      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Can't assign to the final variable 'i'.
 \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null};
 \t                   ^";
       #t380.{core::Map::[]=}("bar", i);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect
index dfec04b..4dce82d 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect
@@ -180,15 +180,15 @@
 //   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
 //                                                                               ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Can't assign to the final variable 'i'.
 //   <int>[for (i in <int>[1]) i];
 //              ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Can't assign to the final variable 'i'.
 //   <int>{for (i in <int>[1]) i, null};
 //              ^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Can't assign to the final variable 'i'.
 // 	<String, int>{for (i in <int>[1]) "bar": i, "baz": null};
 // 	                   ^
 //
@@ -2523,7 +2523,7 @@
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t377 = :sync-for-iterator.{core::Iterator::current};
               {
-                invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Setter not found: 'i'.
+                invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:232:14: Error: Can't assign to the final variable 'i'.
   <int>[for (i in <int>[1]) i];
              ^";
                 #t376.{core::List::add}(i);
@@ -2538,7 +2538,7 @@
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t379 = :sync-for-iterator.{core::Iterator::current};
               {
-                invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Setter not found: 'i'.
+                invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:233:14: Error: Can't assign to the final variable 'i'.
   <int>{for (i in <int>[1]) i, null};
              ^";
                 #t378.{core::Set::add}(i);
@@ -2554,7 +2554,7 @@
             for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
               final core::int* #t381 = :sync-for-iterator.{core::Iterator::current};
               {
-                invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Setter not found: 'i'.
+                invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart:234:21: Error: Can't assign to the final variable 'i'.
 \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null};
 \t                   ^";
                 #t380.{core::Map::[]=}("bar", i);
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.strong.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.strong.expect
index 52ab4ce..4ae3cff 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.strong.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.strong.expect
@@ -42,7 +42,7 @@
 //     for (var x, y in <int>[]) {
 //          ^^^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Setter not found: 'constant'.
+// pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Can't assign to the const variable 'constant'.
 //     for (constant in []) {}
 //          ^^^^^^^^
 //
@@ -169,7 +169,7 @@
       }
     }
     for (final dynamic #t18 in <dynamic>[]) {
-      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Setter not found: 'constant'.
+      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Can't assign to the const variable 'constant'.
     for (constant in []) {}
          ^^^^^^^^";
     }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.strong.transformed.expect
index 9ce4417..220fbaa 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.strong.transformed.expect
@@ -42,7 +42,7 @@
 //     for (var x, y in <int>[]) {
 //          ^^^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Setter not found: 'constant'.
+// pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Can't assign to the const variable 'constant'.
 //     for (constant in []) {}
 //          ^^^^^^^^
 //
@@ -276,7 +276,7 @@
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t18 = :sync-for-iterator.{core::Iterator::current};
         {
-          invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Setter not found: 'constant'.
+          invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Can't assign to the const variable 'constant'.
     for (constant in []) {}
          ^^^^^^^^";
         }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.weak.expect
index 52ab4ce..4ae3cff 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.weak.expect
@@ -42,7 +42,7 @@
 //     for (var x, y in <int>[]) {
 //          ^^^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Setter not found: 'constant'.
+// pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Can't assign to the const variable 'constant'.
 //     for (constant in []) {}
 //          ^^^^^^^^
 //
@@ -169,7 +169,7 @@
       }
     }
     for (final dynamic #t18 in <dynamic>[]) {
-      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Setter not found: 'constant'.
+      invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Can't assign to the const variable 'constant'.
     for (constant in []) {}
          ^^^^^^^^";
     }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.weak.transformed.expect
index 9ce4417..220fbaa 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart.weak.transformed.expect
@@ -42,7 +42,7 @@
 //     for (var x, y in <int>[]) {
 //          ^^^
 //
-// pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Setter not found: 'constant'.
+// pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Can't assign to the const variable 'constant'.
 //     for (constant in []) {}
 //          ^^^^^^^^
 //
@@ -276,7 +276,7 @@
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t18 = :sync-for-iterator.{core::Iterator::current};
         {
-          invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Setter not found: 'constant'.
+          invalid-expression "pkg/front_end/testcases/general_nnbd_opt_out/for_in_without_declaration.dart:48:10: Error: Can't assign to the const variable 'constant'.
     for (constant in []) {}
          ^^^^^^^^";
         }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.strong.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.strong.expect
index ec1126c..5ebdcbd 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.strong.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.strong.expect
@@ -26,5 +26,5 @@
 static method main() → dynamic {}
 
 constants  {
-  #C1 = null
+  #C1 = 0
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.strong.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.strong.transformed.expect
index ec1126c..5ebdcbd 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.strong.transformed.expect
@@ -26,5 +26,5 @@
 static method main() → dynamic {}
 
 constants  {
-  #C1 = null
+  #C1 = 0
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.weak.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.weak.expect
index ec1126c..5ebdcbd 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.weak.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.weak.expect
@@ -26,5 +26,5 @@
 static method main() → dynamic {}
 
 constants  {
-  #C1 = null
+  #C1 = 0
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.weak.transformed.expect
index ec1126c..5ebdcbd 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/nested_implicit_const_with_env_var.dart.weak.transformed.expect
@@ -26,5 +26,5 @@
 static method main() → dynamic {}
 
 constants  {
-  #C1 = null
+  #C1 = 0
 }
diff --git a/pkg/front_end/testcases/nnbd/late.dart.strong.expect b/pkg/front_end/testcases/nnbd/late.dart.strong.expect
index ff0896a..4c32d9b 100644
--- a/pkg/front_end/testcases/nnbd/late.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/late.dart.strong.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Setter not found: 'lateFinalVariableWithInit'.
+// pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Can't assign to the final variable 'lateFinalVariableWithInit'.
 //     lateFinalVariableWithInit = 0;
 //     ^^^^^^^^^^^^^^^^^^^^^^^^^
 //
@@ -60,7 +60,7 @@
   }
   method methodWithErrors() → dynamic {
     late final core::int lateFinalVariableWithInit = 0;
-    invalid-expression "pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Setter not found: 'lateFinalVariableWithInit'.
+    invalid-expression "pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Can't assign to the final variable 'lateFinalVariableWithInit'.
     lateFinalVariableWithInit = 0;
     ^^^^^^^^^^^^^^^^^^^^^^^^^";
     invalid-expression "pkg/front_end/testcases/nnbd/late.dart:42:5: Error: The setter 'lateFinalInstanceFieldWithInit' isn't defined for the class 'Class'.
diff --git a/pkg/front_end/testcases/nnbd/late.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/late.dart.strong.transformed.expect
index ff0896a..4c32d9b 100644
--- a/pkg/front_end/testcases/nnbd/late.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/late.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Setter not found: 'lateFinalVariableWithInit'.
+// pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Can't assign to the final variable 'lateFinalVariableWithInit'.
 //     lateFinalVariableWithInit = 0;
 //     ^^^^^^^^^^^^^^^^^^^^^^^^^
 //
@@ -60,7 +60,7 @@
   }
   method methodWithErrors() → dynamic {
     late final core::int lateFinalVariableWithInit = 0;
-    invalid-expression "pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Setter not found: 'lateFinalVariableWithInit'.
+    invalid-expression "pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Can't assign to the final variable 'lateFinalVariableWithInit'.
     lateFinalVariableWithInit = 0;
     ^^^^^^^^^^^^^^^^^^^^^^^^^";
     invalid-expression "pkg/front_end/testcases/nnbd/late.dart:42:5: Error: The setter 'lateFinalInstanceFieldWithInit' isn't defined for the class 'Class'.
diff --git a/pkg/front_end/testcases/nnbd/late.dart.weak.expect b/pkg/front_end/testcases/nnbd/late.dart.weak.expect
index ff0896a..4c32d9b 100644
--- a/pkg/front_end/testcases/nnbd/late.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/late.dart.weak.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Setter not found: 'lateFinalVariableWithInit'.
+// pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Can't assign to the final variable 'lateFinalVariableWithInit'.
 //     lateFinalVariableWithInit = 0;
 //     ^^^^^^^^^^^^^^^^^^^^^^^^^
 //
@@ -60,7 +60,7 @@
   }
   method methodWithErrors() → dynamic {
     late final core::int lateFinalVariableWithInit = 0;
-    invalid-expression "pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Setter not found: 'lateFinalVariableWithInit'.
+    invalid-expression "pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Can't assign to the final variable 'lateFinalVariableWithInit'.
     lateFinalVariableWithInit = 0;
     ^^^^^^^^^^^^^^^^^^^^^^^^^";
     invalid-expression "pkg/front_end/testcases/nnbd/late.dart:42:5: Error: The setter 'lateFinalInstanceFieldWithInit' isn't defined for the class 'Class'.
diff --git a/pkg/front_end/testcases/nnbd/late.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/late.dart.weak.transformed.expect
index ff0896a..4c32d9b 100644
--- a/pkg/front_end/testcases/nnbd/late.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/late.dart.weak.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Setter not found: 'lateFinalVariableWithInit'.
+// pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Can't assign to the final variable 'lateFinalVariableWithInit'.
 //     lateFinalVariableWithInit = 0;
 //     ^^^^^^^^^^^^^^^^^^^^^^^^^
 //
@@ -60,7 +60,7 @@
   }
   method methodWithErrors() → dynamic {
     late final core::int lateFinalVariableWithInit = 0;
-    invalid-expression "pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Setter not found: 'lateFinalVariableWithInit'.
+    invalid-expression "pkg/front_end/testcases/nnbd/late.dart:40:5: Error: Can't assign to the final variable 'lateFinalVariableWithInit'.
     lateFinalVariableWithInit = 0;
     ^^^^^^^^^^^^^^^^^^^^^^^^^";
     invalid-expression "pkg/front_end/testcases/nnbd/late.dart:42:5: Error: The setter 'lateFinalInstanceFieldWithInit' isn't defined for the class 'Class'.
diff --git a/pkg/front_end/testcases/rasta/type_literals.dart.strong.expect b/pkg/front_end/testcases/rasta/type_literals.dart.strong.expect
index 76fc4ed..4aadd22 100644
--- a/pkg/front_end/testcases/rasta/type_literals.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/type_literals.dart.strong.expect
@@ -26,259 +26,259 @@
 //     use(Func());
 //         ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:29:5: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:29:5: Error: Can't assign to a type literal.
 //     C = 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:30:9: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:30:9: Error: Can't assign to a type literal.
 //     use(C = 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:31:5: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:31:5: Error: Can't assign to a type literal.
 //     dynamic = 42;
 //     ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:32:9: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:32:9: Error: Can't assign to a type literal.
 //     use(dynamic = 42);
 //         ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:33:5: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:33:5: Error: Can't assign to a type literal.
 //     T = 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:34:9: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:34:9: Error: Can't assign to a type literal.
 //     use(T = 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:35:5: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:35:5: Error: Can't assign to a type literal.
 //     Func = 42;
 //     ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:36:9: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:36:9: Error: Can't assign to a type literal.
 //     use(Func = 42);
 //         ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:38:5: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:38:5: Error: Can't assign to a type literal.
 //     C++;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:39:9: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:39:9: Error: Can't assign to a type literal.
 //     use(C++);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:40:5: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:40:5: Error: Can't assign to a type literal.
 //     dynamic++;
 //     ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:41:9: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:41:9: Error: Can't assign to a type literal.
 //     use(dynamic++);
 //         ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:42:5: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:42:5: Error: Can't assign to a type literal.
 //     T++;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:43:9: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:43:9: Error: Can't assign to a type literal.
 //     use(T++);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:44:5: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:44:5: Error: Can't assign to a type literal.
 //     Func++;
 //     ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:45:9: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:45:9: Error: Can't assign to a type literal.
 //     use(Func++);
 //         ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:47:7: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:47:7: Error: Can't assign to a type literal.
 //     ++C;
 //       ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:48:11: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:48:11: Error: Can't assign to a type literal.
 //     use(++C);
 //           ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:49:7: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:49:7: Error: Can't assign to a type literal.
 //     ++dynamic;
 //       ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:50:11: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:50:11: Error: Can't assign to a type literal.
 //     use(++dynamic);
 //           ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:51:7: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:51:7: Error: Can't assign to a type literal.
 //     ++T;
 //       ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:52:11: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:52:11: Error: Can't assign to a type literal.
 //     use(++T);
 //           ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:53:7: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:53:7: Error: Can't assign to a type literal.
 //     ++Func;
 //       ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:54:11: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:54:11: Error: Can't assign to a type literal.
 //     use(++Func);
 //           ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:56:5: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:56:5: Error: Can't assign to a type literal.
 //     C--;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:57:9: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:57:9: Error: Can't assign to a type literal.
 //     use(C--);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:58:5: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:58:5: Error: Can't assign to a type literal.
 //     dynamic--;
 //     ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:59:9: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:59:9: Error: Can't assign to a type literal.
 //     use(dynamic--);
 //         ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:60:5: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:60:5: Error: Can't assign to a type literal.
 //     T--;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:61:9: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:61:9: Error: Can't assign to a type literal.
 //     use(T--);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:62:5: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:62:5: Error: Can't assign to a type literal.
 //     Func--;
 //     ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:63:9: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:63:9: Error: Can't assign to a type literal.
 //     use(Func--);
 //         ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:65:7: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:65:7: Error: Can't assign to a type literal.
 //     --C;
 //       ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:66:11: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:66:11: Error: Can't assign to a type literal.
 //     use(--C);
 //           ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:67:7: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:67:7: Error: Can't assign to a type literal.
 //     --dynamic;
 //       ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:68:11: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:68:11: Error: Can't assign to a type literal.
 //     use(--dynamic);
 //           ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:69:7: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:69:7: Error: Can't assign to a type literal.
 //     --T;
 //       ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:70:11: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:70:11: Error: Can't assign to a type literal.
 //     use(--T);
 //           ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:71:7: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:71:7: Error: Can't assign to a type literal.
 //     --Func;
 //       ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:72:11: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:72:11: Error: Can't assign to a type literal.
 //     use(--Func);
 //           ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:74:5: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:74:5: Error: Can't assign to a type literal.
 //     C ??= 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:75:9: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:75:9: Error: Can't assign to a type literal.
 //     use(C ??= 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:76:5: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:76:5: Error: Can't assign to a type literal.
 //     dynamic ??= 42;
 //     ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:77:9: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:77:9: Error: Can't assign to a type literal.
 //     use(dynamic ??= 42);
 //         ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:78:5: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:78:5: Error: Can't assign to a type literal.
 //     T ??= 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:79:9: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:79:9: Error: Can't assign to a type literal.
 //     use(T ??= 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:80:5: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:80:5: Error: Can't assign to a type literal.
 //     Func ??= 42;
 //     ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:81:9: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:81:9: Error: Can't assign to a type literal.
 //     use(Func ??= 42);
 //         ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:83:5: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:83:5: Error: Can't assign to a type literal.
 //     C += 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:84:9: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:84:9: Error: Can't assign to a type literal.
 //     use(C += 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:85:5: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:85:5: Error: Can't assign to a type literal.
 //     dynamic += 42;
 //     ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:86:9: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:86:9: Error: Can't assign to a type literal.
 //     use(dynamic += 42);
 //         ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:87:5: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:87:5: Error: Can't assign to a type literal.
 //     T += 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:88:9: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:88:9: Error: Can't assign to a type literal.
 //     use(T += 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:89:5: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:89:5: Error: Can't assign to a type literal.
 //     Func += 42;
 //     ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:90:9: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:90:9: Error: Can't assign to a type literal.
 //     use(Func += 42);
 //         ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:92:5: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:92:5: Error: Can't assign to a type literal.
 //     C -= 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:93:9: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:93:9: Error: Can't assign to a type literal.
 //     use(C -= 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:94:5: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:94:5: Error: Can't assign to a type literal.
 //     dynamic -= 42;
 //     ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:95:9: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:95:9: Error: Can't assign to a type literal.
 //     use(dynamic -= 42);
 //         ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:96:5: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:96:5: Error: Can't assign to a type literal.
 //     T -= 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:97:9: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:97:9: Error: Can't assign to a type literal.
 //     use(T -= 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:98:5: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:98:5: Error: Can't assign to a type literal.
 //     Func -= 42;
 //     ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:99:9: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:99:9: Error: Can't assign to a type literal.
 //     use(Func -= 42);
 //         ^^^^
 //
@@ -319,196 +319,196 @@
     self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:27:9: Error: Method not found: 'Func'.
     use(Func());
         ^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:29:5: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:29:5: Error: Can't assign to a type literal.
     C = 42;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:30:9: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:30:9: Error: Can't assign to a type literal.
     use(C = 42);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:31:5: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:31:5: Error: Can't assign to a type literal.
     dynamic = 42;
     ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:32:9: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:32:9: Error: Can't assign to a type literal.
     use(dynamic = 42);
         ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:33:5: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:33:5: Error: Can't assign to a type literal.
     T = 42;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:34:9: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:34:9: Error: Can't assign to a type literal.
     use(T = 42);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:35:5: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:35:5: Error: Can't assign to a type literal.
     Func = 42;
     ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:36:9: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:36:9: Error: Can't assign to a type literal.
     use(Func = 42);
         ^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:38:5: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:38:5: Error: Can't assign to a type literal.
     C++;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:39:9: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:39:9: Error: Can't assign to a type literal.
     use(C++);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:40:5: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:40:5: Error: Can't assign to a type literal.
     dynamic++;
     ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:41:9: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:41:9: Error: Can't assign to a type literal.
     use(dynamic++);
         ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:42:5: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:42:5: Error: Can't assign to a type literal.
     T++;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:43:9: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:43:9: Error: Can't assign to a type literal.
     use(T++);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:44:5: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:44:5: Error: Can't assign to a type literal.
     Func++;
     ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:45:9: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:45:9: Error: Can't assign to a type literal.
     use(Func++);
         ^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:47:7: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:47:7: Error: Can't assign to a type literal.
     ++C;
       ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:48:11: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:48:11: Error: Can't assign to a type literal.
     use(++C);
           ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:49:7: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:49:7: Error: Can't assign to a type literal.
     ++dynamic;
       ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:50:11: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:50:11: Error: Can't assign to a type literal.
     use(++dynamic);
           ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:51:7: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:51:7: Error: Can't assign to a type literal.
     ++T;
       ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:52:11: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:52:11: Error: Can't assign to a type literal.
     use(++T);
           ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:53:7: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:53:7: Error: Can't assign to a type literal.
     ++Func;
       ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:54:11: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:54:11: Error: Can't assign to a type literal.
     use(++Func);
           ^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:56:5: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:56:5: Error: Can't assign to a type literal.
     C--;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:57:9: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:57:9: Error: Can't assign to a type literal.
     use(C--);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:58:5: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:58:5: Error: Can't assign to a type literal.
     dynamic--;
     ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:59:9: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:59:9: Error: Can't assign to a type literal.
     use(dynamic--);
         ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:60:5: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:60:5: Error: Can't assign to a type literal.
     T--;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:61:9: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:61:9: Error: Can't assign to a type literal.
     use(T--);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:62:5: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:62:5: Error: Can't assign to a type literal.
     Func--;
     ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:63:9: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:63:9: Error: Can't assign to a type literal.
     use(Func--);
         ^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:65:7: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:65:7: Error: Can't assign to a type literal.
     --C;
       ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:66:11: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:66:11: Error: Can't assign to a type literal.
     use(--C);
           ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:67:7: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:67:7: Error: Can't assign to a type literal.
     --dynamic;
       ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:68:11: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:68:11: Error: Can't assign to a type literal.
     use(--dynamic);
           ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:69:7: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:69:7: Error: Can't assign to a type literal.
     --T;
       ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:70:11: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:70:11: Error: Can't assign to a type literal.
     use(--T);
           ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:71:7: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:71:7: Error: Can't assign to a type literal.
     --Func;
       ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:72:11: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:72:11: Error: Can't assign to a type literal.
     use(--Func);
           ^^^^");
-    self::C<dynamic>*.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:74:5: Error: Setter not found: 'C'.
+    self::C<dynamic>*.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:74:5: Error: Can't assign to a type literal.
     C ??= 42;
     ^" : null;
-    self::use(let final core::Type* #t1 = self::C<dynamic>* in #t1.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:75:9: Error: Setter not found: 'C'.
+    self::use(let final core::Type* #t1 = self::C<dynamic>* in #t1.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:75:9: Error: Can't assign to a type literal.
     use(C ??= 42);
         ^" : #t1);
-    dynamic.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:76:5: Error: Setter not found: 'dynamic'.
+    dynamic.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:76:5: Error: Can't assign to a type literal.
     dynamic ??= 42;
     ^^^^^^^" : null;
-    self::use(let final core::Type* #t2 = dynamic in #t2.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:77:9: Error: Setter not found: 'dynamic'.
+    self::use(let final core::Type* #t2 = dynamic in #t2.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:77:9: Error: Can't assign to a type literal.
     use(dynamic ??= 42);
         ^^^^^^^" : #t2);
-    self::C::T*.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:78:5: Error: Setter not found: 'T'.
+    self::C::T*.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:78:5: Error: Can't assign to a type literal.
     T ??= 42;
     ^" : null;
-    self::use(let final core::Type* #t3 = self::C::T* in #t3.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:79:9: Error: Setter not found: 'T'.
+    self::use(let final core::Type* #t3 = self::C::T* in #t3.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:79:9: Error: Can't assign to a type literal.
     use(T ??= 42);
         ^" : #t3);
-    () →* void.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:80:5: Error: Setter not found: 'Func'.
+    () →* void.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:80:5: Error: Can't assign to a type literal.
     Func ??= 42;
     ^^^^" : null;
-    self::use(let final core::Type* #t4 = () →* void in #t4.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:81:9: Error: Setter not found: 'Func'.
+    self::use(let final core::Type* #t4 = () →* void in #t4.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:81:9: Error: Can't assign to a type literal.
     use(Func ??= 42);
         ^^^^" : #t4);
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:83:5: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:83:5: Error: Can't assign to a type literal.
     C += 42;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:84:9: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:84:9: Error: Can't assign to a type literal.
     use(C += 42);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:85:5: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:85:5: Error: Can't assign to a type literal.
     dynamic += 42;
     ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:86:9: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:86:9: Error: Can't assign to a type literal.
     use(dynamic += 42);
         ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:87:5: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:87:5: Error: Can't assign to a type literal.
     T += 42;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:88:9: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:88:9: Error: Can't assign to a type literal.
     use(T += 42);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:89:5: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:89:5: Error: Can't assign to a type literal.
     Func += 42;
     ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:90:9: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:90:9: Error: Can't assign to a type literal.
     use(Func += 42);
         ^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:92:5: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:92:5: Error: Can't assign to a type literal.
     C -= 42;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:93:9: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:93:9: Error: Can't assign to a type literal.
     use(C -= 42);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:94:5: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:94:5: Error: Can't assign to a type literal.
     dynamic -= 42;
     ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:95:9: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:95:9: Error: Can't assign to a type literal.
     use(dynamic -= 42);
         ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:96:5: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:96:5: Error: Can't assign to a type literal.
     T -= 42;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:97:9: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:97:9: Error: Can't assign to a type literal.
     use(T -= 42);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:98:5: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:98:5: Error: Can't assign to a type literal.
     Func -= 42;
     ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:99:9: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:99:9: Error: Can't assign to a type literal.
     use(Func -= 42);
         ^^^^");
   }
diff --git a/pkg/front_end/testcases/rasta/type_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/type_literals.dart.strong.transformed.expect
index 76fc4ed..4aadd22 100644
--- a/pkg/front_end/testcases/rasta/type_literals.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/type_literals.dart.strong.transformed.expect
@@ -26,259 +26,259 @@
 //     use(Func());
 //         ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:29:5: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:29:5: Error: Can't assign to a type literal.
 //     C = 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:30:9: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:30:9: Error: Can't assign to a type literal.
 //     use(C = 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:31:5: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:31:5: Error: Can't assign to a type literal.
 //     dynamic = 42;
 //     ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:32:9: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:32:9: Error: Can't assign to a type literal.
 //     use(dynamic = 42);
 //         ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:33:5: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:33:5: Error: Can't assign to a type literal.
 //     T = 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:34:9: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:34:9: Error: Can't assign to a type literal.
 //     use(T = 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:35:5: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:35:5: Error: Can't assign to a type literal.
 //     Func = 42;
 //     ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:36:9: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:36:9: Error: Can't assign to a type literal.
 //     use(Func = 42);
 //         ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:38:5: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:38:5: Error: Can't assign to a type literal.
 //     C++;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:39:9: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:39:9: Error: Can't assign to a type literal.
 //     use(C++);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:40:5: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:40:5: Error: Can't assign to a type literal.
 //     dynamic++;
 //     ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:41:9: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:41:9: Error: Can't assign to a type literal.
 //     use(dynamic++);
 //         ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:42:5: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:42:5: Error: Can't assign to a type literal.
 //     T++;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:43:9: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:43:9: Error: Can't assign to a type literal.
 //     use(T++);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:44:5: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:44:5: Error: Can't assign to a type literal.
 //     Func++;
 //     ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:45:9: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:45:9: Error: Can't assign to a type literal.
 //     use(Func++);
 //         ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:47:7: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:47:7: Error: Can't assign to a type literal.
 //     ++C;
 //       ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:48:11: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:48:11: Error: Can't assign to a type literal.
 //     use(++C);
 //           ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:49:7: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:49:7: Error: Can't assign to a type literal.
 //     ++dynamic;
 //       ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:50:11: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:50:11: Error: Can't assign to a type literal.
 //     use(++dynamic);
 //           ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:51:7: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:51:7: Error: Can't assign to a type literal.
 //     ++T;
 //       ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:52:11: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:52:11: Error: Can't assign to a type literal.
 //     use(++T);
 //           ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:53:7: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:53:7: Error: Can't assign to a type literal.
 //     ++Func;
 //       ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:54:11: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:54:11: Error: Can't assign to a type literal.
 //     use(++Func);
 //           ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:56:5: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:56:5: Error: Can't assign to a type literal.
 //     C--;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:57:9: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:57:9: Error: Can't assign to a type literal.
 //     use(C--);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:58:5: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:58:5: Error: Can't assign to a type literal.
 //     dynamic--;
 //     ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:59:9: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:59:9: Error: Can't assign to a type literal.
 //     use(dynamic--);
 //         ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:60:5: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:60:5: Error: Can't assign to a type literal.
 //     T--;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:61:9: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:61:9: Error: Can't assign to a type literal.
 //     use(T--);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:62:5: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:62:5: Error: Can't assign to a type literal.
 //     Func--;
 //     ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:63:9: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:63:9: Error: Can't assign to a type literal.
 //     use(Func--);
 //         ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:65:7: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:65:7: Error: Can't assign to a type literal.
 //     --C;
 //       ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:66:11: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:66:11: Error: Can't assign to a type literal.
 //     use(--C);
 //           ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:67:7: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:67:7: Error: Can't assign to a type literal.
 //     --dynamic;
 //       ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:68:11: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:68:11: Error: Can't assign to a type literal.
 //     use(--dynamic);
 //           ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:69:7: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:69:7: Error: Can't assign to a type literal.
 //     --T;
 //       ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:70:11: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:70:11: Error: Can't assign to a type literal.
 //     use(--T);
 //           ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:71:7: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:71:7: Error: Can't assign to a type literal.
 //     --Func;
 //       ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:72:11: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:72:11: Error: Can't assign to a type literal.
 //     use(--Func);
 //           ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:74:5: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:74:5: Error: Can't assign to a type literal.
 //     C ??= 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:75:9: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:75:9: Error: Can't assign to a type literal.
 //     use(C ??= 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:76:5: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:76:5: Error: Can't assign to a type literal.
 //     dynamic ??= 42;
 //     ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:77:9: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:77:9: Error: Can't assign to a type literal.
 //     use(dynamic ??= 42);
 //         ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:78:5: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:78:5: Error: Can't assign to a type literal.
 //     T ??= 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:79:9: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:79:9: Error: Can't assign to a type literal.
 //     use(T ??= 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:80:5: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:80:5: Error: Can't assign to a type literal.
 //     Func ??= 42;
 //     ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:81:9: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:81:9: Error: Can't assign to a type literal.
 //     use(Func ??= 42);
 //         ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:83:5: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:83:5: Error: Can't assign to a type literal.
 //     C += 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:84:9: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:84:9: Error: Can't assign to a type literal.
 //     use(C += 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:85:5: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:85:5: Error: Can't assign to a type literal.
 //     dynamic += 42;
 //     ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:86:9: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:86:9: Error: Can't assign to a type literal.
 //     use(dynamic += 42);
 //         ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:87:5: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:87:5: Error: Can't assign to a type literal.
 //     T += 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:88:9: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:88:9: Error: Can't assign to a type literal.
 //     use(T += 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:89:5: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:89:5: Error: Can't assign to a type literal.
 //     Func += 42;
 //     ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:90:9: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:90:9: Error: Can't assign to a type literal.
 //     use(Func += 42);
 //         ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:92:5: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:92:5: Error: Can't assign to a type literal.
 //     C -= 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:93:9: Error: Setter not found: 'C'.
+// pkg/front_end/testcases/rasta/type_literals.dart:93:9: Error: Can't assign to a type literal.
 //     use(C -= 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:94:5: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:94:5: Error: Can't assign to a type literal.
 //     dynamic -= 42;
 //     ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:95:9: Error: Setter not found: 'dynamic'.
+// pkg/front_end/testcases/rasta/type_literals.dart:95:9: Error: Can't assign to a type literal.
 //     use(dynamic -= 42);
 //         ^^^^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:96:5: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:96:5: Error: Can't assign to a type literal.
 //     T -= 42;
 //     ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:97:9: Error: Setter not found: 'T'.
+// pkg/front_end/testcases/rasta/type_literals.dart:97:9: Error: Can't assign to a type literal.
 //     use(T -= 42);
 //         ^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:98:5: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:98:5: Error: Can't assign to a type literal.
 //     Func -= 42;
 //     ^^^^
 //
-// pkg/front_end/testcases/rasta/type_literals.dart:99:9: Error: Setter not found: 'Func'.
+// pkg/front_end/testcases/rasta/type_literals.dart:99:9: Error: Can't assign to a type literal.
 //     use(Func -= 42);
 //         ^^^^
 //
@@ -319,196 +319,196 @@
     self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:27:9: Error: Method not found: 'Func'.
     use(Func());
         ^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:29:5: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:29:5: Error: Can't assign to a type literal.
     C = 42;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:30:9: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:30:9: Error: Can't assign to a type literal.
     use(C = 42);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:31:5: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:31:5: Error: Can't assign to a type literal.
     dynamic = 42;
     ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:32:9: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:32:9: Error: Can't assign to a type literal.
     use(dynamic = 42);
         ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:33:5: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:33:5: Error: Can't assign to a type literal.
     T = 42;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:34:9: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:34:9: Error: Can't assign to a type literal.
     use(T = 42);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:35:5: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:35:5: Error: Can't assign to a type literal.
     Func = 42;
     ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:36:9: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:36:9: Error: Can't assign to a type literal.
     use(Func = 42);
         ^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:38:5: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:38:5: Error: Can't assign to a type literal.
     C++;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:39:9: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:39:9: Error: Can't assign to a type literal.
     use(C++);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:40:5: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:40:5: Error: Can't assign to a type literal.
     dynamic++;
     ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:41:9: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:41:9: Error: Can't assign to a type literal.
     use(dynamic++);
         ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:42:5: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:42:5: Error: Can't assign to a type literal.
     T++;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:43:9: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:43:9: Error: Can't assign to a type literal.
     use(T++);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:44:5: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:44:5: Error: Can't assign to a type literal.
     Func++;
     ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:45:9: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:45:9: Error: Can't assign to a type literal.
     use(Func++);
         ^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:47:7: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:47:7: Error: Can't assign to a type literal.
     ++C;
       ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:48:11: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:48:11: Error: Can't assign to a type literal.
     use(++C);
           ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:49:7: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:49:7: Error: Can't assign to a type literal.
     ++dynamic;
       ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:50:11: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:50:11: Error: Can't assign to a type literal.
     use(++dynamic);
           ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:51:7: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:51:7: Error: Can't assign to a type literal.
     ++T;
       ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:52:11: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:52:11: Error: Can't assign to a type literal.
     use(++T);
           ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:53:7: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:53:7: Error: Can't assign to a type literal.
     ++Func;
       ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:54:11: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:54:11: Error: Can't assign to a type literal.
     use(++Func);
           ^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:56:5: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:56:5: Error: Can't assign to a type literal.
     C--;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:57:9: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:57:9: Error: Can't assign to a type literal.
     use(C--);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:58:5: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:58:5: Error: Can't assign to a type literal.
     dynamic--;
     ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:59:9: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:59:9: Error: Can't assign to a type literal.
     use(dynamic--);
         ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:60:5: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:60:5: Error: Can't assign to a type literal.
     T--;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:61:9: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:61:9: Error: Can't assign to a type literal.
     use(T--);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:62:5: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:62:5: Error: Can't assign to a type literal.
     Func--;
     ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:63:9: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:63:9: Error: Can't assign to a type literal.
     use(Func--);
         ^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:65:7: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:65:7: Error: Can't assign to a type literal.
     --C;
       ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:66:11: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:66:11: Error: Can't assign to a type literal.
     use(--C);
           ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:67:7: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:67:7: Error: Can't assign to a type literal.
     --dynamic;
       ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:68:11: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:68:11: Error: Can't assign to a type literal.
     use(--dynamic);
           ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:69:7: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:69:7: Error: Can't assign to a type literal.
     --T;
       ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:70:11: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:70:11: Error: Can't assign to a type literal.
     use(--T);
           ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:71:7: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:71:7: Error: Can't assign to a type literal.
     --Func;
       ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:72:11: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:72:11: Error: Can't assign to a type literal.
     use(--Func);
           ^^^^");
-    self::C<dynamic>*.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:74:5: Error: Setter not found: 'C'.
+    self::C<dynamic>*.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:74:5: Error: Can't assign to a type literal.
     C ??= 42;
     ^" : null;
-    self::use(let final core::Type* #t1 = self::C<dynamic>* in #t1.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:75:9: Error: Setter not found: 'C'.
+    self::use(let final core::Type* #t1 = self::C<dynamic>* in #t1.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:75:9: Error: Can't assign to a type literal.
     use(C ??= 42);
         ^" : #t1);
-    dynamic.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:76:5: Error: Setter not found: 'dynamic'.
+    dynamic.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:76:5: Error: Can't assign to a type literal.
     dynamic ??= 42;
     ^^^^^^^" : null;
-    self::use(let final core::Type* #t2 = dynamic in #t2.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:77:9: Error: Setter not found: 'dynamic'.
+    self::use(let final core::Type* #t2 = dynamic in #t2.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:77:9: Error: Can't assign to a type literal.
     use(dynamic ??= 42);
         ^^^^^^^" : #t2);
-    self::C::T*.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:78:5: Error: Setter not found: 'T'.
+    self::C::T*.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:78:5: Error: Can't assign to a type literal.
     T ??= 42;
     ^" : null;
-    self::use(let final core::Type* #t3 = self::C::T* in #t3.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:79:9: Error: Setter not found: 'T'.
+    self::use(let final core::Type* #t3 = self::C::T* in #t3.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:79:9: Error: Can't assign to a type literal.
     use(T ??= 42);
         ^" : #t3);
-    () →* void.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:80:5: Error: Setter not found: 'Func'.
+    () →* void.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:80:5: Error: Can't assign to a type literal.
     Func ??= 42;
     ^^^^" : null;
-    self::use(let final core::Type* #t4 = () →* void in #t4.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:81:9: Error: Setter not found: 'Func'.
+    self::use(let final core::Type* #t4 = () →* void in #t4.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:81:9: Error: Can't assign to a type literal.
     use(Func ??= 42);
         ^^^^" : #t4);
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:83:5: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:83:5: Error: Can't assign to a type literal.
     C += 42;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:84:9: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:84:9: Error: Can't assign to a type literal.
     use(C += 42);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:85:5: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:85:5: Error: Can't assign to a type literal.
     dynamic += 42;
     ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:86:9: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:86:9: Error: Can't assign to a type literal.
     use(dynamic += 42);
         ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:87:5: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:87:5: Error: Can't assign to a type literal.
     T += 42;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:88:9: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:88:9: Error: Can't assign to a type literal.
     use(T += 42);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:89:5: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:89:5: Error: Can't assign to a type literal.
     Func += 42;
     ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:90:9: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:90:9: Error: Can't assign to a type literal.
     use(Func += 42);
         ^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:92:5: Error: Setter not found: 'C'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:92:5: Error: Can't assign to a type literal.
     C -= 42;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:93:9: Error: Setter not found: 'C'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:93:9: Error: Can't assign to a type literal.
     use(C -= 42);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:94:5: Error: Setter not found: 'dynamic'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:94:5: Error: Can't assign to a type literal.
     dynamic -= 42;
     ^^^^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:95:9: Error: Setter not found: 'dynamic'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:95:9: Error: Can't assign to a type literal.
     use(dynamic -= 42);
         ^^^^^^^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:96:5: Error: Setter not found: 'T'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:96:5: Error: Can't assign to a type literal.
     T -= 42;
     ^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:97:9: Error: Setter not found: 'T'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:97:9: Error: Can't assign to a type literal.
     use(T -= 42);
         ^");
-    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:98:5: Error: Setter not found: 'Func'.
+    invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:98:5: Error: Can't assign to a type literal.
     Func -= 42;
     ^^^^";
-    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:99:9: Error: Setter not found: 'Func'.
+    self::use(invalid-expression "pkg/front_end/testcases/rasta/type_literals.dart:99:9: Error: Can't assign to a type literal.
     use(Func -= 42);
         ^^^^");
   }
diff --git a/pkg/front_end/testcases/rasta/typedef.dart.strong.expect b/pkg/front_end/testcases/rasta/typedef.dart.strong.expect
index eccfc19..36ac25e 100644
--- a/pkg/front_end/testcases/rasta/typedef.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/typedef.dart.strong.expect
@@ -2,11 +2,11 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/rasta/typedef.dart:9:3: Error: Setter not found: 'Foo'.
+// pkg/front_end/testcases/rasta/typedef.dart:9:3: Error: Can't assign to a type literal.
 //   Foo = null;
 //   ^^^
 //
-// pkg/front_end/testcases/rasta/typedef.dart:10:3: Error: Setter not found: 'Foo'.
+// pkg/front_end/testcases/rasta/typedef.dart:10:3: Error: Can't assign to a type literal.
 //   Foo ??= null;
 //   ^^^
 //
@@ -20,10 +20,10 @@
 typedef Foo = () →* void;
 static method main() → dynamic {
   core::print(() →* void);
-  invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:9:3: Error: Setter not found: 'Foo'.
+  invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:9:3: Error: Can't assign to a type literal.
   Foo = null;
   ^^^";
-  () →* void.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:10:3: Error: Setter not found: 'Foo'.
+  () →* void.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:10:3: Error: Can't assign to a type literal.
   Foo ??= null;
   ^^^" : null;
   invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:11:3: Error: Method not found: 'Foo'.
diff --git a/pkg/front_end/testcases/rasta/typedef.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/typedef.dart.strong.transformed.expect
index eccfc19..36ac25e 100644
--- a/pkg/front_end/testcases/rasta/typedef.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/typedef.dart.strong.transformed.expect
@@ -2,11 +2,11 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/rasta/typedef.dart:9:3: Error: Setter not found: 'Foo'.
+// pkg/front_end/testcases/rasta/typedef.dart:9:3: Error: Can't assign to a type literal.
 //   Foo = null;
 //   ^^^
 //
-// pkg/front_end/testcases/rasta/typedef.dart:10:3: Error: Setter not found: 'Foo'.
+// pkg/front_end/testcases/rasta/typedef.dart:10:3: Error: Can't assign to a type literal.
 //   Foo ??= null;
 //   ^^^
 //
@@ -20,10 +20,10 @@
 typedef Foo = () →* void;
 static method main() → dynamic {
   core::print(() →* void);
-  invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:9:3: Error: Setter not found: 'Foo'.
+  invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:9:3: Error: Can't assign to a type literal.
   Foo = null;
   ^^^";
-  () →* void.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:10:3: Error: Setter not found: 'Foo'.
+  () →* void.{core::Object::==}(null) ?{dynamic} invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:10:3: Error: Can't assign to a type literal.
   Foo ??= null;
   ^^^" : null;
   invalid-expression "pkg/front_end/testcases/rasta/typedef.dart:11:3: Error: Method not found: 'Foo'.
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.expect
index 4b6f9c8..76a12f1 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Setter not found: 'Fisk'.
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Can't assign to a type literal.
 //     for (Fisk in x) {
 //          ^^^^
 //
@@ -14,7 +14,7 @@
 //     for (collection in x) {
 //          ^^^^^^^^^^
 //
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:20:10: Error: Setter not found: 'VoidFunction'.
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:20:10: Error: Can't assign to a type literal.
 //     for (VoidFunction in x) {
 //          ^^^^^^^^^^^^
 //
@@ -52,7 +52,7 @@
 //   for (key in arguments) {
 //        ^^^
 //
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:34:8: Error: Setter not found: 'Fisk'.
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:34:8: Error: Can't assign to a type literal.
 //   for (Fisk in arguments) {
 //        ^^^^
 //
@@ -64,7 +64,7 @@
 //   for (collection in arguments) {
 //        ^^^^^^^^^^
 //
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:40:8: Error: Setter not found: 'VoidFunction'.
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:40:8: Error: Can't assign to a type literal.
 //   for (VoidFunction in arguments) {
 //        ^^^^^^^^^^^^
 //
@@ -104,7 +104,7 @@
             ^^^");
     }
     for (final dynamic #t2 in x as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-      invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Setter not found: 'Fisk'.
+      invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Can't assign to a type literal.
     for (Fisk in x) {
          ^^^^";
       core::print(self::Fisk*);
@@ -118,7 +118,7 @@
             ^^^^^^^^^^");
     }
     for (final dynamic #t4 in x as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-      invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:20:10: Error: Setter not found: 'VoidFunction'.
+      invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:20:10: Error: Can't assign to a type literal.
     for (VoidFunction in x) {
          ^^^^^^^^^^^^";
       core::print(() →* void);
@@ -152,7 +152,7 @@
           ^^^");
   }
   for (final dynamic #t7 in arguments as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-    invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:34:8: Error: Setter not found: 'Fisk'.
+    invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:34:8: Error: Can't assign to a type literal.
   for (Fisk in arguments) {
        ^^^^";
     core::print(self::Fisk*);
@@ -166,7 +166,7 @@
           ^^^^^^^^^^");
   }
   for (final dynamic #t9 in arguments as{TypeError,ForDynamic} core::Iterable<dynamic>*) {
-    invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:40:8: Error: Setter not found: 'VoidFunction'.
+    invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:40:8: Error: Can't assign to a type literal.
   for (VoidFunction in arguments) {
        ^^^^^^^^^^^^";
     core::print(() →* void);
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.transformed.expect
index 1cc912e..48bbc83 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Setter not found: 'Fisk'.
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Can't assign to a type literal.
 //     for (Fisk in x) {
 //          ^^^^
 //
@@ -14,7 +14,7 @@
 //     for (collection in x) {
 //          ^^^^^^^^^^
 //
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:20:10: Error: Setter not found: 'VoidFunction'.
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:20:10: Error: Can't assign to a type literal.
 //     for (VoidFunction in x) {
 //          ^^^^^^^^^^^^
 //
@@ -52,7 +52,7 @@
 //   for (key in arguments) {
 //        ^^^
 //
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:34:8: Error: Setter not found: 'Fisk'.
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:34:8: Error: Can't assign to a type literal.
 //   for (Fisk in arguments) {
 //        ^^^^
 //
@@ -64,7 +64,7 @@
 //   for (collection in arguments) {
 //        ^^^^^^^^^^
 //
-// pkg/front_end/testcases/rasta/unresolved_for_in.dart:40:8: Error: Setter not found: 'VoidFunction'.
+// pkg/front_end/testcases/rasta/unresolved_for_in.dart:40:8: Error: Can't assign to a type literal.
 //   for (VoidFunction in arguments) {
 //        ^^^^^^^^^^^^
 //
@@ -115,7 +115,7 @@
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t2 = :sync-for-iterator.{core::Iterator::current};
         {
-          invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Setter not found: 'Fisk'.
+          invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:14:10: Error: Can't assign to a type literal.
     for (Fisk in x) {
          ^^^^";
           core::print(self::Fisk*);
@@ -141,7 +141,7 @@
       for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
         final dynamic #t4 = :sync-for-iterator.{core::Iterator::current};
         {
-          invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:20:10: Error: Setter not found: 'VoidFunction'.
+          invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:20:10: Error: Can't assign to a type literal.
     for (VoidFunction in x) {
          ^^^^^^^^^^^^";
           core::print(() →* void);
@@ -193,7 +193,7 @@
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final dynamic #t7 = :sync-for-iterator.{core::Iterator::current};
       {
-        invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:34:8: Error: Setter not found: 'Fisk'.
+        invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:34:8: Error: Can't assign to a type literal.
   for (Fisk in arguments) {
        ^^^^";
         core::print(self::Fisk*);
@@ -219,7 +219,7 @@
     for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
       final dynamic #t9 = :sync-for-iterator.{core::Iterator::current};
       {
-        invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:40:8: Error: Setter not found: 'VoidFunction'.
+        invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:40:8: Error: Can't assign to a type literal.
   for (VoidFunction in arguments) {
        ^^^^^^^^^^^^";
         core::print(() →* void);
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 1a235ee..5dc34b0 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -245,6 +245,7 @@
 general/issue39344: TextSerializationFailure
 general/issue39421: TextSerializationFailure
 general/issue39817: TextSerializationFailure
+general/issue40242: TextSerializationFailure
 general/issue40428: TextSerializationFailure
 general/issue40662: TextSerializationFailure
 general/issue40744: TextSerializationFailure
diff --git a/pkg/front_end/tool/fasta_perf.dart b/pkg/front_end/tool/fasta_perf.dart
index 986fc83..2037866 100644
--- a/pkg/front_end/tool/fasta_perf.dart
+++ b/pkg/front_end/tool/fasta_perf.dart
@@ -218,7 +218,7 @@
 // bodies. So this listener is not feature complete.
 class _PartialAstBuilder extends AstBuilder {
   _PartialAstBuilder(Uri uri)
-      : super(null, null, true, null, FeatureSet.fromEnableFlags([]), uri);
+      : super(null, null, true, FeatureSet.fromEnableFlags([]), uri);
 }
 
 // Invoke the fasta kernel generator for the program starting in [entryUri]
diff --git a/pkg/front_end/tool/perf.dart b/pkg/front_end/tool/perf.dart
index 2c18e45..5804f9d 100644
--- a/pkg/front_end/tool/perf.dart
+++ b/pkg/front_end/tool/perf.dart
@@ -103,7 +103,6 @@
   var parser = new Parser(
     source,
     AnalysisErrorListener.NULL_LISTENER,
-    languageVersion: null,
     featureSet: FeatureSet.fromEnableFlags([]),
   );
   return parser.parseDirectives(token);
@@ -128,7 +127,6 @@
   var parser = new Parser(
     source,
     AnalysisErrorListener.NULL_LISTENER,
-    languageVersion: null,
     featureSet: FeatureSet.fromEnableFlags([]),
   );
   var unit = parser.parseCompilationUnit(token);
diff --git a/pkg/native_stack_traces/CHANGELOG.md b/pkg/native_stack_traces/CHANGELOG.md
index c6fb8b8..06b1702 100644
--- a/pkg/native_stack_traces/CHANGELOG.md
+++ b/pkg/native_stack_traces/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Changelog
 
+## 0.3.1
+
+- Uses dynamic symbol information embedded in stack frame lines when available.
+
 ## 0.3.0
 
 - Adds handling of virtual addresses within stub code payloads.
diff --git a/pkg/native_stack_traces/lib/src/constants.dart b/pkg/native_stack_traces/lib/src/constants.dart
new file mode 100644
index 0000000..980e8e0
--- /dev/null
+++ b/pkg/native_stack_traces/lib/src/constants.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// The dynamic symbol name for the VM instructions section.
+const String vmSymbolName = "_kDartVmSnapshotInstructions";
+
+// The dynamic symbol name for the isolate instructions section.
+const String isolateSymbolName = "_kDartIsolateSnapshotInstructions";
diff --git a/pkg/native_stack_traces/lib/src/convert.dart b/pkg/native_stack_traces/lib/src/convert.dart
index 86eebaa..df32604 100644
--- a/pkg/native_stack_traces/lib/src/convert.dart
+++ b/pkg/native_stack_traces/lib/src/convert.dart
@@ -5,6 +5,7 @@
 import "dart:async";
 import "dart:math";
 
+import 'constants.dart' as constants;
 import "dwarf.dart";
 
 String _stackTracePiece(CallInfo call, int depth) => "#${depth}\t${call}";
@@ -53,15 +54,47 @@
 ///   - The absolute address of the program counter.
 ///   - The virtual address of the program counter, if the snapshot was
 ///     loaded as a dynamic library, otherwise not present.
-///   - The path to the snapshot, if it was loaded as a dynamic library,
-///     otherwise the string "<unknown>".
-final _traceLineRE =
-    RegExp(r'    #(\d{2}) abs ([\da-f]+)(?: virt ([\da-f]+))? (.*)$');
+///   - The location of the virtual address, which is one of the following:
+///     - A dynamic symbol name, a plus sign, and a hexadecimal offset.
+///     - The path to the snapshot, if it was loaded as a dynamic library,
+///       otherwise the string "<unknown>".
+const _symbolREString = r'(?:(?<symbol>' +
+    constants.vmSymbolName +
+    r'|' +
+    constants.isolateSymbolName +
+    r')\+0x(?<offset>[\da-f]+))';
+final _traceLineRE = RegExp(
+    r'    #(\d{2}) abs (?<address>[\da-f]+)(?: virt ([\da-f]+))? (?:' +
+        _symbolREString +
+        r'|.*)$');
 
-PCOffset _retrievePCOffset(StackTraceHeader header, Match match) {
-  if (header == null || match == null) return null;
-  final address = int.tryParse(match[2], radix: 16);
-  return header.offsetOf(address);
+PCOffset _retrievePCOffset(StackTraceHeader header, RegExpMatch match) {
+  if (match == null) return null;
+  // Try using the symbol information first, since we don't need the header
+  // information to translate it.
+  final symbolString = match.namedGroup('symbol');
+  final offsetString = match.namedGroup('offset');
+  if (symbolString != null && offsetString != null) {
+    final offset = int.tryParse(offsetString, radix: 16);
+    if (offset != null) {
+      switch (symbolString) {
+        case constants.vmSymbolName:
+          return PCOffset(offset, InstructionsSection.vm);
+        case constants.isolateSymbolName:
+          return PCOffset(offset, InstructionsSection.isolate);
+        default:
+          break;
+      }
+    }
+  }
+  // If we're parsing the absolute address, we can only convert it into
+  // a PCOffset if we saw the instructions line of the stack trace header.
+  final addressString = match.namedGroup('address');
+  if (addressString != null && header != null) {
+    final address = int.tryParse(addressString, radix: 16);
+    return header.offsetOf(address);
+  }
+  return null;
 }
 
 /// The [PCOffset]s for frames of the non-symbolic stack traces in [lines].
diff --git a/pkg/native_stack_traces/lib/src/dwarf.dart b/pkg/native_stack_traces/lib/src/dwarf.dart
index a53ea59..88c75b1 100644
--- a/pkg/native_stack_traces/lib/src/dwarf.dart
+++ b/pkg/native_stack_traces/lib/src/dwarf.dart
@@ -5,6 +5,7 @@
 import 'dart:math';
 import 'dart:typed_data';
 
+import 'constants.dart' as constants;
 import 'elf.dart';
 import 'reader.dart';
 
@@ -1201,9 +1202,6 @@
   /// Returns a [Dwarf] object if the load succeeds, otherwise returns null.
   static Dwarf fromFile(String path) => Dwarf.fromReader(Reader.fromFile(path));
 
-  static const String _vmSymbolName = "_kDartVmSnapshotInstructions";
-  static const String _isolateSymbolName = "_kDartIsolateSnapshotInstructions";
-
   static Dwarf _loadSectionsFromElf(Elf elf) {
     final abbrevSection = elf.namedSections(".debug_abbrev").single;
     final abbreviationTables = <int, _AbbreviationsTable>{};
@@ -1223,17 +1221,18 @@
     final debugInfo = DebugInfo.fromReader(
         infoSection.reader, abbreviationTables, lineNumberInfo);
 
-    final vmStartSymbol = elf.dynamicSymbolFor(_vmSymbolName);
+    final vmStartSymbol = elf.dynamicSymbolFor(constants.vmSymbolName);
     if (vmStartSymbol == null) {
       throw FormatException(
-          "Expected a dynamic symbol with name ${_vmSymbolName}");
+          "Expected a dynamic symbol with name ${constants.vmSymbolName}");
     }
     final vmStartAddress = vmStartSymbol.value;
 
-    final isolateStartSymbol = elf.dynamicSymbolFor(_isolateSymbolName);
+    final isolateStartSymbol =
+        elf.dynamicSymbolFor(constants.isolateSymbolName);
     if (isolateStartSymbol == null) {
       throw FormatException(
-          "Expected a dynamic symbol with name ${_isolateSymbolName}");
+          "Expected a dynamic symbol with name ${constants.isolateSymbolName}");
     }
     final isolateStartAddress = isolateStartSymbol.value;
 
diff --git a/pkg/native_stack_traces/pubspec.yaml b/pkg/native_stack_traces/pubspec.yaml
index e300e9e..ad15e37 100644
--- a/pkg/native_stack_traces/pubspec.yaml
+++ b/pkg/native_stack_traces/pubspec.yaml
@@ -1,6 +1,6 @@
 name: native_stack_traces
 description: Utilities for working with non-symbolic stack traces.
-version: 0.3.0
+version: 0.3.1
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/native_stack_traces
 
diff --git a/pkg/nnbd_migration/lib/instrumentation.dart b/pkg/nnbd_migration/lib/instrumentation.dart
index cda88c5..79f88e9 100644
--- a/pkg/nnbd_migration/lib/instrumentation.dart
+++ b/pkg/nnbd_migration/lib/instrumentation.dart
@@ -133,6 +133,9 @@
 /// migrated, suggesting that if one type (the source) is made nullable, it may
 /// be desirable to make the other type (the destination) nullable as well.
 abstract class EdgeInfo implements FixReasonInfo {
+  /// User-friendly description of the edge, or `null` if not known.
+  String get description;
+
   /// Information about the graph node that this edge "points to".
   NullabilityNodeInfo get destinationNode;
 
@@ -216,7 +219,6 @@
   alreadyMigratedType,
   alwaysNullableType,
   compoundAssignment,
-  defaultValue,
   dynamicAssignment,
   enumValue,
   expressionChecks,
@@ -229,7 +231,6 @@
   implicitNullInitializer,
   implicitNullReturn,
   inferredTypeParameterInstantiation,
-  initializerInference,
   instanceCreation,
   instantiateToBounds,
   isCheckComponentType,
@@ -373,6 +374,10 @@
 
 abstract class PropagationStepInfo {
   CodeReference get codeReference;
+
+  /// The nullability edge associated with this propagation step, if any.
+  /// Otherwise `null`.
+  EdgeInfo get edge;
 }
 
 /// Information exposed to the migration client about a node in the nullability
diff --git a/pkg/nnbd_migration/lib/nnbd_migration.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
index 16cdeed..677c7fa 100644
--- a/pkg/nnbd_migration/lib/nnbd_migration.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -51,6 +51,13 @@
   );
 
   /// An unnecessary downcast has been discarded.
+  static const removeLanguageVersionComment = const NullabilityFixDescription._(
+    appliedMessage: 'Removed language version comment so that NNBD features '
+        'will be allowed in this file',
+    kind: NullabilityFixKind.removeLanguageVersionComment,
+  );
+
+  /// An unnecessary downcast has been discarded.
   static const removeAs = const NullabilityFixDescription._(
     appliedMessage: 'Discarded a downcast that is now unnecessary',
     kind: NullabilityFixKind.removeAs,
@@ -126,6 +133,7 @@
   discardThen,
   makeTypeNullable,
   removeAs,
+  removeLanguageVersionComment,
   removeNullAwareness,
   typeNotMadeNullable,
 }
diff --git a/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart b/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
index 16f07b6..2277fb3 100644
--- a/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
+++ b/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
@@ -31,7 +31,7 @@
     if (type.isVoid || type.isDynamic) {
       var node = NullabilityNode.forAlreadyMigrated(target);
       _graph.makeNullableUnion(
-          node, AlwaysNullableTypeOrigin.forElement(element));
+          node, AlwaysNullableTypeOrigin.forElement(element, type.isVoid));
       return DecoratedType(type, node);
     }
     NullabilityNode node;
@@ -39,11 +39,11 @@
     if (nullabilitySuffix == NullabilitySuffix.question) {
       node = NullabilityNode.forAlreadyMigrated(target);
       _graph.makeNullableUnion(
-          node, AlreadyMigratedTypeOrigin.forElement(element));
+          node, AlreadyMigratedTypeOrigin.forElement(element, true));
     } else {
       node = NullabilityNode.forAlreadyMigrated(target);
       _graph.makeNonNullableUnion(
-          node, AlreadyMigratedTypeOrigin.forElement(element));
+          node, AlreadyMigratedTypeOrigin.forElement(element, false));
     }
     if (type is FunctionType) {
       for (var element in type.typeFormals) {
diff --git a/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart b/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart
index 7418253..d35fd15 100644
--- a/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_class_hierarchy.dart
@@ -6,8 +6,8 @@
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:nnbd_migration/src/decorated_type.dart';
-import 'package:nnbd_migration/src/node_builder.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:nnbd_migration/src/variables.dart';
 
 /// Responsible for building and maintaining information about nullability
 /// decorations related to the class hierarchy.
@@ -15,7 +15,7 @@
 /// For instance, if one class is a subclass of the other, we record the
 /// nullabilities of all the types involved in the subclass relationship.
 class DecoratedClassHierarchy {
-  final VariableRepository _variables;
+  final Variables _variables;
 
   final NullabilityGraph _graph;
 
diff --git a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
index b9f6f01..f69f365 100644
--- a/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
@@ -6,14 +6,14 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type_system.dart';
 import 'package:nnbd_migration/src/decorated_type.dart';
-import 'package:nnbd_migration/src/node_builder.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:nnbd_migration/src/variables.dart';
 
 /// [TypeOperations] that works with [DecoratedType]s.
 class DecoratedTypeOperations
     implements TypeOperations<PromotableElement, DecoratedType> {
   final TypeSystem _typeSystem;
-  final VariableRepository _variableRepository;
+  final Variables _variableRepository;
   final NullabilityGraph _graph;
 
   DecoratedTypeOperations(
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index 021717b..25aebf8 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -23,13 +23,14 @@
 import 'package:nnbd_migration/src/decorated_type.dart';
 import 'package:nnbd_migration/src/edge_origin.dart';
 import 'package:nnbd_migration/src/expression_checks.dart';
-import 'package:nnbd_migration/src/node_builder.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
 import 'package:nnbd_migration/src/nullability_node_target.dart';
 import 'package:nnbd_migration/src/utilities/completeness_tracker.dart';
+import 'package:nnbd_migration/src/utilities/hint_utils.dart';
 import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
 import 'package:nnbd_migration/src/utilities/resolution_utils.dart';
 import 'package:nnbd_migration/src/utilities/scoped_set.dart';
+import 'package:nnbd_migration/src/variables.dart';
 
 import 'decorated_type_operations.dart';
 
@@ -103,7 +104,7 @@
 
   /// The repository of constraint variables and decorated types (from a
   /// previous pass over the source code).
-  final VariableRepository _variables;
+  final Variables _variables;
 
   final NullabilityMigrationListener /*?*/ listener;
 
@@ -201,6 +202,9 @@
   /// initializer in the constructor declaration.
   Set<FieldElement> _fieldsNotInitializedByConstructor;
 
+  /// Current nesting depth of [visitTypeName]
+  int _typeNameNesting = 0;
+
   EdgeBuilder(this.typeProvider, this._typeSystem, this._variables, this._graph,
       this.source, this.listener, this._decoratedClassHierarchy,
       {this.instrumentation})
@@ -764,15 +768,17 @@
     final typeArguments = node.typeArguments;
     typeArguments?.accept(this);
     DecoratedType calleeType = _checkExpressionNotNull(node.function);
+    DecoratedType result;
     if (calleeType.type is FunctionType) {
-      return _handleInvocationArguments(node, argumentList.arguments,
+      result = _handleInvocationArguments(node, argumentList.arguments,
           typeArguments, node.typeArgumentTypes, calleeType, null,
           invokeType: node.staticInvokeType);
     } else {
       // Invocation of type `dynamic` or `Function`.
       argumentList.accept(this);
-      return _makeNullableDynamicType(node);
+      result = _makeNullableDynamicType(node);
     }
+    return _handleNullCheckHint(node, result);
   }
 
   @override
@@ -867,21 +873,24 @@
       targetType = _checkExpressionNotNull(target);
     }
     var callee = node.staticElement;
+    DecoratedType result;
     if (callee == null) {
       // Dynamic dispatch.  The return type is `dynamic`.
       // TODO(paulberry): would it be better to assume a return type of `Never`
       // so that we don't unnecessarily propagate nullabilities everywhere?
-      return _makeNullableDynamicType(node);
-    }
-    var calleeType = getOrComputeElementType(callee, targetType: targetType);
-    // TODO(paulberry): substitute if necessary
-    _handleAssignment(node.index,
-        destinationType: calleeType.positionalParameters[0]);
-    if (node.inSetterContext()) {
-      return calleeType.positionalParameters[1];
+      result = _makeNullableDynamicType(node);
     } else {
-      return calleeType.returnType;
+      var calleeType = getOrComputeElementType(callee, targetType: targetType);
+      // TODO(paulberry): substitute if necessary
+      _handleAssignment(node.index,
+          destinationType: calleeType.positionalParameters[0]);
+      if (node.inSetterContext()) {
+        result = calleeType.positionalParameters[1];
+      } else {
+        result = calleeType.returnType;
+      }
     }
+    return _handleNullCheckHint(node, result);
   }
 
   @override
@@ -1060,31 +1069,33 @@
     } else if (target == null && callee.enclosingElement is ClassElement) {
       targetType = _thisOrSuper(node);
     }
+    DecoratedType expressionType;
     if (callee == null) {
       // Dynamic dispatch.  The return type is `dynamic`.
       // TODO(paulberry): would it be better to assume a return type of `Never`
       // so that we don't unnecessarily propagate nullabilities everywhere?
       node.argumentList.accept(this);
-      return _makeNullableDynamicType(node);
+      expressionType = _makeNullableDynamicType(node);
+    } else {
+      var calleeType = getOrComputeElementType(callee, targetType: targetType);
+      if (callee is PropertyAccessorElement) {
+        calleeType = calleeType.returnType;
+      }
+      expressionType = _handleInvocationArguments(
+          node,
+          node.argumentList.arguments,
+          node.typeArguments,
+          node.typeArgumentTypes,
+          calleeType,
+          null,
+          invokeType: node.staticInvokeType);
+      if (isNullAware) {
+        expressionType = expressionType.withNode(
+            NullabilityNode.forLUB(targetType.node, expressionType.node));
+        _variables.recordDecoratedExpressionType(node, expressionType);
+      }
     }
-    var calleeType = getOrComputeElementType(callee, targetType: targetType);
-    if (callee is PropertyAccessorElement) {
-      calleeType = calleeType.returnType;
-    }
-    var expressionType = _handleInvocationArguments(
-        node,
-        node.argumentList.arguments,
-        node.typeArguments,
-        node.typeArgumentTypes,
-        calleeType,
-        null,
-        invokeType: node.staticInvokeType);
-    if (isNullAware) {
-      expressionType = expressionType.withNode(
-          NullabilityNode.forLUB(targetType.node, expressionType.node));
-      _variables.recordDecoratedExpressionType(node, expressionType);
-    }
-    return expressionType;
+    return _handleNullCheckHint(node, expressionType);
   }
 
   @override
@@ -1117,7 +1128,7 @@
   DecoratedType visitParenthesizedExpression(ParenthesizedExpression node) {
     var result = node.expression.accept(this);
     _flowAnalysis.parenthesizedExpression(node, node.expression);
-    return result;
+    return _handleNullCheckHint(node, result);
   }
 
   @override
@@ -1162,8 +1173,9 @@
       // TODO(paulberry)
       _unimplemented(node, 'PrefixedIdentifier with a prefix');
     } else {
-      return _handlePropertyAccess(
+      var type = _handlePropertyAccess(
           node, node.prefix, node.identifier, false, false);
+      return _handleNullCheckHint(node, type);
     }
   }
 
@@ -1208,8 +1220,9 @@
 
   @override
   DecoratedType visitPropertyAccess(PropertyAccess node) {
-    return _handlePropertyAccess(node, node.target, node.propertyName,
+    var type = _handlePropertyAccess(node, node.target, node.propertyName,
         node.isNullAware, node.isCascaded);
+    return _handleNullCheckHint(node, type);
   }
 
   @override
@@ -1242,9 +1255,9 @@
           NullabilityNodeTarget.text('implicit null return').withCodeRef(node);
       var implicitNullType = DecoratedType.forImplicitType(
           typeProvider, typeProvider.nullType, _graph, target);
-      _graph.makeNullable(
-          implicitNullType.node, AlwaysNullableTypeOrigin(source, node));
-      _checkAssignment(ImplicitNullReturnOrigin(source, node),
+      var origin = ImplicitNullReturnOrigin(source, node);
+      _graph.makeNullable(implicitNullType.node, origin);
+      _checkAssignment(origin,
           source:
               isAsync ? _futureOf(implicitNullType, node) : implicitNullType,
           destination: returnType,
@@ -1332,6 +1345,7 @@
 
   @override
   DecoratedType visitSimpleIdentifier(SimpleIdentifier node) {
+    DecoratedType result;
     var staticElement = node.staticElement;
     if (staticElement is PromotableElement) {
       if (!node.inDeclarationContext()) {
@@ -1344,11 +1358,11 @@
           !_flowAnalysis.isAssigned(staticElement)) {
         _graph.makeNullable(type.node, UninitializedReadOrigin(source, node));
       }
-      return type;
+      result = type;
     } else if (staticElement is FunctionElement ||
         staticElement is MethodElement ||
         staticElement is ConstructorElement) {
-      return getOrComputeElementType(staticElement,
+      result = getOrComputeElementType(staticElement,
           targetType: staticElement.enclosingElement is ClassElement
               ? _thisOrSuper(node)
               : null);
@@ -1357,24 +1371,25 @@
           targetType: staticElement.enclosingElement is ClassElement
               ? _thisOrSuper(node)
               : null);
-      return staticElement.isGetter
+      result = staticElement.isGetter
           ? elementType.returnType
           : elementType.positionalParameters[0];
     } else if (staticElement is TypeDefiningElement) {
-      return _makeNonNullLiteralType(node);
+      result = _makeNonNullLiteralType(node);
     } else if (staticElement is ExtensionElement) {
-      return _makeNonNullLiteralType(node);
+      result = _makeNonNullLiteralType(node);
     } else if (staticElement == null) {
       assert(node.toString() == 'void');
-      return _makeNullableVoidType(node);
+      result = _makeNullableVoidType(node);
     } else if (staticElement.enclosingElement is ClassElement &&
         (staticElement.enclosingElement as ClassElement).isEnum) {
-      return getOrComputeElementType(staticElement);
+      result = getOrComputeElementType(staticElement);
     } else {
       // TODO(paulberry)
       _unimplemented(node,
           'Simple identifier with a static element of type ${staticElement.runtimeType}');
     }
+    return _handleNullCheckHint(node, result);
   }
 
   @override
@@ -1484,7 +1499,8 @@
 
   @override
   DecoratedType visitThisExpression(ThisExpression node) {
-    return _thisOrSuper(node);
+    var type = _thisOrSuper(node);
+    return _handleNullCheckHint(node, type);
   }
 
   @override
@@ -1527,69 +1543,78 @@
 
   @override
   DecoratedType visitTypeName(TypeName typeName) {
-    var typeArguments = typeName.typeArguments?.arguments;
-    var element = typeName.name.staticElement;
-    if (element is GenericTypeAliasElement) {
-      final typedefType = _variables.decoratedElementType(element.function);
-      final typeNameType = _variables.decoratedTypeAnnotation(source, typeName);
-
-      Map<TypeParameterElement, DecoratedType> substitutions;
-      if (typeName.typeArguments == null) {
-        // TODO(mfairhurst): substitute instantiations to bounds
-        substitutions = {};
-      } else {
-        substitutions = Map<TypeParameterElement, DecoratedType>.fromIterables(
-            element.typeParameters,
-            typeName.typeArguments.arguments
-                .map((t) => _variables.decoratedTypeAnnotation(source, t)));
-      }
-
-      final decoratedType = typedefType.substitute(substitutions);
-      final origin = TypedefReferenceOrigin(source, typeName);
-      _linkDecoratedTypeParameters(decoratedType, typeNameType, origin,
-          isUnion: true);
-      _linkDecoratedTypes(
-          decoratedType.returnType, typeNameType.returnType, origin,
-          isUnion: true);
-    } else if (element is TypeParameterizedElement) {
-      if (typeArguments == null) {
-        var instantiatedType =
+    try {
+      _typeNameNesting++;
+      var typeArguments = typeName.typeArguments?.arguments;
+      var element = typeName.name.staticElement;
+      if (element is GenericTypeAliasElement) {
+        final typedefType = _variables.decoratedElementType(element.function);
+        final typeNameType =
             _variables.decoratedTypeAnnotation(source, typeName);
-        if (instantiatedType == null) {
-          throw new StateError('No type annotation for type name '
-              '${typeName.toSource()}, offset=${typeName.offset}');
+
+        Map<TypeParameterElement, DecoratedType> substitutions;
+        if (typeName.typeArguments == null) {
+          // TODO(mfairhurst): substitute instantiations to bounds
+          substitutions = {};
+        } else {
+          substitutions =
+              Map<TypeParameterElement, DecoratedType>.fromIterables(
+                  element.typeParameters,
+                  typeName.typeArguments.arguments.map(
+                      (t) => _variables.decoratedTypeAnnotation(source, t)));
         }
-        var origin = InstantiateToBoundsOrigin(source, typeName);
-        for (int i = 0; i < instantiatedType.typeArguments.length; i++) {
-          _linkDecoratedTypes(
-              instantiatedType.typeArguments[i],
-              _variables.decoratedTypeParameterBound(element.typeParameters[i]),
-              origin,
-              isUnion: false);
-        }
-      } else {
-        for (int i = 0; i < typeArguments.length; i++) {
-          DecoratedType bound;
-          bound =
-              _variables.decoratedTypeParameterBound(element.typeParameters[i]);
-          assert(bound != null);
-          var argumentType =
-              _variables.decoratedTypeAnnotation(source, typeArguments[i]);
-          if (argumentType == null) {
-            _unimplemented(typeName,
-                'No decorated type for type argument ${typeArguments[i]} ($i)');
+
+        final decoratedType = typedefType.substitute(substitutions);
+        final origin = TypedefReferenceOrigin(source, typeName);
+        _linkDecoratedTypeParameters(decoratedType, typeNameType, origin,
+            isUnion: true);
+        _linkDecoratedTypes(
+            decoratedType.returnType, typeNameType.returnType, origin,
+            isUnion: true);
+      } else if (element is TypeParameterizedElement) {
+        if (typeArguments == null) {
+          var instantiatedType =
+              _variables.decoratedTypeAnnotation(source, typeName);
+          if (instantiatedType == null) {
+            throw new StateError('No type annotation for type name '
+                '${typeName.toSource()}, offset=${typeName.offset}');
           }
-          _checkAssignment(
-              TypeParameterInstantiationOrigin(source, typeArguments[i]),
-              source: argumentType,
-              destination: bound,
-              hard: true);
+          var origin = InstantiateToBoundsOrigin(source, typeName);
+          for (int i = 0; i < instantiatedType.typeArguments.length; i++) {
+            _linkDecoratedTypes(
+                instantiatedType.typeArguments[i],
+                _variables
+                    .decoratedTypeParameterBound(element.typeParameters[i]),
+                origin,
+                isUnion: false);
+          }
+        } else {
+          for (int i = 0; i < typeArguments.length; i++) {
+            DecoratedType bound;
+            bound = _variables
+                .decoratedTypeParameterBound(element.typeParameters[i]);
+            assert(bound != null);
+            var argumentType =
+                _variables.decoratedTypeAnnotation(source, typeArguments[i]);
+            if (argumentType == null) {
+              _unimplemented(typeName,
+                  'No decorated type for type argument ${typeArguments[i]} ($i)');
+            }
+            _checkAssignment(
+                TypeParameterInstantiationOrigin(source, typeArguments[i]),
+                source: argumentType,
+                destination: bound,
+                hard: true);
+          }
         }
       }
+      typeName.visitChildren(this);
+      typeNameVisited(
+          typeName); // Note this has been visited to TypeNameTracker.
+      return null;
+    } finally {
+      _typeNameNesting--;
     }
-    typeName.visitChildren(this);
-    typeNameVisited(typeName); // Note this has been visited to TypeNameTracker.
-    return null;
   }
 
   @override
@@ -2447,6 +2472,22 @@
     return calleeType.returnType;
   }
 
+  DecoratedType _handleNullCheckHint(
+      Expression expression, DecoratedType type) {
+    // Sometimes we think we're looking at an expression but we're really not
+    // because we're inside a type name.  If this happens, ignore trailing
+    // `/*!*/`s because they're not expression null check hints, they're type
+    // non-nullability hints (which are handled by NodeBuilder).
+    if (_typeNameNesting > 0) return type;
+    switch (getPostfixHint(expression)) {
+      case NullabilityComment.bang:
+        _variables.recordNullCheckHint(source, expression);
+        return type.withNode(_graph.never);
+      default:
+        return type;
+    }
+  }
+
   DecoratedType _handlePropertyAccess(Expression node, Expression target,
       SimpleIdentifier propertyName, bool isNullAware, bool isCascaded) {
     DecoratedType targetType;
@@ -2600,7 +2641,7 @@
     var decoratedType = DecoratedType.forImplicitType(
         typeProvider, typeProvider.dynamicType, _graph, target);
     _graph.makeNullable(
-        decoratedType.node, AlwaysNullableTypeOrigin(source, astNode));
+        decoratedType.node, AlwaysNullableTypeOrigin(source, astNode, false));
     return decoratedType;
   }
 
@@ -2609,7 +2650,7 @@
     var decoratedType = DecoratedType.forImplicitType(
         typeProvider, typeProvider.voidType, _graph, target);
     _graph.makeNullable(
-        decoratedType.node, AlwaysNullableTypeOrigin(source, astNode));
+        decoratedType.node, AlwaysNullableTypeOrigin(source, astNode, true));
     return decoratedType;
   }
 
@@ -2630,8 +2671,8 @@
 
     NullabilityNode makeNonNullableNode(NullabilityNodeTarget target) {
       var nullabilityNode = NullabilityNode.forInferredType(target);
-      _graph.makeNonNullableUnion(
-          nullabilityNode, ThisOrSuperOrigin(source, node));
+      _graph.makeNonNullableUnion(nullabilityNode,
+          ThisOrSuperOrigin(source, node, node is ThisExpression));
       return nullabilityNode;
     }
 
diff --git a/pkg/nnbd_migration/lib/src/edge_origin.dart b/pkg/nnbd_migration/lib/src/edge_origin.dart
index 481783a..e71c1b4 100644
--- a/pkg/nnbd_migration/lib/src/edge_origin.dart
+++ b/pkg/nnbd_migration/lib/src/edge_origin.dart
@@ -23,10 +23,17 @@
 /// [NullabilityMigrationInstrumentation.externalDecoratedType] and
 /// [NullabilityMigrationInstrumentation.externalDecoratedTypeParameterBound].
 class AlreadyMigratedTypeOrigin extends EdgeOrigin {
-  AlreadyMigratedTypeOrigin.forElement(Element element)
+  /// Indicates whether the already-migrated type is nullable or not.
+  final bool isNullable;
+
+  AlreadyMigratedTypeOrigin.forElement(Element element, this.isNullable)
       : super.forElement(element);
 
   @override
+  String get description => '${isNullable ? 'nullable' : 'non-nullable'}'
+      ' type in already-migrated code';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.alreadyMigratedType;
 }
 
@@ -39,12 +46,21 @@
 /// parameter, due to the fact that the `dynamic` type is always considered
 /// nullable.
 class AlwaysNullableTypeOrigin extends EdgeOrigin {
-  AlwaysNullableTypeOrigin(Source source, AstNode node) : super(source, node);
+  /// Indicates whether the always-nullable type is the `void` type (if `false`,
+  /// it is the `dynamic` type).
+  final bool isVoid;
 
-  AlwaysNullableTypeOrigin.forElement(Element element)
+  AlwaysNullableTypeOrigin(Source source, AstNode node, this.isVoid)
+      : super(source, node);
+
+  AlwaysNullableTypeOrigin.forElement(Element element, this.isVoid)
       : super.forElement(element);
 
   @override
+  String get description =>
+      '${isVoid ? 'void' : 'dynamic'} type is nullable by definition';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.alwaysNullableType;
 }
 
@@ -55,27 +71,24 @@
       : super(source, node);
 
   @override
+  String get description => 'compound assignment';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.compoundAssignment;
 
   @override
   AssignmentExpression get node => super.node as AssignmentExpression;
 }
 
-/// An edge origin used for edges that originated because of a default value on
-/// a parameter.
-class DefaultValueOrigin extends EdgeOrigin {
-  DefaultValueOrigin(Source source, Expression node) : super(source, node);
-
-  @override
-  EdgeOriginKind get kind => EdgeOriginKind.defaultValue;
-}
-
 /// An edge origin used for edges that originated because of an assignment
 /// involving a value with a dynamic type.
 class DynamicAssignmentOrigin extends EdgeOrigin {
   DynamicAssignmentOrigin(Source source, AstNode node) : super(source, node);
 
   @override
+  String get description => 'assignment of dynamic value';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.dynamicAssignment;
 }
 
@@ -106,6 +119,9 @@
     }
     return null;
   }
+
+  /// User-friendly description of the edge.
+  String get description;
 }
 
 /// An edge origin used for edges that originated because of a reference to an
@@ -114,6 +130,9 @@
   EnumValueOrigin(Source source, AstNode node) : super(source, node);
 
   @override
+  String get description => 'non-nullable enum value';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.enumValue;
 }
 
@@ -124,6 +143,9 @@
       : super(source, node);
 
   @override
+  String get description => 'field formal parameter';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.fieldFormalParameter;
 }
 
@@ -137,6 +159,9 @@
   FieldNotInitializedOrigin(Source source, AstNode node) : super(source, node);
 
   @override
+  String get description => 'field not initialized';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.fieldNotInitialized;
 }
 
@@ -153,6 +178,9 @@
   ForEachVariableOrigin(Source source, ForEachParts node) : super(source, node);
 
   @override
+  String get description => 'variable in "for each" loop';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.forEachVariable;
 }
 
@@ -169,6 +197,9 @@
   GreatestLowerBoundOrigin(Source source, AstNode node) : super(source, node);
 
   @override
+  String get description => 'greatest lower bound';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.greatestLowerBound;
 }
 
@@ -177,6 +208,9 @@
   IfNullOrigin(Source source, AstNode node) : super(source, node);
 
   @override
+  String get description => 'if-null operator';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.ifNull;
 }
 
@@ -198,6 +232,9 @@
       : super(source, node);
 
   @override
+  String get description => 'implicit super call in mixin constructor';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.implicitMixinSuperCall;
 }
 
@@ -208,6 +245,9 @@
       : super(source, node);
 
   @override
+  String get description => 'uninitialized variable';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.implicitNullInitializer;
 }
 
@@ -218,6 +258,9 @@
       : super(source, node);
 
   @override
+  String get description => 'implicit return of null';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.implicitNullReturn;
 
   @override
@@ -231,16 +274,10 @@
       : super(source, node);
 
   @override
-  EdgeOriginKind get kind => EdgeOriginKind.inferredTypeParameterInstantiation;
-}
-
-/// Edge origin resulting from a type that is inferred from its initializer.
-class InitializerInferenceOrigin extends EdgeOrigin {
-  InitializerInferenceOrigin(Source source, VariableDeclaration node)
-      : super(source, node);
+  String get description => 'inferred type parameter';
 
   @override
-  EdgeOriginKind get kind => EdgeOriginKind.initializerInference;
+  EdgeOriginKind get kind => EdgeOriginKind.inferredTypeParameterInstantiation;
 }
 
 /// An edge origin used for edges that originated because of an instance
@@ -249,6 +286,9 @@
   InstanceCreationOrigin(Source source, AstNode node) : super(source, node);
 
   @override
+  String get description => 'instance creation';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.instanceCreation;
 }
 
@@ -264,6 +304,9 @@
   InstantiateToBoundsOrigin(Source source, TypeName node) : super(source, node);
 
   @override
+  String get description => 'type instantiated to bounds';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.instantiateToBounds;
 }
 
@@ -277,6 +320,9 @@
       : super(source, node);
 
   @override
+  String get description => '"is" check does not accept null';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.isCheckMainType;
 }
 
@@ -287,6 +333,9 @@
       : super(source, node);
 
   @override
+  String get description => 'construction of list via a length';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.listLengthConstructor;
 }
 
@@ -296,6 +345,9 @@
   LiteralOrigin(Source source, AstNode node) : super(source, node);
 
   @override
+  String get description => 'literal expression';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.literal;
 }
 
@@ -316,6 +368,9 @@
       : super(source, node);
 
   @override
+  String get description => 'named parameter not supplied';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.namedParameterNotSupplied;
 }
 
@@ -325,6 +380,9 @@
   NonNullableBoolTypeOrigin(Source source, AstNode node) : super(source, node);
 
   @override
+  String get description => 'non-null boolean expression';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.nonNullableBoolType;
 }
 
@@ -335,6 +393,9 @@
       : super(source, node);
 
   @override
+  String get description => 'implicit supertype of Object';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.nonNullableObjectSuperclass;
 }
 
@@ -344,6 +405,9 @@
   NonNullableUsageOrigin(Source source, AstNode node) : super(source, node);
 
   @override
+  String get description => 'value cannot be null';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.nonNullableUsage;
 }
 
@@ -360,6 +424,9 @@
   NonNullAssertionOrigin(Source source, Assertion node) : super(source, node);
 
   @override
+  String get description => 'value asserted to be non-null';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.nonNullAssertion;
 }
 
@@ -372,10 +439,18 @@
 /// this class is used for the edge connecting `always` to the type of f's `i`
 /// parameter, due to the presence of the `/*?*/` comment.
 class NullabilityCommentOrigin extends EdgeOrigin {
-  NullabilityCommentOrigin(Source source, TypeAnnotation node)
+  /// Indicates whether the nullability comment makes the type nullable or
+  /// non-nullable.
+  final bool isNullable;
+
+  NullabilityCommentOrigin(Source source, TypeAnnotation node, this.isNullable)
       : super(source, node);
 
   @override
+  String get description =>
+      'explicitly hinted to be ${isNullable ? 'nullable' : 'non-nullable'}';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.nullabilityComment;
 }
 
@@ -391,6 +466,9 @@
       : super(source, node);
 
   @override
+  String get description => 'optional formal parameter must be nullable';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.optionalFormalParameter;
 }
 
@@ -400,6 +478,9 @@
   ParameterInheritanceOrigin(Source source, AstNode node) : super(source, node);
 
   @override
+  String get description => 'function parameter override';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.parameterInheritance;
 }
 
@@ -410,6 +491,9 @@
       : super(source, node);
 
   @override
+  String get description => 'function return type override';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.returnTypeInheritance;
 }
 
@@ -420,12 +504,24 @@
   StackTraceTypeOrigin(Source source, AstNode node) : super(source, node);
 
   @override
+  String get description => 'stack trace variable is nullable';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.stackTraceTypeOrigin;
 }
 
 /// Edge origin resulting from the use of `this` or `super`.
 class ThisOrSuperOrigin extends EdgeOrigin {
-  ThisOrSuperOrigin(Source source, AstNode node) : super(source, node);
+  /// Indicates whether the expression in question is `this`.  If `false`, the
+  /// expression in question is `super`.
+  final bool isThis;
+
+  ThisOrSuperOrigin(Source source, AstNode node, this.isThis)
+      : super(source, node);
+
+  @override
+  String get description =>
+      'type of "${isThis ? 'this' : 'super'}" is non-nullable';
 
   @override
   EdgeOriginKind get kind => EdgeOriginKind.thisOrSuper;
@@ -437,6 +533,10 @@
   ThrowOrigin(Source source, AstNode node) : super(source, node);
 
   @override
+  String get description =>
+      'type of thrown expression is presumed non-nullable';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.throw_;
 }
 
@@ -450,6 +550,9 @@
   TypedefReferenceOrigin(Source source, TypeName node) : super(source, node);
 
   @override
+  String get description => 'reference to typedef';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.typedefReference;
 }
 
@@ -460,6 +563,9 @@
       : super(source, node);
 
   @override
+  String get description => 'type parameter instantiation';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.typeParameterInstantiation;
 
   @override
@@ -472,5 +578,8 @@
   UninitializedReadOrigin(Source source, AstNode node) : super(source, node);
 
   @override
+  String get description => 'local variable might not be initialized';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.uninitializedRead;
 }
diff --git a/pkg/nnbd_migration/lib/src/expression_checks.dart b/pkg/nnbd_migration/lib/src/expression_checks.dart
index dd7ba9f..17d4459 100644
--- a/pkg/nnbd_migration/lib/src/expression_checks.dart
+++ b/pkg/nnbd_migration/lib/src/expression_checks.dart
@@ -86,5 +86,8 @@
       : super(source, node);
 
   @override
+  String get description => 'data flow';
+
+  @override
   EdgeOriginKind get kind => EdgeOriginKind.expressionChecks;
 }
diff --git a/pkg/nnbd_migration/lib/src/fix_aggregator.dart b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
index a4c8043..082f4ef 100644
--- a/pkg/nnbd_migration/lib/src/fix_aggregator.dart
+++ b/pkg/nnbd_migration/lib/src/fix_aggregator.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -271,6 +272,29 @@
   }
 }
 
+/// Implementation of [NodeChange] specialized for operating on
+/// [CompilationUnit] nodes.
+class NodeChangeForCompilationUnit extends NodeChange<CompilationUnit> {
+  bool removeLanguageVersionComment = false;
+
+  NodeChangeForCompilationUnit() : super._();
+
+  @override
+  EditPlan _apply(CompilationUnit node, FixAggregator aggregator) {
+    List<EditPlan> innerPlans = [];
+    if (removeLanguageVersionComment) {
+      final comment = (node as CompilationUnitImpl).languageVersionToken;
+      assert(comment != null);
+      innerPlans.add(aggregator.planner.replaceToken(node, comment, [],
+          info: AtomicEditInfo(
+              NullabilityFixDescription.removeLanguageVersionComment,
+              const [])));
+    }
+    innerPlans.addAll(aggregator.innerPlansForNode(node));
+    return aggregator.planner.passThrough(node, innerPlans: innerPlans);
+  }
+}
+
 /// Common infrastructure used by [NodeChange] objects that operate on AST nodes
 /// with conditional behavior (if statements, if elements, and conditional
 /// expressions).
@@ -404,7 +428,6 @@
   /// Causes a null check to be added to this expression, with the given [info].
   void addNullCheck(AtomicEditInfo info) {
     assert(!_addsNullCheck);
-    assert(_introducesAsType == null);
     _addsNullCheck = true;
     _addNullCheckInfo = info;
   }
@@ -412,7 +435,6 @@
   /// Causes a cast to the given [type] to be added to this expression, with
   /// the given [info].
   void introduceAs(DartType type, AtomicEditInfo info) {
-    assert(!_addsNullCheck);
     assert(_introducesAsType == null);
     assert(type != null);
     _introducesAsType = type;
@@ -430,16 +452,17 @@
   /// Otherwise returns [innerPlan] unchanged.
   NodeProducingEditPlan _applyExpression(
       FixAggregator aggregator, NodeProducingEditPlan innerPlan) {
+    var plan = innerPlan;
     if (_addsNullCheck) {
-      return aggregator.planner
-          .addUnaryPostfix(innerPlan, TokenType.BANG, info: _addNullCheckInfo);
-    } else if (_introducesAsType != null) {
-      return aggregator.planner.addBinaryPostfix(
-          innerPlan, TokenType.AS, aggregator.typeToCode(_introducesAsType),
-          info: _introduceAsInfo);
-    } else {
-      return innerPlan;
+      plan = aggregator.planner
+          .addUnaryPostfix(plan, TokenType.BANG, info: _addNullCheckInfo);
     }
+    if (_introducesAsType != null) {
+      plan = aggregator.planner.addBinaryPostfix(
+          plan, TokenType.AS, aggregator.typeToCode(_introducesAsType),
+          info: _introduceAsInfo);
+    }
+    return plan;
   }
 }
 
@@ -639,6 +662,10 @@
       NodeChangeForAsExpression();
 
   @override
+  NodeChange visitCompilationUnit(CompilationUnit node) =>
+      NodeChangeForCompilationUnit();
+
+  @override
   NodeChange visitDefaultFormalParameter(DefaultFormalParameter node) =>
       NodeChangeForDefaultFormalParameter();
 
diff --git a/pkg/nnbd_migration/lib/src/fix_builder.dart b/pkg/nnbd_migration/lib/src/fix_builder.dart
index 76b1db7..3019ad6 100644
--- a/pkg/nnbd_migration/lib/src/fix_builder.dart
+++ b/pkg/nnbd_migration/lib/src/fix_builder.dart
@@ -385,6 +385,9 @@
   @override
   DartType modifyExpressionType(Expression node, DartType type) =>
       _wrapExceptions(node, () => type, () {
+        if (_fixBuilder._variables.hasNullCheckHint(_fixBuilder.source, node)) {
+          type = _addNullCheck(node, type);
+        }
         if (type.isDynamic) return type;
         var ancestor = _findNullabilityContextAncestor(node);
         var context =
@@ -580,6 +583,15 @@
   }
 
   @override
+  void visitCompilationUnit(CompilationUnit node) {
+    if ((node as CompilationUnitImpl).languageVersionToken != null) {
+      (_fixBuilder._getChange(node) as NodeChangeForCompilationUnit)
+          .removeLanguageVersionComment = true;
+    }
+    super.visitCompilationUnit(node);
+  }
+
+  @override
   void visitSimpleFormalParameter(SimpleFormalParameter node) {
     if (node.type == null) {
       var typeToAdd = _fixBuilder._addedParameterTypes[node.declaredElement];
@@ -651,6 +663,8 @@
           _fixBuilder._addProblem(
               node, const NonNullableUnnamedOptionalParameter());
         }
+      } else if (element.metadata.any((m) => m.isRequired)) {
+        _addRequiredKeyword(node, nullabilityNode);
       }
     }
     super.visitDefaultFormalParameter(node);
diff --git a/pkg/nnbd_migration/lib/src/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
index e0e5a2f..f50f396 100644
--- a/pkg/nnbd_migration/lib/src/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -2,7 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:_fe_analyzer_shared/src/scanner/token.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -14,15 +13,15 @@
 import 'package:meta/meta.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
-import 'package:nnbd_migration/src/conditional_discard.dart';
 import 'package:nnbd_migration/src/decorated_type.dart';
-import 'package:nnbd_migration/src/expression_checks.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
 import 'package:nnbd_migration/src/nullability_node_target.dart';
 import 'package:nnbd_migration/src/potential_modification.dart';
 import 'package:nnbd_migration/src/utilities/completeness_tracker.dart';
+import 'package:nnbd_migration/src/utilities/hint_utils.dart';
 import 'package:nnbd_migration/src/utilities/permissive_mode.dart';
 import 'package:nnbd_migration/src/utilities/resolution_utils.dart';
+import 'package:nnbd_migration/src/variables.dart';
 
 import 'edge_origin.dart';
 
@@ -37,7 +36,7 @@
         PermissiveModeVisitor<DecoratedType>,
         CompletenessTracker<DecoratedType> {
   /// Constraint variables and decorated types are stored here.
-  final VariableRecorder _variables;
+  final Variables _variables;
 
   @override
   final Source source;
@@ -502,17 +501,16 @@
         decoratedType,
         PotentiallyAddQuestionSuffix(
             nullabilityNode, decoratedType.type, node.end));
-    var commentToken = node.endToken.next.precedingComments;
-    switch (_classifyComment(commentToken)) {
-      case _NullabilityComment.bang:
+    switch (getPostfixHint(node)) {
+      case NullabilityComment.bang:
         _graph.makeNonNullableUnion(
-            decoratedType.node, NullabilityCommentOrigin(source, node));
+            decoratedType.node, NullabilityCommentOrigin(source, node, false));
         break;
-      case _NullabilityComment.question:
+      case NullabilityComment.question:
         _graph.makeNullableUnion(
-            decoratedType.node, NullabilityCommentOrigin(source, node));
+            decoratedType.node, NullabilityCommentOrigin(source, node, true));
         break;
-      case _NullabilityComment.none:
+      case NullabilityComment.none:
         break;
     }
     return decoratedType;
@@ -536,7 +534,7 @@
           NullabilityNodeTarget.typeParameterBound(element));
       decoratedBound = DecoratedType(_typeProvider.objectType, nullabilityNode);
       _graph.connect(_graph.always, nullabilityNode,
-          AlwaysNullableTypeOrigin.forElement(element));
+          AlwaysNullableTypeOrigin.forElement(element, false));
     }
     DecoratedTypeParameterBounds.current.put(element, decoratedBound);
     return null;
@@ -562,14 +560,6 @@
     return null;
   }
 
-  _NullabilityComment _classifyComment(Token token) {
-    if (token is CommentToken) {
-      if (token.lexeme == '/*!*/') return _NullabilityComment.bang;
-      if (token.lexeme == '/*?*/') return _NullabilityComment.question;
-    }
-    return _NullabilityComment.none;
-  }
-
   DecoratedType _createDecoratedTypeForClass(
       ClassElement classElement, AstNode node) {
     var typeArguments = classElement.typeParameters
@@ -763,94 +753,3 @@
     throw UnimplementedError(buffer.toString());
   }
 }
-
-/// Repository of constraint variables and decorated types corresponding to the
-/// code being migrated.
-///
-/// This data structure records the results of the first pass of migration
-/// ([NodeBuilder], which finds all the variables that need to be
-/// constrained).
-abstract class VariableRecorder {
-  /// Associates a [class_] with decorated type information for the superclasses
-  /// it directly implements/extends/etc.
-  void recordDecoratedDirectSupertypes(ClassElement class_,
-      Map<ClassElement, DecoratedType> decoratedDirectSupertypes);
-
-  /// Associates decorated type information with the given [element].
-  void recordDecoratedElementType(Element element, DecoratedType type);
-
-  /// Associates decorated type information with the given [type] node.
-  void recordDecoratedTypeAnnotation(Source source, TypeAnnotation node,
-      DecoratedType type, PotentiallyAddQuestionSuffix potentialModification);
-
-  /// Records that [node] is associated with the question of whether the named
-  /// [parameter] should be optional (should not have a `required`
-  /// annotation added to it).
-  void recordPossiblyOptional(
-      Source source, DefaultFormalParameter parameter, NullabilityNode node);
-}
-
-/// Repository of constraint variables and decorated types corresponding to the
-/// code being migrated.
-///
-/// This data structure allows the second pass of migration
-/// ([ConstraintGatherer], which builds all the constraints) to access the
-/// results of the first ([NodeBuilder], which finds all the
-/// variables that need to be constrained).
-abstract class VariableRepository {
-  /// Given a [class_], gets the decorated type information for the superclasses
-  /// it directly implements/extends/etc.
-  Map<ClassElement, DecoratedType> decoratedDirectSupertypes(
-      ClassElement class_);
-
-  /// Retrieves the [DecoratedType] associated with the static type of the given
-  /// [element].
-  ///
-  /// If no decorated type is found for the given element, and the element is in
-  /// a library that's not being migrated, a decorated type is synthesized using
-  /// [DecoratedType.forElement].
-  DecoratedType decoratedElementType(Element element);
-
-  /// Gets the [DecoratedType] associated with the given [typeAnnotation].
-  DecoratedType decoratedTypeAnnotation(
-      Source source, TypeAnnotation typeAnnotation);
-
-  /// Retrieves the decorated bound of the given [typeParameter].
-  DecoratedType decoratedTypeParameterBound(TypeParameterElement typeParameter);
-
-  /// Records conditional discard information for the given AST node (which is
-  /// an `if` statement or a conditional (`?:`) expression).
-  void recordConditionalDiscard(
-      Source source, AstNode node, ConditionalDiscard conditionalDiscard);
-
-  /// Associates decorated type information with the given [element].
-  ///
-  /// TODO(paulberry): why is this in both [VariableRecorder] and
-  /// [VariableRepository]?
-  void recordDecoratedElementType(Element element, DecoratedType type);
-
-  /// Associates decorated type information with the given expression [node].
-  void recordDecoratedExpressionType(Expression node, DecoratedType type);
-
-  /// Associates a set of nullability checks with the given expression [node].
-  void recordExpressionChecks(
-      Source source, Expression expression, ExpressionChecksOrigin origin);
-
-  /// Records the fact that prior to migration, an unnecessary cast existed at
-  /// [node].
-  void recordUnnecessaryCast(Source source, AsExpression node);
-}
-
-/// Types of comments that can influence nullability
-enum _NullabilityComment {
-  /// The comment `/*!*/`, which indicates that the type should not have a `?`
-  /// appended.
-  bang,
-
-  /// The comment `/*?*/`, which indicates that the type should have a `?`
-  /// appended.
-  question,
-
-  /// No special comment.
-  none,
-}
diff --git a/pkg/nnbd_migration/lib/src/nullability_node.dart b/pkg/nnbd_migration/lib/src/nullability_node.dart
index 6031c97..1f1b1b3 100644
--- a/pkg/nnbd_migration/lib/src/nullability_node.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_node.dart
@@ -84,13 +84,16 @@
   /// The location in the source code that caused this edge to be built.
   final CodeReference codeReference;
 
+  final String description;
+
   NullabilityEdge.fromJson(
       dynamic json, NullabilityGraphDeserializer deserializer)
       : destinationNode = deserializer.nodeForId(json['dest'] as int),
         upstreamNodes = [],
         _kind = _deserializeKind(json['kind']),
         codeReference =
-            json['code'] == null ? null : CodeReference.fromJson(json['code']) {
+            json['code'] == null ? null : CodeReference.fromJson(json['code']),
+        description = json['description'] as String {
     deserializer.defer(() {
       for (var id in json['us'] as List<dynamic>) {
         upstreamNodes.add(deserializer.nodeForId(id as int));
@@ -98,7 +101,8 @@
     });
   }
 
-  NullabilityEdge._(this.destinationNode, this.upstreamNodes, this._kind,
+  NullabilityEdge._(
+      this.destinationNode, this.upstreamNodes, this._kind, this.description,
       {this.codeReference});
 
   @override
@@ -156,6 +160,7 @@
         break;
     }
     if (codeReference != null) json['code'] = codeReference.toJson();
+    if (description != null) json['description'] = description;
     serializer.defer(() {
       json['dest'] = serializer.idForNode(destinationNode);
       json['us'] = [for (var n in upstreamNodes) serializer.idForNode(n)];
@@ -424,7 +429,8 @@
       NullabilityNode destinationNode,
       _NullabilityEdgeKind kind,
       EdgeOrigin origin) {
-    var edge = NullabilityEdge._(destinationNode, upstreamNodes, kind,
+    var edge = NullabilityEdge._(
+        destinationNode, upstreamNodes, kind, origin?.description,
         codeReference: origin?.codeReference);
     instrumentation?.graphEdge(edge, origin);
     for (var upstreamNode in upstreamNodes) {
@@ -1082,6 +1088,9 @@
         super.fromJson(json, deserializer);
 
   @override
+  EdgeInfo get edge => null;
+
+  @override
   Map<String, Object> toJson(NullabilityGraphSerializer serializer) {
     var json = super.toJson(serializer);
     json['kind'] = 'resolveSubstitution';
@@ -1102,7 +1111,7 @@
   @override
   final DownstreamPropagationStep principalCause;
 
-  /// The nullability edge whose sources are nullable.
+  @override
   final NullabilityEdge edge;
 
   SimpleDownstreamPropagationStep(this.principalCause, this.edge);
@@ -1138,6 +1147,7 @@
   @override
   final ExactNullablePropagationStep principalCause;
 
+  @override
   final NullabilityEdge edge;
 
   SimpleExactNullablePropagationStep(this.principalCause, this.edge);
diff --git a/pkg/nnbd_migration/lib/src/utilities/hint_utils.dart b/pkg/nnbd_migration/lib/src/utilities/hint_utils.dart
new file mode 100644
index 0000000..4dac293
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/utilities/hint_utils.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+
+/// Determine if the given token is a nullability hint, and if so, return the
+/// type of nullability hint it is.
+NullabilityComment classifyComment(Token token) {
+  if (token is CommentToken) {
+    if (token.lexeme == '/*!*/') return NullabilityComment.bang;
+    if (token.lexeme == '/*?*/') return NullabilityComment.question;
+  }
+  return NullabilityComment.none;
+}
+
+/// Determine if the given [node] is followed by a nullability hint, and if so,
+/// return the type of nullability hint it is followed by.
+NullabilityComment getPostfixHint(AstNode node) {
+  var commentToken = node.endToken.next.precedingComments;
+  var commentType = classifyComment(commentToken);
+  return commentType;
+}
+
+/// Types of comments that can influence nullability
+enum NullabilityComment {
+  /// The comment `/*!*/`, which indicates that the type should not have a `?`
+  /// appended.
+  bang,
+
+  /// The comment `/*?*/`, which indicates that the type should have a `?`
+  /// appended.
+  question,
+
+  /// No special comment.
+  none,
+}
diff --git a/pkg/nnbd_migration/lib/src/variables.dart b/pkg/nnbd_migration/lib/src/variables.dart
index 2445e76..1d537c9 100644
--- a/pkg/nnbd_migration/lib/src/variables.dart
+++ b/pkg/nnbd_migration/lib/src/variables.dart
@@ -23,7 +23,6 @@
 import 'package:nnbd_migration/src/decorated_type.dart';
 import 'package:nnbd_migration/src/expression_checks.dart';
 import 'package:nnbd_migration/src/fix_builder.dart';
-import 'package:nnbd_migration/src/node_builder.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
 import 'package:nnbd_migration/src/nullability_node_target.dart';
 import 'package:nnbd_migration/src/postmortem_file.dart';
@@ -42,7 +41,7 @@
   String toString() => '$offset-$end';
 }
 
-class Variables implements VariableRecorder, VariableRepository {
+class Variables {
   final NullabilityGraph _graph;
 
   final TypeProvider _typeProvider;
@@ -58,6 +57,8 @@
 
   final _expressionChecks = <Source, Map<int, ExpressionChecks>>{};
 
+  final _nullCheckHints = <Source, Set<int>>{};
+
   final _potentialModifications = <Source, List<PotentialModification>>{};
 
   final _unnecessaryCasts = <Source, Set<int>>{};
@@ -73,14 +74,20 @@
       : _alreadyMigratedCodeDecorator =
             AlreadyMigratedCodeDecorator(_graph, _typeProvider);
 
-  @override
+  /// Given a [class_], gets the decorated type information for the superclasses
+  /// it directly implements/extends/etc.
   Map<ClassElement, DecoratedType> decoratedDirectSupertypes(
       ClassElement class_) {
     return _decoratedDirectSupertypes[class_] ??=
         _decorateDirectSupertypes(class_);
   }
 
-  @override
+  /// Retrieves the [DecoratedType] associated with the static type of the given
+  /// [element].
+  ///
+  /// If no decorated type is found for the given element, and the element is in
+  /// a library that's not being migrated, a decorated type is synthesized using
+  /// [DecoratedType.forElement].
   DecoratedType decoratedElementType(Element element) {
     assert(element is! TypeParameterElement,
         'Use decoratedTypeParameterBound instead');
@@ -88,7 +95,7 @@
         _createDecoratedElementType(element);
   }
 
-  @override
+  /// Gets the [DecoratedType] associated with the given [typeAnnotation].
   DecoratedType decoratedTypeAnnotation(
       Source source, TypeAnnotation typeAnnotation) {
     var annotationsInSource = _decoratedTypeAnnotations[source];
@@ -106,6 +113,8 @@
     return decoratedTypeAnnotation;
   }
 
+  /// Retrieves the decorated bound of the given [typeParameter].
+  ///
   /// Note: the optional argument [allowNullUnparentedBounds] is intended for
   /// the FixBuilder stage only, to allow it to cope with the situation where
   /// a type parameter element with a null parent doesn't have a decorated type
@@ -115,7 +124,6 @@
   /// because at that point the types we are dealing with are all
   /// post-migration types, so their bounds already reflect the correct
   /// nullabilities.
-  @override
   DecoratedType decoratedTypeParameterBound(TypeParameterElement typeParameter,
       {bool allowNullUnparentedBounds = false}) {
     var enclosingElement = typeParameter.enclosingElement;
@@ -160,7 +168,15 @@
   Map<Source, List<PotentialModification>> getPotentialModifications() =>
       _potentialModifications;
 
-  @override
+  /// Queries whether the given [expression] is followed by a null check hint
+  /// (`/*!*/`).  See [recordNullCheckHint].
+  bool hasNullCheckHint(Source source, Expression expression) {
+    return (_nullCheckHints[source] ?? {})
+        .contains(uniqueIdentifierForSpan(expression.offset, expression.end));
+  }
+
+  /// Records conditional discard information for the given AST node (which is
+  /// an `if` statement or a conditional (`?:`) expression).
   void recordConditionalDiscard(
       Source source, AstNode node, ConditionalDiscard conditionalDiscard) {
     (_conditionalDiscards[source] ??= {})[node.offset] = conditionalDiscard;
@@ -168,12 +184,14 @@
         source, ConditionalModification(node, conditionalDiscard));
   }
 
-  @override
+  /// Associates a [class_] with decorated type information for the superclasses
+  /// it directly implements/extends/etc.
   void recordDecoratedDirectSupertypes(ClassElement class_,
       Map<ClassElement, DecoratedType> decoratedDirectSupertypes) {
     _decoratedDirectSupertypes[class_] = decoratedDirectSupertypes;
   }
 
+  /// Associates decorated type information with the given [element].
   void recordDecoratedElementType(Element element, DecoratedType type) {
     assert(() {
       assert(element is! TypeParameterElement,
@@ -190,8 +208,10 @@
     _decoratedElementTypes[element] = type;
   }
 
+  /// Associates decorated type information with the given expression [node].
   void recordDecoratedExpressionType(Expression node, DecoratedType type) {}
 
+  /// Associates decorated type information with the given [type] node.
   void recordDecoratedTypeAnnotation(Source source, TypeAnnotation node,
       DecoratedType type, PotentiallyAddQuestionSuffix potentialModification) {
     instrumentation?.explicitTypeNullability(source, node, type.node);
@@ -202,7 +222,7 @@
     postmortemFileWriter?.storeFileDecorations(source.fullName, id, type);
   }
 
-  @override
+  /// Associates a set of nullability checks with the given expression [node].
   void recordExpressionChecks(
       Source source, Expression expression, ExpressionChecksOrigin origin) {
     _addPotentialModification(source, origin.checks);
@@ -211,14 +231,24 @@
         origin.checks;
   }
 
-  @override
+  /// Records that the given [expression] is followed by a null check hint
+  /// (`/*!*/`), for later recall by [hasNullCheckHint].
+  void recordNullCheckHint(Source source, Expression expression) {
+    (_nullCheckHints[source] ??= {})
+        .add(uniqueIdentifierForSpan(expression.offset, expression.end));
+  }
+
+  /// Records that [node] is associated with the question of whether the named
+  /// [parameter] should be optional (should not have a `required`
+  /// annotation added to it).
   void recordPossiblyOptional(
       Source source, DefaultFormalParameter parameter, NullabilityNode node) {
     var modification = PotentiallyAddRequired(parameter, node);
     _addPotentialModification(source, modification);
   }
 
-  @override
+  /// Records the fact that prior to migration, an unnecessary cast existed at
+  /// [node].
   void recordUnnecessaryCast(Source source, AsExpression node) {
     bool newlyAdded = (_unnecessaryCasts[source] ??= {})
         .add(uniqueIdentifierForSpan(node.offset, node.end));
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 06dd229..32badb1 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -1697,6 +1697,36 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_expression_bang_hint() async {
+    var content = '''
+int f(int/*?*/ i) => i/*!*/;
+''';
+    var expected = '''
+int f(int?/*?*/ i) => i!/*!*/;
+''';
+    await _checkSingleFileChanges(content, expected, removeViaComments: true);
+  }
+
+  Future<void> test_expression_bang_hint_unnecessary() async {
+    var content = '''
+int/*?*/ f(int/*?*/ i) => i/*!*/;
+''';
+    // The user requested a null check so we should add it even if it's not
+    // required to avoid compile errors.
+    var expected = '''
+int?/*?*/ f(int?/*?*/ i) => i!/*!*/;
+''';
+    await _checkSingleFileChanges(content, expected, removeViaComments: true);
+  }
+
+  Future<void> test_expression_bang_hint_with_cast() async {
+    var content = 'int f(Object/*?*/ o) => o/*!*/;';
+    // TODO(paulberry): it would be better to remove the `/*` and `*/` so we
+    // would be left with `o! as int;`
+    var expected = 'int f(Object?/*?*/ o) => o! as int/*!*/;';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/40023')
   Future<void> test_extension_nullableOnType_addsNullCheckToThis() async {
     var content = '''
@@ -3525,7 +3555,7 @@
 ''';
     var expected = '''
 import 'package:meta/meta.dart';
-void f({@required String? s}) {}
+void f({required String? s}) {}
 main() {
   f(s: null);
 }
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index 9612cea..5f8f5f6 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -498,6 +499,9 @@
     return variables.decoratedExpressionType(findNode.expression(text));
   }
 
+  bool hasNullCheckHint(Expression expression) =>
+      variables.hasNullCheckHint(testSource, expression);
+
   Future<void> test_already_migrated_field() async {
     await analyze('''
 double f() => double.NAN;
@@ -3212,6 +3216,20 @@
     assertEdge(always, decoratedTypeAnnotation('int').node, hard: false);
   }
 
+  Future<void> test_functionExpressionInvocation_bangHint() async {
+    await analyze('''
+int f1(int Function() g1) => g1();
+int f2(int Function() g2) => g2()/*!*/;
+''');
+    assertEdge(decoratedTypeAnnotation('int Function() g1').node,
+        decoratedTypeAnnotation('int f1').node,
+        hard: false);
+    assertNoEdge(decoratedTypeAnnotation('int Function() g2').node,
+        decoratedTypeAnnotation('int f2').node);
+    expect(hasNullCheckHint(findNode.functionExpressionInvocation('g2()')),
+        isTrue);
+  }
+
   Future<void> test_functionExpressionInvocation_parameterType() async {
     await analyze('''
 abstract class C {
@@ -3713,6 +3731,22 @@
     // metadata was visited.
   }
 
+  Future<void> test_indexExpression_bangHint() async {
+    await analyze('''
+abstract class C {
+  int operator[](int index);
+}
+int f1(C c) => c[0];
+int f2(C c) => c[0]/*!*/;
+''');
+    assertEdge(decoratedTypeAnnotation('int operator').node,
+        decoratedTypeAnnotation('int f1').node,
+        hard: false);
+    assertNoEdge(decoratedTypeAnnotation('int operator').node,
+        decoratedTypeAnnotation('int f2').node);
+    expect(hasNullCheckHint(findNode.index('c[0]/*!*/')), isTrue);
+  }
+
   Future<void> test_indexExpression_dynamic() async {
     await analyze('''
 int f(dynamic d, int i) {
@@ -4313,6 +4347,23 @@
     assertEdge(decoratedTypeAnnotation('int k').node, never, hard: true);
   }
 
+  Future<void> test_methodInvocation_bangHint() async {
+    await analyze('''
+abstract class C {
+  int m1();
+  int m2();
+}
+int f1(C c) => c.m1();
+int f2(C c) => c.m2()/*!*/;
+''');
+    assertEdge(decoratedTypeAnnotation('int m1').node,
+        decoratedTypeAnnotation('int f1').node,
+        hard: false);
+    assertNoEdge(decoratedTypeAnnotation('int m2').node,
+        decoratedTypeAnnotation('int f2').node);
+    expect(hasNullCheckHint(findNode.methodInvocation('c.m2')), isTrue);
+  }
+
   Future<void> test_methodInvocation_dynamic() async {
     await analyze('''
 class C {
@@ -4945,6 +4996,11 @@
     expect(never.isNullable, isFalse);
   }
 
+  Future<void> test_non_null_hint_is_not_expression_hint() async {
+    await analyze('int/*!*/ x;');
+    expect(hasNullCheckHint(findNode.simple('int')), isFalse);
+  }
+
   Future<void> test_override_parameter_type_named() async {
     await analyze('''
 abstract class Base {
@@ -5190,6 +5246,19 @@
             hard: false));
   }
 
+  Future<void> test_parenthesizedExpression_bangHint() async {
+    await analyze('''
+int f1(int i1) => (i1);
+int f2(int i2) => (i2)/*!*/;
+''');
+    assertEdge(decoratedTypeAnnotation('int i1').node,
+        decoratedTypeAnnotation('int f1').node,
+        hard: true);
+    assertNoEdge(decoratedTypeAnnotation('int i2').node,
+        decoratedTypeAnnotation('int f2').node);
+    expect(hasNullCheckHint(findNode.parenthesized('(i2)')), isTrue);
+  }
+
   Future<void> test_part_metadata() async {
     var pathContext = resourceProvider.pathContext;
     addSource(pathContext.join(pathContext.dirname(testFile), 'part.dart'), '''
@@ -5884,6 +5953,25 @@
         hard: false, checkable: false);
   }
 
+  Future<void> test_prefixedIdentifier_bangHint() async {
+    await analyze('''
+import 'dart:math' as m;
+double f1() => m.PI;
+double f2() => m.PI/*!*/;
+''');
+    expect(
+        assertEdge(anyNode, decoratedTypeAnnotation('double f1').node,
+                hard: false)
+            .sourceNode,
+        isNot(never));
+    expect(
+        assertEdge(anyNode, decoratedTypeAnnotation('double f2').node,
+                hard: false)
+            .sourceNode,
+        never);
+    expect(hasNullCheckHint(findNode.prefixed('m.PI/*!*/')), isTrue);
+  }
+
   Future<void> test_prefixedIdentifier_field_type() async {
     await analyze('''
 class C {
@@ -6137,6 +6225,23 @@
         hard: false);
   }
 
+  Future<void> test_propertyAccess_bangHint() async {
+    await analyze('''
+abstract class C {
+  int get i1;
+  int get i2;
+}
+int f1(C c) => (c).i1;
+int f2(C c) => (c).i2/*!*/;
+''');
+    assertEdge(decoratedTypeAnnotation('int get i1').node,
+        decoratedTypeAnnotation('int f1').node,
+        hard: false);
+    assertNoEdge(decoratedTypeAnnotation('int get i2').node,
+        decoratedTypeAnnotation('int f2').node);
+    expect(hasNullCheckHint(findNode.propertyAccess('(c).i2')), isTrue);
+  }
+
   Future<void> test_propertyAccess_dynamic() async {
     await analyze('''
 class C {
@@ -6665,6 +6770,19 @@
     assertEdge(string1.node, string2.node, hard: true);
   }
 
+  Future<void> test_simpleIdentifier_bangHint() async {
+    await analyze('''
+int f1(int i1) => i1;
+int f2(int i2) => i2/*!*/;
+''');
+    assertEdge(decoratedTypeAnnotation('int i1').node,
+        decoratedTypeAnnotation('int f1').node,
+        hard: true);
+    assertNoEdge(decoratedTypeAnnotation('int i2').node,
+        decoratedTypeAnnotation('int f2').node);
+    expect(hasNullCheckHint(findNode.simple('i2/*!*/')), isTrue);
+  }
+
   Future<void> test_simpleIdentifier_function() async {
     await analyze('''
 int f() => null;
@@ -6897,6 +7015,24 @@
     assertNoUpstreamNullability(decoratedTypeAnnotation('Symbol').node);
   }
 
+  Future<void> test_this_bangHint() async {
+    await analyze('''
+extension on int {
+  int f1() => this;
+  int f2() => this/*!*/;
+}
+''');
+    expect(
+        assertEdge(anyNode, decoratedTypeAnnotation('int f1').node, hard: false)
+            .sourceNode,
+        isNot(never));
+    expect(
+        assertEdge(anyNode, decoratedTypeAnnotation('int f2').node, hard: false)
+            .sourceNode,
+        never);
+    expect(hasNullCheckHint(findNode.this_('this/*!*/')), isTrue);
+  }
+
   Future<void> test_thisExpression() async {
     await analyze('''
 class C {
@@ -7270,5 +7406,11 @@
   @override
   CodeReference get codeReference => null;
 
+  @override
+  String get description => 'Test edge';
+
+  @override
+  EdgeOriginKind get kind => null;
+
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
diff --git a/pkg/nnbd_migration/test/fix_aggregator_test.dart b/pkg/nnbd_migration/test/fix_aggregator_test.dart
index e50444b..6abb6ef 100644
--- a/pkg/nnbd_migration/test/fix_aggregator_test.dart
+++ b/pkg/nnbd_migration/test/fix_aggregator_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// ignore: deprecated_member_use
 import 'package:analyzer/analyzer.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/nullability_suffix.dart';
@@ -672,6 +673,17 @@
 ''');
   }
 
+  Future<void> test_introduceAs_withNullCheck() async {
+    await analyze('f(x) => x;');
+    var expr = findNode.simple('x;');
+    var previewInfo = run({
+      expr: NodeChangeForExpression()
+        ..introduceAs(nnbdTypeProvider.intType, _MockInfo())
+        ..addNullCheck(_MockInfo())
+    });
+    expect(previewInfo.applyTo(code), 'f(x) => x! as int;');
+  }
+
   Future<void> test_keep_redundant_parens() async {
     await analyze('f(a, b, c) => a + (b * c);');
     var previewInfo = run({});
@@ -865,6 +877,71 @@
     expect(previewInfo.applyTo(code), 'f(a, b, c) => a < b | c;');
   }
 
+  Future<void> test_removeLanguageVersion() async {
+    await analyze('''
+//@dart=2.6
+void main() {}
+''');
+    var previewInfo = run({
+      findNode.unit: NodeChangeForCompilationUnit()
+        ..removeLanguageVersionComment = true
+    });
+    // TODO(mfairhurst): Remove beginning \n once it renders properly in preview
+    expect(previewInfo.applyTo(code), '\nvoid main() {}\n');
+  }
+
+  Future<void> test_removeLanguageVersion_after_license() async {
+    await analyze('''
+// Some licensing stuff here...
+// Some copyrighting stuff too...
+// etc...
+// @dart = 2.6
+void main() {}
+''');
+    var previewInfo = run({
+      findNode.unit: NodeChangeForCompilationUnit()
+        ..removeLanguageVersionComment = true
+    });
+    // TODO(mfairhurst): Remove beginning \n once it renders properly in preview
+    expect(previewInfo.applyTo(code), '''
+// Some licensing stuff here...
+// Some copyrighting stuff too...
+// etc...
+
+void main() {}
+''');
+  }
+
+  Future<void> test_removeLanguageVersion_spaces() async {
+    await analyze('''
+// @dart = 2.6
+void main() {}
+''');
+    var previewInfo = run({
+      findNode.unit: NodeChangeForCompilationUnit()
+        ..removeLanguageVersionComment = true
+    });
+    // TODO(mfairhurst): Remove beginning \n once it renders properly in preview
+    expect(previewInfo.applyTo(code), '\nvoid main() {}\n');
+  }
+
+  Future<void> test_removeLanguageVersion_withOtherChanges() async {
+    await analyze('''
+//@dart=2.6
+int f() => null;
+''');
+    var previewInfo = run({
+      findNode.unit: NodeChangeForCompilationUnit()
+        ..removeLanguageVersionComment = true,
+      findNode.typeAnnotation('int'): NodeChangeForTypeAnnotation()
+        ..makeNullable = true
+        ..decoratedType = MockDecoratedType(
+            MockDartType(toStringValueWithoutNullability: 'int'))
+    });
+    // TODO(mfairhurst): Remove beginning \n once it renders properly in preview
+    expect(previewInfo.applyTo(code), '\nint? f() => null;\n');
+  }
+
   Future<void> test_removeNullAwarenessFromMethodInvocation() async {
     await analyze('f(x) => x?.m();');
     var methodInvocation = findNode.methodInvocation('?.');
diff --git a/pkg/nnbd_migration/test/fix_builder_test.dart b/pkg/nnbd_migration/test/fix_builder_test.dart
index 228047a..f9d4f9a 100644
--- a/pkg/nnbd_migration/test/fix_builder_test.dart
+++ b/pkg/nnbd_migration/test/fix_builder_test.dart
@@ -52,6 +52,12 @@
   static final isNullCheck = TypeMatcher<NodeChangeForExpression>()
       .having((c) => c.addsNullCheck, 'addsNullCheck', true);
 
+  static final isRemoveLanguageVersion =
+      TypeMatcher<NodeChangeForCompilationUnit>().having(
+          (c) => c.removeLanguageVersionComment,
+          'removeLanguageVersionComment',
+          true);
+
   static final isRemoveNullAwareness =
       TypeMatcher<NodeChangeForPropertyAccess>()
           .having((c) => c.removeNullAwareness, 'removeNullAwareness', true);
@@ -1113,6 +1119,21 @@
     });
   }
 
+  Future<void>
+      test_defaultFormalParameter_add_required_replace_annotation_nullable() async {
+    // TODO(paulberry): it would be nice to remove the import of `meta` if it's
+    // no longer needed after the change.
+    addMetaPackage();
+    await analyze('''
+import 'package:meta/meta.dart';
+void _f({@required int/*?*/ x}) {}
+''');
+    visitAll(changes: {
+      findNode.annotation('required'): isRequiredAnnotationToRequiredKeyword,
+      findNode.typeName('int'): isMakeNullable,
+    });
+  }
+
   Future<void> test_defaultFormalParameter_add_required_yes() async {
     await analyze('''
 int _f({int x}) => x + 1;
@@ -2359,6 +2380,23 @@
     visitSubexpression(findNode.propertyAccess('(c).x'), 'List<int>');
   }
 
+  Future<void> test_removeLanguageVersionComment() async {
+    await analyze('''
+// @dart = 2.6
+void main() {}
+''');
+    visitAll(changes: {findNode.unit: isRemoveLanguageVersion});
+  }
+
+  Future<void> test_removeLanguageVersionComment_withCopyright() async {
+    await analyze('''
+// Some copyright notice here...
+// @dart = 2.6
+void main() {}
+''');
+    visitAll(changes: {findNode.unit: isRemoveLanguageVersion});
+  }
+
   Future<void> test_set_ifElement_alive() async {
     await analyze('''
 _f(int x, bool b, int/*?*/ y) => {if (b) h(y) else g(y)};
@@ -2513,6 +2551,12 @@
     visitSubexpression(findNode.simple('x;'), 'int?');
   }
 
+  Future<void> test_simpleIdentifier_null_check_hint() async {
+    await analyze('int/*?*/ _f(int/*?*/ x) => x/*!*/;');
+    var xRef = findNode.simple('x/*!*/');
+    visitSubexpression(xRef, 'int', changes: {xRef: isNullCheck});
+  }
+
   Future<void> test_stringLiteral() async {
     await analyze('''
 f() => 'foo';
diff --git a/pkg/nnbd_migration/test/nullability_node_test.dart b/pkg/nnbd_migration/test/nullability_node_test.dart
index 9a5444f..c85fa11 100644
--- a/pkg/nnbd_migration/test/nullability_node_test.dart
+++ b/pkg/nnbd_migration/test/nullability_node_test.dart
@@ -735,5 +735,11 @@
   @override
   CodeReference get codeReference => null;
 
+  @override
+  String get description => 'Test edge';
+
+  @override
+  EdgeOriginKind get kind => null;
+
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
diff --git a/pkg/telemetry/lib/telemetry.dart b/pkg/telemetry/lib/telemetry.dart
index ef3491f..6df3990 100644
--- a/pkg/telemetry/lib/telemetry.dart
+++ b/pkg/telemetry/lib/telemetry.dart
@@ -56,7 +56,8 @@
 Analytics createAnalyticsInstance(
   String trackingId,
   String applicationName, {
-  bool disableForSession: false,
+  bool disableForSession = false,
+  bool forceEnabled = false,
 }) {
   Directory dir = getDartStorageDirectory();
   if (dir == null) {
@@ -75,9 +76,15 @@
     }
   }
 
-  File file = new File(path.join(dir.path, _settingsFileName));
+  File settingsFile = new File(path.join(dir.path, _settingsFileName));
   return new _TelemetryAnalytics(
-      trackingId, applicationName, getDartVersion(), file, disableForSession);
+    trackingId,
+    applicationName,
+    getDartVersion(),
+    settingsFile,
+    disableForSession: disableForSession,
+    forceEnabled: forceEnabled,
+  );
 }
 
 /// The directory used to store the analytics settings file.
@@ -100,16 +107,18 @@
 
 class _TelemetryAnalytics extends AnalyticsImpl {
   final bool disableForSession;
+  final bool forceEnabled;
 
   _TelemetryAnalytics(
     String trackingId,
     String applicationName,
     String applicationVersion,
-    File file,
-    this.disableForSession,
-  ) : super(
+    File settingsFile, {
+    @required this.disableForSession,
+    @required this.forceEnabled,
+  }) : super(
           trackingId,
-          new IOPersistentProperties.fromFile(file),
+          new IOPersistentProperties.fromFile(settingsFile),
           new IOPostHandler(),
           applicationName: applicationName,
           applicationVersion: applicationVersion,
@@ -126,6 +135,11 @@
       return false;
     }
 
+    // This is only used in special cases.
+    if (forceEnabled) {
+      return true;
+    }
+
     // If there's no explicit setting (enabled or disabled) then we don't send.
     return (properties['enabled'] as bool) ?? false;
   }
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 7109a15..6e9b063 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -632,7 +632,10 @@
     if (field.isExtensionMember) {
       flags |= FieldDeclaration.isExtensionMemberFlag;
     }
-    if (field.isLate) {
+    // In NNBD libraries, static fields act like late fields
+    // regardless of whether they're marked late.
+    if (field.isLate ||
+        (field.isStatic && field.enclosingLibrary.isNonNullableByDefault)) {
       flags |= FieldDeclaration.isLateFlag;
     }
     int position = TreeNode.noOffset;
diff --git a/pkg/vm/lib/bytecode/generics.dart b/pkg/vm/lib/bytecode/generics.dart
index 64c1140..f29fcce 100644
--- a/pkg/vm/lib/bytecode/generics.dart
+++ b/pkg/vm/lib/bytecode/generics.dart
@@ -28,7 +28,9 @@
   }
   final types = new List<DartType>(typeParameters.length);
   for (int i = 0; i < typeParameters.length; ++i) {
-    types[i] = new TypeParameterType(typeParameters[i], Nullability.legacy);
+    final tp = typeParameters[i];
+    types[i] = new TypeParameterType(
+        tp, TypeParameterType.computeNullabilityFromBound(tp));
   }
   return types;
 }
@@ -37,8 +39,11 @@
     List<TypeParameter> typeParameters, int overlap) {
   for (int i = 0; i < overlap; ++i) {
     final superTypeArg = superTypeArgs[superTypeArgs.length - overlap + i];
+    final typeParam = typeParameters[i];
     if (!(superTypeArg is TypeParameterType &&
-        superTypeArg.parameter == typeParameters[i])) {
+        superTypeArg.parameter == typeParameters[i] &&
+        superTypeArg.nullability ==
+            TypeParameterType.computeNullabilityFromBound(typeParam))) {
       return false;
     }
   }
diff --git a/pkg/vm/lib/transformations/type_flow/unboxing_info.dart b/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
index 67be799..caefba4 100644
--- a/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
+++ b/pkg/vm/lib/transformations/type_flow/unboxing_info.dart
@@ -8,6 +8,7 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/external_name.dart' show getExternalName;
 import 'package:vm/transformations/type_flow/analysis.dart';
+import 'package:vm/transformations/type_flow/native_code.dart';
 import 'package:vm/transformations/type_flow/types.dart';
 
 import '../../metadata/unboxing_info.dart';
@@ -22,11 +23,13 @@
 
   final TypeHierarchy _typeHierarchy;
   final CoreTypes _coreTypes;
+  final NativeCodeOracle _nativeCodeOracle;
   bool _finishedGraph;
 
   UnboxingInfoManager(TypeFlowAnalysis typeFlowAnalysis)
       : _typeHierarchy = typeFlowAnalysis.hierarchyCache,
         _coreTypes = typeFlowAnalysis.environment.coreTypes,
+        _nativeCodeOracle = typeFlowAnalysis.nativeCodeOracle,
         _finishedGraph = false;
 
   void registerMember(Member member) {
@@ -195,8 +198,10 @@
     // Methods that do not need dynamic invocation forwarders can not have
     // unboxed parameters and return because dynamic calls always use boxed
     // values.
-
+    // Similarly C->Dart calls (entrypoints) and Dart->C calls (natives) need to
+    // have boxed parameters and return values.
     return (_isNative(member) ||
+        _nativeCodeOracle.isMemberReferencedFromNativeCode(member) ||
         _isEnclosingClassSubtypeOfNum(member) ||
         (!_isConstructorOrStatic(member) &&
             !_needsDynamicInvocationForwarder(member)));
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart
index 58424bd..49c6b9f 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart
@@ -53,6 +53,12 @@
 dynamic returnBoxedNullableX() => kTrue ? X() : null;
 dynamic returnBoxedX() => X();
 
+@pragma('vm:entry-point')
+int returnBoxedSmiFromEntryPoint() => kTrue ? 1 : 2;
+
+@pragma('vm:entry-point')
+void takeBoxedSmiFromEntryPoint(int value) {}
+
 main() {
   takePositional(
       kTrue ? 1 : 2,
@@ -87,6 +93,8 @@
       boxedNullableX: kTrue ? X() : null,
       boxedX: X());
 
+  takeBoxedSmiFromEntryPoint(kTrue ? 1 : 2);
+
   use(returnUnboxedSmi());
   use(returnUnboxedInt());
   use(returnUnboxedDouble());
@@ -96,6 +104,7 @@
   use(returnBoxedNullableIntOrDouble());
   use(returnBoxedNullableX());
   use(returnBoxedX());
+  use(returnBoxedSmiFromEntryPoint());
 }
 
 void use(dynamic value) {}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect
index 25761a4..3b27f22 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unboxed_static_method.dart.expect
@@ -34,10 +34,16 @@
   return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null;
 static method returnBoxedX() → dynamic
   return new self::X::•();
+@#C3
+static method returnBoxedSmiFromEntryPoint() → core::int*
+  return [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2;
+@#C3
+static method takeBoxedSmiFromEntryPoint(core::int* value) → void {}
 static method main() → dynamic {
   self::takePositional([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null, new self::X::•());
   self::takeOptional([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null, [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null, new self::X::•());
   let core::int* #arg1 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2 in let core::int* #arg2 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : 2 in let core::double* #arg3 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : 2.2 in let core::int* #arg4 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} [@vm.inferred-type.metadata=int] self::smiOrMint : null in let core::double* #arg5 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::double*} 1.1 : null in let core::num* #arg6 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 in let core::num* #arg7 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::num*} [@vm.inferred-type.metadata=dart.core::bool?] self::kFalse ?{core::num*} [@vm.inferred-type.metadata=int] self::smiOrMint : 1.1 : null in let self::X* #arg8 = [@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{self::X*} new self::X::•() : null in let self::X* #arg9 = new self::X::•() in self::takeNamed(#arg6, #arg5, #arg4, #arg7, #arg8, #arg9, #arg3, #arg2, #arg1);
+  self::takeBoxedSmiFromEntryPoint([@vm.inferred-type.metadata=dart.core::bool?] self::kTrue ?{core::int*} 1 : 2);
   self::use([@vm.inferred-type.metadata=dart.core::_Smi] self::returnUnboxedSmi());
   self::use([@vm.inferred-type.metadata=int] self::returnUnboxedInt());
   self::use([@vm.inferred-type.metadata=dart.core::_Double] self::returnUnboxedDouble());
@@ -47,5 +53,6 @@
   self::use(self::returnBoxedNullableIntOrDouble());
   self::use([@vm.inferred-type.metadata=#lib::X?] self::returnBoxedNullableX());
   self::use([@vm.inferred-type.metadata=#lib::X] self::returnBoxedX());
+  self::use([@vm.inferred-type.metadata=dart.core::_Smi] self::returnBoxedSmiFromEntryPoint());
 }
 static method use(dynamic value) → void {}
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index 1b79c66..036d9f3 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -381,7 +381,10 @@
 #else
   RawAddr addr;
   Dart_Handle address = Dart_GetNativeArgument(args, 1);
-  ASSERT(Dart_IsString(address));
+  if (Dart_IsNull(address)) {
+    Dart_SetReturnValue(args,
+        DartUtils::NewDartArgumentError("expect address to be of type String"));
+  }
   Dart_Handle result = SocketAddress::GetUnixDomainSockAddr(
       DartUtils::GetStringValue(address), Namespace::GetNamespace(args, 3),
       &addr);
@@ -391,7 +394,10 @@
 
   RawAddr sourceAddr;
   address = Dart_GetNativeArgument(args, 2);
-  ASSERT(Dart_IsString(address));
+  if (Dart_IsNull(address)) {
+    Dart_SetReturnValue(args,
+        DartUtils::NewDartArgumentError("expect address to be of type String"));
+  }
   result = SocketAddress::GetUnixDomainSockAddr(
       DartUtils::GetStringValue(address), Namespace::GetNamespace(args, 3),
       &sourceAddr);
@@ -419,7 +425,10 @@
 #else
   RawAddr addr;
   Dart_Handle address = Dart_GetNativeArgument(args, 1);
-  ASSERT(Dart_IsString(address));
+  if (Dart_IsNull(address)) {
+    Dart_SetReturnValue(args,
+        DartUtils::NewDartArgumentError("expect address to be of type String"));
+  }
   Dart_Handle result = SocketAddress::GetUnixDomainSockAddr(
       DartUtils::GetStringValue(address), Namespace::GetNamespace(args, 2),
       &addr);
@@ -810,7 +819,10 @@
   Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
 #else
   Dart_Handle address = Dart_GetNativeArgument(args, 1);
-  ASSERT(Dart_IsString(address));
+  if (Dart_IsNull(address)) {
+    Dart_SetReturnValue(args,
+        DartUtils::NewDartArgumentError("expect address to be of type String"));
+  }
   const char* path = DartUtils::GetStringValue(address);
   int64_t backlog = DartUtils::GetInt64ValueCheckRange(
       Dart_GetNativeArgument(args, 2), 0, 65535);
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index caed3bb..d2c36b1 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -167,6 +167,7 @@
   ListeningSocketRegistry()
       : sockets_by_port_(SameIntptrValue, kInitialSocketsCount),
         sockets_by_fd_(SameIntptrValue, kInitialSocketsCount),
+        unix_domain_sockets_(nullptr),
         mutex_() {}
 
   ~ListeningSocketRegistry() {
diff --git a/runtime/tests/vm/dart/causal_stacks/utils.dart b/runtime/tests/vm/dart/causal_stacks/utils.dart
index 50d9527..118ce14 100644
--- a/runtime/tests/vm/dart/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart/causal_stacks/utils.dart
@@ -140,10 +140,10 @@
 
 Future<void> customErrorZone() async {
   final completer = Completer<void>();
-  runZoned(() async {
+  runZonedGuarded(() async {
     await allYield();
     completer.complete(null);
-  }, onError: (e, s) {
+  }, (e, s) {
     completer.completeError(e, s);
   });
   return completer.future;
@@ -550,7 +550,7 @@
     r'#5      _rootRun ',
     r'#6      _CustomZone.run ',
     r'#7      _runZoned ',
-    r'#8      runZoned ',
+    r'#8      runZonedGuarded ',
     r'#9      customErrorZone \(.*/utils.dart:143(:3)?\)$',
   ];
   await doTestAwait(
diff --git a/runtime/tests/vm/dart/isolate_send_function_types_test.dart b/runtime/tests/vm/dart/isolate_send_function_types_test.dart
index e8fb8ff..e45e045 100644
--- a/runtime/tests/vm/dart/isolate_send_function_types_test.dart
+++ b/runtime/tests/vm/dart/isolate_send_function_types_test.dart
@@ -14,9 +14,9 @@
 
   {
     final caughtErrorCompleter = Completer<String>();
-    await runZoned(() {
+    await runZonedGuarded(() {
       Isolate.spawn(isolate, x);
-    }, onError: (e) {
+    }, (e, s) {
       caughtErrorCompleter.complete(e.toString());
     });
     Expect.equals(
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index a464e6b..c22bccd 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -54,7 +54,6 @@
 
 [ $mode == debug ]
 cc/CorelibIsolateStartup: SkipByDesign # This is a benchmark that is not informative in debug mode.
-cc/IRTest_TypedDataAOT_FunctionalGetSet: Skip # run_vm_tests contains JIT/AOT but FLAG_precompiled_mode is not always correct. This causes this test to fail in debug mode, hitting an assertion. See http://dartbug.com/36521
 cc/VerifyExplicit_Crash: Crash # Negative tests of VerifiedMemory should crash iff in DEBUG mode. TODO(koda): Improve support for negative tests.
 cc/VerifyImplicit_Crash: Crash # Negative tests of VerifiedMemory should crash iff in DEBUG mode. TODO(koda): Improve support for negative tests.
 dart/appjit_cha_deopt_test: Pass, Slow # Quite slow in debug mode, uses --optimization-counter-threshold=100
diff --git a/runtime/vm/bss_relocs.cc b/runtime/vm/bss_relocs.cc
index 7e01696..12809a7 100644
--- a/runtime/vm/bss_relocs.cc
+++ b/runtime/vm/bss_relocs.cc
@@ -2,16 +2,22 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include <vm/bss_relocs.h>
-#include <vm/runtime_entry.h>
-#include <vm/thread.h>
+#include "vm/bss_relocs.h"
+#include "vm/runtime_entry.h"
+#include "vm/thread.h"
 
 namespace dart {
 
 void BSS::Initialize(Thread* current, uword* bss_start) {
-  bss_start[BSS::RelocationIndex(
-      BSS::Relocation::DRT_GetThreadForNativeCallback)] =
-      reinterpret_cast<uword>(DLRT_GetThreadForNativeCallback);
+  std::atomic<uword>* slot =
+      reinterpret_cast<std::atomic<uword>*>(&bss_start[BSS::RelocationIndex(
+          BSS::Relocation::DRT_GetThreadForNativeCallback)]);
+  uword old_value = slot->load(std::memory_order_relaxed);
+  uword new_value = reinterpret_cast<uword>(DLRT_GetThreadForNativeCallback);
+  if (!slot->compare_exchange_strong(old_value, new_value,
+                                     std::memory_order_relaxed)) {
+    RELEASE_ASSERT(old_value == new_value);
+  }
 }
 
 }  // namespace dart
diff --git a/runtime/vm/bss_relocs.h b/runtime/vm/bss_relocs.h
index aa3c1f7..c557b46 100644
--- a/runtime/vm/bss_relocs.h
+++ b/runtime/vm/bss_relocs.h
@@ -5,7 +5,7 @@
 #ifndef RUNTIME_VM_BSS_RELOCS_H_
 #define RUNTIME_VM_BSS_RELOCS_H_
 
-#include <platform/allocation.h>
+#include "platform/allocation.h"
 
 namespace dart {
 class Thread;
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 5a6e7c1..cf1f9e4 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -6050,6 +6050,7 @@
   for (intptr_t i = 0; i < num_clusters_; i++) {
     clusters_[i]->PostLoad(refs, kind_, zone_);
   }
+  object_store->PostLoad();
 
   // Setup native resolver for bootstrap impl.
   Bootstrap::SetupNativeResolver();
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 82ed009..6b899bb 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -233,7 +233,11 @@
       // optimized instruction count (used in inlining heuristics).
       ClassFinalizer::ClearAllCode(
           /*including_nonchanging_cids=*/FLAG_use_bare_instructions);
-      PrecompileConstructors();
+
+      {
+        CompilerState state(thread_, /*is_aot=*/true);
+        PrecompileConstructors();
+      }
 
       ClassFinalizer::ClearAllCode(
           /*including_nonchanging_cids=*/FLAG_use_bare_instructions);
@@ -2394,7 +2398,7 @@
 // If optimized_result_code is not NULL then it is caller's responsibility
 // to install code.
 bool PrecompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
-  ASSERT(FLAG_precompiled_mode);
+  ASSERT(CompilerState::Current().is_aot());
   if (optimized() && !parsed_function()->function().IsOptimizable()) {
     // All functions compiled by precompiler must be optimizable.
     UNREACHABLE();
@@ -2423,7 +2427,7 @@
       ZoneGrowableArray<const ICData*>* ic_data_array = nullptr;
       const Function& function = parsed_function()->function();
 
-      CompilerState compiler_state(thread());
+      CompilerState compiler_state(thread(), /*is_aot=*/true);
 
       {
         ic_data_array = new (zone) ZoneGrowableArray<const ICData*>();
@@ -2624,7 +2628,7 @@
                                           const Function& function,
                                           bool optimized) {
   // Check that we optimize, except if the function is not optimizable.
-  ASSERT(FLAG_precompiled_mode);
+  ASSERT(CompilerState::Current().is_aot());
   ASSERT(!function.IsOptimizable() || optimized);
   ASSERT(!function.HasCode());
   LongJumpScope jump;
@@ -2701,7 +2705,7 @@
   VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
   TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "CompileFunction", function);
 
-  ASSERT(FLAG_precompiled_mode);
+  ASSERT(CompilerState::Current().is_aot());
   const bool optimized = function.IsOptimizable();  // False for natives.
   DartCompilationPipeline pipeline;
   return PrecompileFunctionHelper(precompiler, &pipeline, function, optimized);
diff --git a/runtime/vm/compiler/backend/block_scheduler.cc b/runtime/vm/compiler/backend/block_scheduler.cc
index d5a2f01..0d84725 100644
--- a/runtime/vm/compiler/backend/block_scheduler.cc
+++ b/runtime/vm/compiler/backend/block_scheduler.cc
@@ -55,7 +55,7 @@
   if (!FLAG_reorder_basic_blocks) {
     return;
   }
-  if (FLAG_precompiled_mode) {
+  if (CompilerState::Current().is_aot()) {
     return;
   }
 
@@ -159,7 +159,7 @@
 }
 
 void BlockScheduler::ReorderBlocks(FlowGraph* flow_graph) {
-  if (FLAG_precompiled_mode) {
+  if (CompilerState::Current().is_aot()) {
     ReorderBlocksAOT(flow_graph);
   } else {
     ReorderBlocksJIT(flow_graph);
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index 084a67d..266cb14 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -529,7 +529,7 @@
                                         intptr_t deopt_id) {
   Value* val1 = new (zone()) Value(length);
   Value* val2 = new (zone()) Value(index);
-  if (FLAG_precompiled_mode) {
+  if (CompilerState::Current().is_aot()) {
     return new (zone()) GenericCheckBoundInstr(val1, val2, deopt_id);
   }
   return new (zone()) CheckArrayBoundInstr(val1, val2, deopt_id);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 95841cb..ef80744 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -173,19 +173,14 @@
 }
 
 bool FlowGraphCompiler::IsUnboxedField(const Field& field) {
-  bool valid_class;
-  if (FLAG_precompiled_mode) {
-    valid_class =
-        (SupportsUnboxedDoubles() && (field.guarded_cid() == kDoubleCid)) ||
-        (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat32x4Cid)) ||
-        (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat64x2Cid)) ||
-        field.is_non_nullable_integer();
-  } else {
-    valid_class =
-        (SupportsUnboxedDoubles() && (field.guarded_cid() == kDoubleCid)) ||
-        (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat32x4Cid)) ||
-        (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat64x2Cid));
-  }
+  // The `field.is_non_nullable_integer()` is set in the kernel loader and can
+  // only be set if we consume a AOT kernel (annotated with inferred types).
+  ASSERT(!field.is_non_nullable_integer() || FLAG_precompiled_mode);
+  const bool valid_class =
+      (SupportsUnboxedDoubles() && (field.guarded_cid() == kDoubleCid)) ||
+      (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat32x4Cid)) ||
+      (SupportsUnboxedSimd128() && (field.guarded_cid() == kFloat64x2Cid)) ||
+      field.is_non_nullable_integer();
   return field.is_unboxing_candidate() && !field.is_nullable() && valid_class;
 }
 
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index deec0f6..c32f5d1 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -359,19 +359,18 @@
   const Class& type_class = Class::Handle(zone(), type.type_class());
   ASSERT(type_class.NumTypeArguments() == 0);
 
-  const Register kInstanceReg = R0;
-  __ tst(kInstanceReg, compiler::Operand(kSmiTagMask));
+  __ tst(TypeTestABI::kInstanceReg, compiler::Operand(kSmiTagMask));
   // If instance is Smi, check directly.
   const Class& smi_class = Class::Handle(zone(), Smi::Class());
-  if (Class::IsSubtypeOf(smi_class, Object::null_type_arguments(), type,
-                         Heap::kOld)) {
+  if (Class::IsSubtypeOf(smi_class, Object::null_type_arguments(),
+                         Nullability::kNonNullable, type, Heap::kOld)) {
     // Fast case for type = int/num/top-type.
     __ b(is_instance_lbl, EQ);
   } else {
     __ b(is_not_instance_lbl, EQ);
   }
   const Register kClassIdReg = R2;
-  __ LoadClassId(kClassIdReg, kInstanceReg);
+  __ LoadClassId(kClassIdReg, TypeTestABI::kInstanceReg);
   // Bool interface can be implemented only by core class Bool.
   if (type.IsBoolType()) {
     __ CompareImmediate(kClassIdReg, kBoolCid);
@@ -460,7 +459,8 @@
   // Skip check if destination is a dynamic type.
   if (type.IsTypeParameter()) {
     const TypeParameter& type_param = TypeParameter::Cast(type);
-    static_assert(kFunctionTypeArgumentsReg < kInstantiatorTypeArgumentsReg,
+    static_assert(TypeTestABI::kFunctionTypeArgumentsReg <
+                      TypeTestABI::kInstantiatorTypeArgumentsReg,
                   "Should be ordered to load arguments with one instruction");
     __ ldm(IA, SP,
            (1 << TypeTestABI::kFunctionTypeArgumentsReg) |
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index 59c4bb7..20cc37d 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -346,18 +346,17 @@
   const Class& type_class = Class::Handle(zone(), type.type_class());
   ASSERT(type_class.NumTypeArguments() == 0);
 
-  const Register kInstanceReg = R0;
   // If instance is Smi, check directly.
   const Class& smi_class = Class::Handle(zone(), Smi::Class());
-  if (Class::IsSubtypeOf(smi_class, Object::null_type_arguments(), type,
-                         Heap::kOld)) {
+  if (Class::IsSubtypeOf(smi_class, Object::null_type_arguments(),
+                         Nullability::kNonNullable, type, Heap::kOld)) {
     // Fast case for type = int/num/top-type.
-    __ BranchIfSmi(kInstanceReg, is_instance_lbl);
+    __ BranchIfSmi(TypeTestABI::kInstanceReg, is_instance_lbl);
   } else {
-    __ BranchIfSmi(kInstanceReg, is_not_instance_lbl);
+    __ BranchIfSmi(TypeTestABI::kInstanceReg, is_not_instance_lbl);
   }
   const Register kClassIdReg = R2;
-  __ LoadClassId(kClassIdReg, kInstanceReg);
+  __ LoadClassId(kClassIdReg, TypeTestABI::kInstanceReg);
   // Bool interface can be implemented only by core class Bool.
   if (type.IsBoolType()) {
     __ CompareImmediate(kClassIdReg, kBoolCid);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index e5e0a06..d362feb 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -256,10 +256,9 @@
   ASSERT(!type.IsFunctionType());
   const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
   ASSERT(type_class.NumTypeArguments() > 0);
-  const Register kInstanceReg = EAX;
   const Type& smi_type = Type::Handle(zone(), Type::SmiType());
   const bool smi_is_ok = smi_type.IsSubtypeOf(type, Heap::kOld);
-  __ testl(kInstanceReg, compiler::Immediate(kSmiTagMask));
+  __ testl(TypeTestABI::kInstanceReg, compiler::Immediate(kSmiTagMask));
   if (smi_is_ok) {
     // Fast case for type = FutureOr<int/num/top-type>.
     __ j(ZERO, is_instance_lbl);
@@ -276,7 +275,7 @@
   if (is_raw_type) {
     const Register kClassIdReg = ECX;
     // dynamic type argument, check only classes.
-    __ LoadClassId(kClassIdReg, kInstanceReg);
+    __ LoadClassId(kClassIdReg, TypeTestABI::kInstanceReg);
     __ cmpl(kClassIdReg, compiler::Immediate(type_class.id()));
     __ j(EQUAL, is_instance_lbl);
     // List is a very common case.
@@ -300,10 +299,10 @@
   const Register kInstantiatorTypeArgumentsReg = kNoRegister;
   const Register kFunctionTypeArgumentsReg = kNoRegister;
   const Register kTempReg = EDI;
-  return GenerateCallSubtypeTestStub(kTestTypeTwoArgs, kInstanceReg,
-                                     kInstantiatorTypeArgumentsReg,
-                                     kFunctionTypeArgumentsReg, kTempReg,
-                                     is_instance_lbl, is_not_instance_lbl);
+  return GenerateCallSubtypeTestStub(
+      kTestTypeTwoArgs, TypeTestABI::kInstanceReg,
+      kInstantiatorTypeArgumentsReg, kFunctionTypeArgumentsReg, kTempReg,
+      is_instance_lbl, is_not_instance_lbl);
 }
 
 void FlowGraphCompiler::CheckClassIds(Register class_id_reg,
@@ -333,19 +332,18 @@
   const Class& type_class = Class::Handle(zone(), type.type_class());
   ASSERT(type_class.NumTypeArguments() == 0);
 
-  const Register kInstanceReg = EAX;
-  __ testl(kInstanceReg, compiler::Immediate(kSmiTagMask));
+  __ testl(TypeTestABI::kInstanceReg, compiler::Immediate(kSmiTagMask));
   // If instance is Smi, check directly.
   const Class& smi_class = Class::Handle(zone(), Smi::Class());
-  if (Class::IsSubtypeOf(smi_class, Object::null_type_arguments(), type,
-                         Heap::kOld)) {
+  if (Class::IsSubtypeOf(smi_class, Object::null_type_arguments(),
+                         Nullability::kNonNullable, type, Heap::kOld)) {
     // Fast case for type = int/num/top-type.
     __ j(ZERO, is_instance_lbl);
   } else {
     __ j(ZERO, is_not_instance_lbl);
   }
   const Register kClassIdReg = ECX;
-  __ LoadClassId(kClassIdReg, kInstanceReg);
+  __ LoadClassId(kClassIdReg, TypeTestABI::kInstanceReg);
   // Bool interface can be implemented only by core class Bool.
   if (type.IsBoolType()) {
     __ cmpl(kClassIdReg, compiler::Immediate(kBoolCid));
@@ -394,14 +392,13 @@
     compiler::Label* is_instance_lbl,
     compiler::Label* is_not_instance_lbl) {
   __ Comment("Subtype1TestCacheLookup");
-  const Register kInstanceReg = EAX;
 #if defined(DEBUG)
   compiler::Label ok;
-  __ BranchIfNotSmi(kInstanceReg, &ok);
+  __ BranchIfNotSmi(TypeTestABI::kInstanceReg, &ok);
   __ Breakpoint();
   __ Bind(&ok);
 #endif
-  __ LoadClassId(EDI, kInstanceReg);
+  __ LoadClassId(EDI, TypeTestABI::kInstanceReg);
   __ LoadClassById(ECX, EDI);
   // ECX: instance class.
   // Check immediate superclass equality.
@@ -413,7 +410,7 @@
   const Register kInstantiatorTypeArgumentsReg = kNoRegister;
   const Register kFunctionTypeArgumentsReg = kNoRegister;
   const Register kTempReg = EDI;
-  return GenerateCallSubtypeTestStub(kTestTypeOneArg, kInstanceReg,
+  return GenerateCallSubtypeTestStub(kTestTypeOneArg, TypeTestABI::kInstanceReg,
                                      kInstantiatorTypeArgumentsReg,
                                      kFunctionTypeArgumentsReg, kTempReg,
                                      is_instance_lbl, is_not_instance_lbl);
@@ -428,7 +425,6 @@
     compiler::Label* is_instance_lbl,
     compiler::Label* is_not_instance_lbl) {
   __ Comment("UninstantiatedTypeTest");
-  const Register kInstanceReg = EAX;
   const Register kTempReg = EDI;
   ASSERT(!type.IsInstantiated());
   ASSERT(!type.IsFunctionType());
@@ -444,9 +440,10 @@
             compiler::Address(ESP, 0 * kWordSize));  // Get function type args.
     // EDX: instantiator type arguments.
     // ECX: function type arguments.
-    const Register kTypeArgumentsReg = type_param.IsClassTypeParameter()
-                                           ? kInstantiatorTypeArgumentsReg
-                                           : kFunctionTypeArgumentsReg;
+    const Register kTypeArgumentsReg =
+        type_param.IsClassTypeParameter()
+            ? TypeTestABI::kInstantiatorTypeArgumentsReg
+            : TypeTestABI::kFunctionTypeArgumentsReg;
     // Check if type arguments are null, i.e. equivalent to vector of dynamic.
     __ cmpl(kTypeArgumentsReg, raw_null);
     __ j(EQUAL, is_instance_lbl);
@@ -478,27 +475,30 @@
     const auto test_kind = GetTypeTestStubKindForTypeParameter(type_param);
     const SubtypeTestCache& type_test_cache = SubtypeTestCache::ZoneHandle(
         zone(), GenerateCallSubtypeTestStub(
-                    test_kind, kInstanceReg, kInstantiatorTypeArgumentsReg,
-                    kFunctionTypeArgumentsReg, kTempReg, is_instance_lbl,
-                    is_not_instance_lbl));
+                    test_kind, TypeTestABI::kInstanceReg,
+                    TypeTestABI::kInstantiatorTypeArgumentsReg,
+                    TypeTestABI::kFunctionTypeArgumentsReg, kTempReg,
+                    is_instance_lbl, is_not_instance_lbl));
     return type_test_cache.raw();
   }
   if (type.IsType()) {
     // Smi is FutureOr<T>, when T is a top type or int or num.
     if (!type.IsFutureOrType()) {
-      __ testl(kInstanceReg,
+      __ testl(TypeTestABI::kInstanceReg,
                compiler::Immediate(kSmiTagMask));  // Is instance Smi?
       __ j(ZERO, is_not_instance_lbl);
     }
-    __ movl(kInstantiatorTypeArgumentsReg,
+    __ movl(TypeTestABI::kInstantiatorTypeArgumentsReg,
             compiler::Address(ESP, 1 * kWordSize));
-    __ movl(kFunctionTypeArgumentsReg, compiler::Address(ESP, 0 * kWordSize));
+    __ movl(TypeTestABI::kFunctionTypeArgumentsReg,
+            compiler::Address(ESP, 0 * kWordSize));
     // Uninstantiated type class is known at compile time, but the type
     // arguments are determined at runtime by the instantiator(s).
-    return GenerateCallSubtypeTestStub(kTestTypeFourArgs, kInstanceReg,
-                                       kInstantiatorTypeArgumentsReg,
-                                       kFunctionTypeArgumentsReg, kTempReg,
-                                       is_instance_lbl, is_not_instance_lbl);
+    return GenerateCallSubtypeTestStub(
+        kTestTypeFourArgs, TypeTestABI::kInstanceReg,
+        TypeTestABI::kInstantiatorTypeArgumentsReg,
+        TypeTestABI::kFunctionTypeArgumentsReg, kTempReg, is_instance_lbl,
+        is_not_instance_lbl);
   }
   return SubtypeTestCache::null();
 }
@@ -511,18 +511,18 @@
     const AbstractType& type,
     compiler::Label* is_instance_lbl,
     compiler::Label* is_not_instance_lbl) {
-  const Register kInstanceReg = EAX;
   __ Comment("FunctionTypeTest");
 
-  __ testl(kInstanceReg, compiler::Immediate(kSmiTagMask));
+  __ testl(TypeTestABI::kInstanceReg, compiler::Immediate(kSmiTagMask));
   __ j(ZERO, is_not_instance_lbl);
   // Uninstantiated type class is known at compile time, but the type
   // arguments are determined at runtime by the instantiator(s).
   const Register kTempReg = EDI;
-  return GenerateCallSubtypeTestStub(kTestTypeSixArgs, kInstanceReg,
-                                     kInstantiatorTypeArgumentsReg,
-                                     kFunctionTypeArgumentsReg, kTempReg,
-                                     is_instance_lbl, is_not_instance_lbl);
+  return GenerateCallSubtypeTestStub(
+      kTestTypeSixArgs, TypeTestABI::kInstanceReg,
+      TypeTestABI::kInstantiatorTypeArgumentsReg,
+      TypeTestABI::kFunctionTypeArgumentsReg, kTempReg, is_instance_lbl,
+      is_not_instance_lbl);
 }
 
 // Inputs:
@@ -628,8 +628,8 @@
     __ PushObject(Object::null_object());  // Make room for the result.
     __ pushl(EAX);                         // Push the instance.
     __ PushObject(type);                   // Push the type.
-    __ pushl(kInstantiatorTypeArgumentsReg);
-    __ pushl(kFunctionTypeArgumentsReg);
+    __ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
+    __ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
     __ LoadObject(EAX, test_cache);
     __ pushl(EAX);
     GenerateRuntimeCall(token_pos, deopt_id, kInstanceofRuntimeEntry, 5, locs);
@@ -673,8 +673,8 @@
   // Assignable check is skipped in FlowGraphBuilder, not here.
   ASSERT(!dst_type.IsTopTypeForAssignability());
 
-  __ pushl(kInstantiatorTypeArgumentsReg);
-  __ pushl(kFunctionTypeArgumentsReg);
+  __ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
+  __ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
 
   compiler::Label is_assignable, runtime_call;
   if (Instance::NullIsAssignableTo(dst_type)) {
@@ -691,15 +691,15 @@
 
   __ Bind(&runtime_call);
   __ movl(
-      kInstantiatorTypeArgumentsReg,
+      TypeTestABI::kInstantiatorTypeArgumentsReg,
       compiler::Address(ESP, 1 * kWordSize));  // Get instantiator type args.
-  __ movl(kFunctionTypeArgumentsReg,
+  __ movl(TypeTestABI::kFunctionTypeArgumentsReg,
           compiler::Address(ESP, 0 * kWordSize));  // Get function type args.
   __ PushObject(Object::null_object());            // Make room for the result.
   __ pushl(EAX);                                   // Push the source object.
   __ PushObject(dst_type);  // Push the type of the destination.
-  __ pushl(kInstantiatorTypeArgumentsReg);
-  __ pushl(kFunctionTypeArgumentsReg);
+  __ pushl(TypeTestABI::kInstantiatorTypeArgumentsReg);
+  __ pushl(TypeTestABI::kFunctionTypeArgumentsReg);
   __ PushObject(dst_name);  // Push the name of the destination.
   __ LoadObject(EAX, test_cache);
   __ pushl(EAX);
@@ -711,8 +711,8 @@
   __ popl(EAX);
 
   __ Bind(&is_assignable);
-  __ popl(kFunctionTypeArgumentsReg);
-  __ popl(kInstantiatorTypeArgumentsReg);
+  __ popl(TypeTestABI::kFunctionTypeArgumentsReg);
+  __ popl(TypeTestABI::kInstantiatorTypeArgumentsReg);
 }
 
 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index 82fdc74..f1f0c6b 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -360,19 +360,18 @@
   const Class& type_class = Class::Handle(zone(), type.type_class());
   ASSERT(type_class.NumTypeArguments() == 0);
 
-  const Register kInstanceReg = RAX;
-  __ testq(kInstanceReg, compiler::Immediate(kSmiTagMask));
+  __ testq(TypeTestABI::kInstanceReg, compiler::Immediate(kSmiTagMask));
   // If instance is Smi, check directly.
   const Class& smi_class = Class::Handle(zone(), Smi::Class());
-  if (Class::IsSubtypeOf(smi_class, Object::null_type_arguments(), type,
-                         Heap::kOld)) {
+  if (Class::IsSubtypeOf(smi_class, Object::null_type_arguments(),
+                         Nullability::kNonNullable, type, Heap::kOld)) {
     // Fast case for type = int/num/top-type.
     __ j(ZERO, is_instance_lbl);
   } else {
     __ j(ZERO, is_not_instance_lbl);
   }
   const Register kClassIdReg = R10;
-  __ LoadClassId(kClassIdReg, kInstanceReg);
+  __ LoadClassId(kClassIdReg, TypeTestABI::kInstanceReg);
   // Bool interface can be implemented only by core class Bool.
   if (type.IsBoolType()) {
     __ cmpl(kClassIdReg, compiler::Immediate(kBoolCid));
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 16e9531..ff57ae3 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -454,7 +454,7 @@
 bool HierarchyInfo::InstanceOfHasClassRange(const AbstractType& type,
                                             intptr_t* lower_limit,
                                             intptr_t* upper_limit) {
-  ASSERT(FLAG_precompiled_mode);
+  ASSERT(CompilerState::Current().is_aot());
   if (CanUseSubtypeRangeCheckFor(type)) {
     const Class& type_class =
         Class::Handle(thread()->zone(), type.type_class());
@@ -908,7 +908,7 @@
       num_context_variables_(num_context_variables),
       identity_(AliasIdentity::Unknown()) {
   // This instruction is not used in AOT for code size reasons.
-  ASSERT(!FLAG_precompiled_mode);
+  ASSERT(!CompilerState::Current().is_aot());
 }
 
 bool StoreInstanceFieldInstr::IsUnboxedStore() const {
@@ -3995,7 +3995,7 @@
 }
 
 void OsrEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(!FLAG_precompiled_mode);
+  ASSERT(!CompilerState::Current().is_aot());
   ASSERT(compiler->is_optimizing());
   __ Bind(compiler->GetJumpLabel(this));
 
@@ -4327,7 +4327,7 @@
 }
 
 void InstanceCallBaseInstr::UpdateReceiverSminess(Zone* zone) {
-  if (FLAG_precompiled_mode && !receiver_is_not_smi()) {
+  if (CompilerState::Current().is_aot() && !receiver_is_not_smi()) {
     if (Receiver()->Type()->IsNotSmi()) {
       set_receiver_is_not_smi(true);
       return;
@@ -4720,7 +4720,7 @@
 }
 
 bool PolymorphicInstanceCallInstr::IsSureToCallSingleRecognizedTarget() const {
-  if (FLAG_precompiled_mode && !complete()) return false;
+  if (CompilerState::Current().is_aot() && !complete()) return false;
   return targets_.HasSingleRecognizedTarget();
 }
 
@@ -4743,7 +4743,7 @@
 }
 
 Definition* StaticCallInstr::Canonicalize(FlowGraph* flow_graph) {
-  if (!FLAG_precompiled_mode) {
+  if (!CompilerState::Current().is_aot()) {
     return this;
   }
 
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 9445c6a..66105c7 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -782,7 +782,7 @@
 
   intptr_t deopt_id() const {
     ASSERT(ComputeCanDeoptimize() || CanBecomeDeoptimizationTarget() ||
-           FLAG_precompiled_mode);
+           CompilerState::Current().is_aot());
     return GetDeoptId();
   }
 
@@ -2385,7 +2385,7 @@
 
   // In AOT mode Phi instructions do not check types of inputs when unboxing.
   virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
-    return FLAG_precompiled_mode ? kNotSpeculative : kGuardInputs;
+    return CompilerState::Current().is_aot() ? kNotSpeculative : kGuardInputs;
   }
 
   virtual intptr_t Hashcode() const {
@@ -2870,7 +2870,9 @@
   virtual TokenPosition token_pos() const { return token_pos_; }
   Value* exception() const { return inputs_[0]; }
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool HasUnknownSideEffects() const { return false; }
 
@@ -2903,7 +2905,9 @@
   Value* exception() const { return inputs_[0]; }
   Value* stacktrace() const { return inputs_[1]; }
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool HasUnknownSideEffects() const { return false; }
 
@@ -3437,7 +3441,9 @@
   const AbstractType& sub_type() const { return sub_type_; }
   const String& dst_name() const { return dst_name_; }
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool CanBecomeDeoptimizationTarget() const { return true; }
 
@@ -3511,7 +3517,9 @@
   }
   const String& dst_name() const { return dst_name_; }
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool CanBecomeDeoptimizationTarget() const {
     // AssertAssignable instructions that are specialized by the optimizer
@@ -3550,7 +3558,9 @@
   virtual TokenPosition token_pos() const { return token_pos_; }
   Value* value() const { return inputs_[0]; }
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
@@ -3765,7 +3775,9 @@
   // TODO(kmillikin): implement exact call counts for closure calls.
   virtual intptr_t CallCount() const { return 1; }
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool HasUnknownSideEffects() const { return true; }
 
@@ -3834,7 +3846,9 @@
 
   virtual CompileType ComputeType() const;
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool CanBecomeDeoptimizationTarget() const {
     // Instance calls that are specialized by the optimizer need a
@@ -4548,7 +4562,9 @@
     return ic_data() == NULL ? call_count_ : ic_data()->AggregateCount();
   }
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool CanBecomeDeoptimizationTarget() const {
     // Static calls that are specialized by the optimizer (e.g. sqrt) need a
@@ -4893,7 +4909,9 @@
   virtual bool MayThrow() const { return false; }
 
   // FfiCallInstr calls C code, which can call back into Dart.
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool HasUnknownSideEffects() const { return true; }
 
@@ -5018,8 +5036,9 @@
   virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const {
     // In AOT unbox is done based on TFA, therefore it was proven to be correct
     // and it can never deoptmize.
-    return (IsUnboxedStore() && FLAG_precompiled_mode) ? kNotSpeculative
-                                                       : kGuardInputs;
+    return (IsUnboxedStore() && CompilerState::Current().is_aot())
+               ? kNotSpeculative
+               : kGuardInputs;
   }
 
   DECLARE_INSTRUCTION(StoreInstanceField)
@@ -5461,7 +5480,9 @@
   // Issues a static call to Dart code which calls toString on objects.
   virtual bool HasUnknownSideEffects() const { return true; }
   virtual bool CanCallDart() const { return true; }
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   const Function& CallFunction() const;
 
@@ -5604,7 +5625,9 @@
   const AbstractType& type() const { return type_; }
   virtual TokenPosition token_pos() const { return token_pos_; }
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool HasUnknownSideEffects() const { return false; }
 
@@ -5895,7 +5918,9 @@
 
   // Throw needs environment, which is created only if instruction can
   // deoptimize.
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool HasUnknownSideEffects() const { return false; }
 
@@ -6132,7 +6157,9 @@
   const AbstractType& type() const { return type_; }
   virtual TokenPosition token_pos() const { return token_pos_; }
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool HasUnknownSideEffects() const { return false; }
 
@@ -6175,7 +6202,9 @@
   const Function& function() const { return function_; }
   virtual TokenPosition token_pos() const { return token_pos_; }
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool HasUnknownSideEffects() const { return false; }
 
@@ -6260,7 +6289,9 @@
 
   DECLARE_INSTRUCTION(InitInstanceField)
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
   virtual bool HasUnknownSideEffects() const { return true; }
   virtual Instruction* Canonicalize(FlowGraph* flow_graph);
 
@@ -6282,7 +6313,9 @@
 
   DECLARE_INSTRUCTION(InitStaticField)
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
   virtual bool HasUnknownSideEffects() const { return true; }
   virtual Instruction* Canonicalize(FlowGraph* flow_graph);
 
@@ -6316,7 +6349,9 @@
   DECLARE_INSTRUCTION(CloneContext)
   virtual CompileType ComputeType() const;
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool HasUnknownSideEffects() const { return false; }
 
@@ -7700,7 +7735,9 @@
 
   DECLARE_INSTRUCTION(CheckStackOverflow)
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual Instruction* Canonicalize(FlowGraph* flow_graph);
 
@@ -7829,7 +7866,9 @@
   DECLARE_INSTRUCTION(DoubleToInteger)
   virtual CompileType ComputeType() const;
 
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool HasUnknownSideEffects() const { return false; }
 
@@ -8265,7 +8304,9 @@
 
   // CheckNull can implicitly call Dart code (NoSuchMethodError constructor),
   // so it needs a deopt ID in optimized and unoptimized code.
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
   virtual bool CanBecomeDeoptimizationTarget() const { return true; }
 
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
@@ -8406,7 +8447,9 @@
 
   // GenericCheckBound can implicitly call Dart code (RangeError or
   // ArgumentError constructor), so it can lazily deopt.
-  virtual bool ComputeCanDeoptimize() const { return !FLAG_precompiled_mode; }
+  virtual bool ComputeCanDeoptimize() const {
+    return !CompilerState::Current().is_aot();
+  }
 
   virtual bool MayThrow() const { return true; }
 
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 22e2e75..4383bad 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -736,8 +736,8 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  summary->set_in(0, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  summary->set_in(1, Location::RegisterLocation(kFunctionTypeArgumentsReg));
+  summary->set_in(0, Location::RegisterLocation(R2));  // Instant. type args.
+  summary->set_in(1, Location::RegisterLocation(R1));  // Function type args.
   return summary;
 }
 
@@ -3318,9 +3318,12 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* locs = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(kFunctionTypeArgumentsReg));
-  locs->set_out(0, Location::RegisterLocation(R0));
+  locs->set_in(0, Location::RegisterLocation(
+                      InstantiationABI::kInstantiatorTypeArgumentsReg));
+  locs->set_in(1, Location::RegisterLocation(
+                      InstantiationABI::kFunctionTypeArgumentsReg));
+  locs->set_out(0,
+                Location::RegisterLocation(InstantiationABI::kResultTypeReg));
   return locs;
 }
 
@@ -3334,7 +3337,8 @@
   // A runtime call to instantiate the type is required.
   __ PushObject(Object::null_object());  // Make room for the result.
   __ PushObject(type());
-  static_assert(kFunctionTypeArgumentsReg < kInstantiatorTypeArgumentsReg,
+  static_assert(InstantiationABI::kFunctionTypeArgumentsReg <
+                    InstantiationABI::kInstantiatorTypeArgumentsReg,
                 "Should be ordered to push arguments with one instruction");
   __ PushList((1 << instantiator_type_args_reg) |
               (1 << function_type_args_reg));
@@ -3351,9 +3355,12 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* locs = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(kFunctionTypeArgumentsReg));
-  locs->set_out(0, Location::RegisterLocation(kResultTypeArgumentsReg));
+  locs->set_in(0, Location::RegisterLocation(
+                      InstantiationABI::kInstantiatorTypeArgumentsReg));
+  locs->set_in(1, Location::RegisterLocation(
+                      InstantiationABI::kFunctionTypeArgumentsReg));
+  locs->set_out(
+      0, Location::RegisterLocation(InstantiationABI::kResultTypeArgumentsReg));
   return locs;
 }
 
@@ -3380,7 +3387,8 @@
     __ b(&type_arguments_instantiated, EQ);
   }
   // Lookup cache in stub before calling runtime.
-  __ LoadObject(kUninstantiatedTypeArgumentsReg, type_arguments());
+  __ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
+                type_arguments());
   compiler->GenerateCall(token_pos(), GetStub(), RawPcDescriptors::kOther,
                          locs());
   __ Bind(&type_arguments_instantiated);
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 5987165..0b8a188 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -627,8 +627,8 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  summary->set_in(0, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  summary->set_in(1, Location::RegisterLocation(kFunctionTypeArgumentsReg));
+  summary->set_in(0, Location::RegisterLocation(R2));  // Instant. type args.
+  summary->set_in(1, Location::RegisterLocation(R1));  // Function type args.
   return summary;
 }
 
@@ -2809,9 +2809,12 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* locs = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(kFunctionTypeArgumentsReg));
-  locs->set_out(0, Location::RegisterLocation(R0));
+  locs->set_in(0, Location::RegisterLocation(
+                      InstantiationABI::kInstantiatorTypeArgumentsReg));
+  locs->set_in(1, Location::RegisterLocation(
+                      InstantiationABI::kFunctionTypeArgumentsReg));
+  locs->set_out(0,
+                Location::RegisterLocation(InstantiationABI::kResultTypeReg));
   return locs;
 }
 
@@ -2839,9 +2842,12 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* locs = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(kFunctionTypeArgumentsReg));
-  locs->set_out(0, Location::RegisterLocation(kResultTypeArgumentsReg));
+  locs->set_in(0, Location::RegisterLocation(
+                      InstantiationABI::kInstantiatorTypeArgumentsReg));
+  locs->set_in(1, Location::RegisterLocation(
+                      InstantiationABI::kFunctionTypeArgumentsReg));
+  locs->set_out(
+      0, Location::RegisterLocation(InstantiationABI::kResultTypeArgumentsReg));
   return locs;
 }
 
@@ -2871,7 +2877,8 @@
     __ Bind(&non_null_type_args);
   }
   // Lookup cache in stub before calling runtime.
-  __ LoadObject(kUninstantiatedTypeArgumentsReg, type_arguments());
+  __ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
+                type_arguments());
   compiler->GenerateCall(token_pos(), GetStub(), RawPcDescriptors::kOther,
                          locs());
   __ Bind(&type_arguments_instantiated);
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 4d31a35..89ec595 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -368,8 +368,10 @@
   LocationSummary* summary = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
   summary->set_in(0, Location::RegisterLocation(EAX));  // Value.
-  summary->set_in(1, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  summary->set_in(2, Location::RegisterLocation(kFunctionTypeArgumentsReg));
+  summary->set_in(1, Location::RegisterLocation(
+                         TypeTestABI::kInstantiatorTypeArgumentsReg));
+  summary->set_in(
+      2, Location::RegisterLocation(TypeTestABI::kFunctionTypeArgumentsReg));
   summary->set_out(0, Location::RegisterLocation(EAX));
   return summary;
 }
@@ -380,8 +382,8 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  summary->set_in(0, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  summary->set_in(1, Location::RegisterLocation(kFunctionTypeArgumentsReg));
+  summary->set_in(0, Location::RegisterLocation(EDX));  // Instant. type args.
+  summary->set_in(1, Location::RegisterLocation(ECX));  // Function type args.
   return summary;
 }
 
@@ -2229,17 +2231,20 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  summary->set_in(0, Location::RegisterLocation(EAX));  // Instance.
-  summary->set_in(1, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  summary->set_in(2, Location::RegisterLocation(kFunctionTypeArgumentsReg));
+
+  summary->set_in(0, Location::RegisterLocation(TypeTestABI::kInstanceReg));
+  summary->set_in(1, Location::RegisterLocation(
+                         TypeTestABI::kInstantiatorTypeArgumentsReg));
+  summary->set_in(
+      2, Location::RegisterLocation(TypeTestABI::kFunctionTypeArgumentsReg));
   summary->set_out(0, Location::RegisterLocation(EAX));
   return summary;
 }
 
 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(locs()->in(0).reg() == EAX);  // Value.
-  ASSERT(locs()->in(1).reg() == kInstantiatorTypeArgumentsReg);
-  ASSERT(locs()->in(2).reg() == kFunctionTypeArgumentsReg);
+  ASSERT(locs()->in(0).reg() == TypeTestABI::kInstanceReg);
+  ASSERT(locs()->in(1).reg() == TypeTestABI::kInstantiatorTypeArgumentsReg);
+  ASSERT(locs()->in(2).reg() == TypeTestABI::kFunctionTypeArgumentsReg);
 
   compiler->GenerateInstanceOf(token_pos(), deopt_id(), type(), locs());
   ASSERT(locs()->out(0).reg() == EAX);
@@ -2488,9 +2493,12 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* locs = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(kFunctionTypeArgumentsReg));
-  locs->set_out(0, Location::RegisterLocation(EAX));
+  locs->set_in(0, Location::RegisterLocation(
+                      InstantiationABI::kInstantiatorTypeArgumentsReg));
+  locs->set_in(1, Location::RegisterLocation(
+                      InstantiationABI::kFunctionTypeArgumentsReg));
+  locs->set_out(0,
+                Location::RegisterLocation(InstantiationABI::kResultTypeReg));
   return locs;
 }
 
@@ -2519,9 +2527,12 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* locs = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(kFunctionTypeArgumentsReg));
-  locs->set_out(0, Location::RegisterLocation(kResultTypeArgumentsReg));
+  locs->set_in(0, Location::RegisterLocation(
+                      InstantiationABI::kInstantiatorTypeArgumentsReg));
+  locs->set_in(1, Location::RegisterLocation(
+                      InstantiationABI::kFunctionTypeArgumentsReg));
+  locs->set_out(
+      0, Location::RegisterLocation(InstantiationABI::kResultTypeArgumentsReg));
   return locs;
 }
 
@@ -2551,7 +2562,8 @@
     __ Bind(&non_null_type_args);
   }
   // Lookup cache in stub before calling runtime.
-  __ LoadObject(kUninstantiatedTypeArgumentsReg, type_arguments());
+  __ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
+                type_arguments());
   compiler->GenerateCall(token_pos(), GetStub(), RawPcDescriptors::kOther,
                          locs());
   __ Bind(&type_arguments_instantiated);
diff --git a/runtime/vm/compiler/backend/il_test_helper.h b/runtime/vm/compiler/backend/il_test_helper.h
index 9555044..9655791 100644
--- a/runtime/vm/compiler/backend/il_test_helper.h
+++ b/runtime/vm/compiler/backend/il_test_helper.h
@@ -71,7 +71,7 @@
                         CompilerPass::PipelineMode mode)
       : function_(function),
         thread_(Thread::Current()),
-        compiler_state_(thread_),
+        compiler_state_(thread_, mode == CompilerPass::PipelineMode::kAOT),
         mode_(mode) {}
   ~TestPipeline() { delete pass_state_; }
 
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index d1eff91..a9c78e1 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -582,8 +582,8 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  summary->set_in(0, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  summary->set_in(1, Location::RegisterLocation(kFunctionTypeArgumentsReg));
+  summary->set_in(0, Location::RegisterLocation(RDX));  // Instant. type args.
+  summary->set_in(1, Location::RegisterLocation(RCX));  // Function type args.
   return summary;
 }
 
@@ -2505,8 +2505,8 @@
 
 void InstanceOfInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   ASSERT(locs()->in(0).reg() == TypeTestABI::kInstanceReg);
-  ASSERT(locs()->in(1).reg() == kInstantiatorTypeArgumentsReg);
-  ASSERT(locs()->in(2).reg() == kFunctionTypeArgumentsReg);
+  ASSERT(locs()->in(1).reg() == TypeTestABI::kInstantiatorTypeArgumentsReg);
+  ASSERT(locs()->in(2).reg() == TypeTestABI::kFunctionTypeArgumentsReg);
 
   compiler->GenerateInstanceOf(token_pos(), deopt_id(), type(), locs());
   ASSERT(locs()->out(0).reg() == RAX);
@@ -2801,9 +2801,12 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* locs = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(kFunctionTypeArgumentsReg));
-  locs->set_out(0, Location::RegisterLocation(RAX));
+  locs->set_in(0, Location::RegisterLocation(
+                      InstantiationABI::kInstantiatorTypeArgumentsReg));
+  locs->set_in(1, Location::RegisterLocation(
+                      InstantiationABI::kFunctionTypeArgumentsReg));
+  locs->set_out(0,
+                Location::RegisterLocation(InstantiationABI::kResultTypeReg));
   return locs;
 }
 
@@ -2832,9 +2835,12 @@
   const intptr_t kNumTemps = 0;
   LocationSummary* locs = new (zone)
       LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_in(0, Location::RegisterLocation(kInstantiatorTypeArgumentsReg));
-  locs->set_in(1, Location::RegisterLocation(kFunctionTypeArgumentsReg));
-  locs->set_out(0, Location::RegisterLocation(kResultTypeArgumentsReg));
+  locs->set_in(0, Location::RegisterLocation(
+                      InstantiationABI::kInstantiatorTypeArgumentsReg));
+  locs->set_in(1, Location::RegisterLocation(
+                      InstantiationABI::kFunctionTypeArgumentsReg));
+  locs->set_out(
+      0, Location::RegisterLocation(InstantiationABI::kResultTypeArgumentsReg));
   return locs;
 }
 
@@ -2863,7 +2869,8 @@
     __ j(EQUAL, &type_arguments_instantiated, compiler::Assembler::kNearJump);
     __ Bind(&non_null_type_args);
   }
-  __ LoadObject(kUninstantiatedTypeArgumentsReg, type_arguments());
+  __ LoadObject(InstantiationABI::kUninstantiatedTypeArgumentsReg,
+                type_arguments());
   compiler->GenerateCall(token_pos(), GetStub(), RawPcDescriptors::kOther,
                          locs());
   __ Bind(&type_arguments_instantiated);
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index 139e73d..c124196 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -367,8 +367,9 @@
       const InstanceCallInfo& info =
           instance_calls_[i + instance_call_start_ix];
       intptr_t aggregate_count =
-          FLAG_precompiled_mode ? AotCallCountApproximation(info.nesting_depth)
-                                : info.call->CallCount();
+          CompilerState::Current().is_aot()
+              ? AotCallCountApproximation(info.nesting_depth)
+              : info.call->CallCount();
       instance_call_counts.Add(aggregate_count);
       if (aggregate_count > max_count) max_count = aggregate_count;
     }
@@ -377,8 +378,9 @@
     for (intptr_t i = 0; i < num_static_calls; ++i) {
       const StaticCallInfo& info = static_calls_[i + static_call_start_ix];
       intptr_t aggregate_count =
-          FLAG_precompiled_mode ? AotCallCountApproximation(info.nesting_depth)
-                                : info.call->CallCount();
+          CompilerState::Current().is_aot()
+              ? AotCallCountApproximation(info.nesting_depth)
+              : info.call->CallCount();
       static_call_counts.Add(aggregate_count);
       if (aggregate_count > max_count) max_count = aggregate_count;
     }
@@ -449,7 +451,7 @@
         (depth >= inlining_depth_threshold_);
 
     // In AOT, compute loop hierarchy.
-    if (FLAG_precompiled_mode) {
+    if (CompilerState::Current().is_aot()) {
       graph->GetLoopHierarchy();
     }
 
@@ -913,7 +915,7 @@
 
     // Don't inline any intrinsified functions in precompiled mode
     // to reduce code size and make sure we use the intrinsic code.
-    if (FLAG_precompiled_mode && function.is_intrinsic() &&
+    if (CompilerState::Current().is_aot() && function.is_intrinsic() &&
         !inliner_->AlwaysInline(function)) {
       TRACE_INLINING(THR_Print("     Bailout: intrinisic\n"));
       PRINT_INLINING_TREE("intrinsic", &call_data->caller, &function,
@@ -923,7 +925,7 @@
 
     // Do not rely on function type feedback or presence of code to determine
     // if a function was compiled.
-    if (!FLAG_precompiled_mode && !function.WasCompiled()) {
+    if (!CompilerState::Current().is_aot() && !function.WasCompiled()) {
       TRACE_INLINING(THR_Print("     Bailout: not compiled yet\n"));
       PRINT_INLINING_TREE("Not compiled", &call_data->caller, &function,
                           call_data->call);
@@ -932,7 +934,8 @@
 
     // Type feedback may have been cleared for this function (ClearICDataArray),
     // but we need it for inlining.
-    if (!FLAG_precompiled_mode && (function.ic_data_array() == Array::null())) {
+    if (!CompilerState::Current().is_aot() &&
+        (function.ic_data_array() == Array::null())) {
       TRACE_INLINING(THR_Print("     Bailout: type feedback cleared\n"));
       PRINT_INLINING_TREE("Not compiled", &call_data->caller, &function,
                           call_data->call);
@@ -1050,7 +1053,7 @@
           CalleeGraphValidator::Validate(callee_graph);
         }
 #if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
-        if (FLAG_precompiled_mode) {
+        if (CompilerState::Current().is_aot()) {
           callee_graph->PopulateWithICData(parsed_function->function());
         }
 #endif
@@ -1058,7 +1061,7 @@
         // If we inline a function which is intrinsified without a fall-through
         // to IR code, we will not have any ICData attached, so we do it
         // manually here.
-        if (!FLAG_precompiled_mode && function.is_intrinsic()) {
+        if (!CompilerState::Current().is_aot() && function.is_intrinsic()) {
           callee_graph->PopulateWithICData(parsed_function->function());
         }
 
@@ -1143,7 +1146,7 @@
         {
           // TODO(fschneider): Improve suppression of speculative inlining.
           // Deopt-ids overlap between caller and callee.
-          if (FLAG_precompiled_mode) {
+          if (CompilerState::Current().is_aot()) {
 #if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_IA32)
             AotCallSpecializer call_specializer(inliner_->precompiler_,
                                                 callee_graph,
@@ -1292,8 +1295,8 @@
     // In background compilation we may abort compilation as the state
     // changes while compiling. Propagate that 'error' and retry compilation
     // later.
-    ASSERT(FLAG_precompiled_mode || Compiler::IsBackgroundCompilation() ||
-           error.IsUnhandledException());
+    ASSERT(CompilerState::Current().is_aot() ||
+           Compiler::IsBackgroundCompilation() || error.IsUnhandledException());
     Thread::Current()->long_jump_base()->Jump(1, error);
     UNREACHABLE();
     return false;
@@ -1439,7 +1442,7 @@
       // to a relatively high ratio. So, unless we are optimizing solely for
       // speed, such call sites are subject to subsequent stricter heuristic
       // to limit code size increase.
-      bool stricter_heuristic = FLAG_precompiled_mode &&
+      bool stricter_heuristic = CompilerState::Current().is_aot() &&
                                 FLAG_optimization_level <= 2 &&
                                 !inliner_->AlwaysInline(target) &&
                                 call_info[call_idx].nesting_depth == 0;
@@ -1748,7 +1751,7 @@
 }
 
 bool PolymorphicInliner::TryInliningPoly(const TargetInfo& target_info) {
-  if ((!FLAG_precompiled_mode ||
+  if ((!CompilerState::Current().is_aot() ||
        owner_->inliner_->speculative_policy()->AllowsSpeculativeInlining()) &&
       target_info.IsSingleCid() &&
       TryInlineRecognizedMethod(target_info.cid_start, *target_info.target)) {
@@ -3038,7 +3041,7 @@
     case kExternalTypedDataUint8ClampedArrayCid:
     case kTypedDataInt16ArrayCid:
     case kTypedDataUint16ArrayCid: {
-      if (FLAG_precompiled_mode &&
+      if (CompilerState::Current().is_aot() &&
           flow_graph->isolate()->can_use_strong_mode_types()) {
         needs_null_check = true;
       } else {
@@ -3049,7 +3052,7 @@
     }
     case kTypedDataInt32ArrayCid:
     case kTypedDataUint32ArrayCid:
-      if (FLAG_precompiled_mode &&
+      if (CompilerState::Current().is_aot() &&
           flow_graph->isolate()->can_use_strong_mode_types()) {
         needs_null_check = true;
       } else {
@@ -3062,7 +3065,7 @@
     case kTypedDataFloat32ArrayCid:
     case kTypedDataFloat64ArrayCid: {
       // Check that value is always double.
-      if (FLAG_precompiled_mode &&
+      if (CompilerState::Current().is_aot() &&
           flow_graph->isolate()->can_use_strong_mode_types()) {
         needs_null_check = true;
       } else {
@@ -3085,7 +3088,7 @@
       // StoreIndexedInstr takes unboxed int64, so value is
       // checked when unboxing. In AOT Dart2, we use an
       // explicit null check and non-speculative unboxing.
-      needs_null_check = FLAG_precompiled_mode &&
+      needs_null_check = CompilerState::Current().is_aot() &&
                          flow_graph->isolate()->can_use_strong_mode_types();
       break;
     default:
@@ -3561,7 +3564,7 @@
     case MethodRecognizer::kFloat64x2Add:
     case MethodRecognizer::kFloat64x2Sub:
       *last = SimdOpInstr::CreateFromCall(Z, kind, receiver, call);
-      if (FLAG_precompiled_mode) {
+      if (CompilerState::Current().is_aot()) {
         // Add null-checks in case of the arguments are known to be compatible
         // but they are possibly nullable.
         // By inserting the null-check, we can allow the unbox instruction later
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index 8a81d68..7ab4dc2 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -837,7 +837,7 @@
     scheduler_.Start();
 
     // AOT should only see non-deopting GenericCheckBound.
-    ASSERT(!FLAG_precompiled_mode);
+    ASSERT(!CompilerState::Current().is_aot());
 
     ConstantInstr* max_smi = flow_graph_->GetConstant(
         Smi::Handle(Smi::New(compiler::target::kSmiMax)));
@@ -1350,7 +1350,7 @@
     // check earlier and we are not compiling precompiled code
     // (no optimistic hoisting of checks possible)
     const bool try_generalization =
-        !FLAG_precompiled_mode &&
+        !CompilerState::Current().is_aot() &&
         !function.ProhibitsBoundsCheckGeneralization();
     BoundsCheckGeneralizer generalizer(this, flow_graph_);
     for (CheckBoundBase* check : bounds_checks_) {
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index 0ca9eb8..b2eb8d5 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -1327,10 +1327,10 @@
   } else if (current->IsCheckEitherNonSmi()) {
     current->AsCheckEitherNonSmi()->set_licm_hoisted(true);
   } else if (current->IsCheckArrayBound()) {
-    ASSERT(!FLAG_precompiled_mode);  // speculative in JIT only
+    ASSERT(!CompilerState::Current().is_aot());  // speculative in JIT only
     current->AsCheckArrayBound()->set_licm_hoisted(true);
   } else if (current->IsGenericCheckBound()) {
-    ASSERT(FLAG_precompiled_mode);  // non-speculative in AOT only
+    ASSERT(CompilerState::Current().is_aot());  // non-speculative in AOT only
     // Does not deopt, so no need for licm_hoisted flag.
   } else if (current->IsTestCids()) {
     current->AsTestCids()->set_licm_hoisted(true);
@@ -1405,7 +1405,7 @@
 
 void LICM::OptimisticallySpecializeSmiPhis() {
   if (flow_graph()->function().ProhibitsHoistingCheckClass() ||
-      FLAG_precompiled_mode) {
+      CompilerState::Current().is_aot()) {
     // Do not hoist any: Either deoptimized on a hoisted check,
     // or compiling precompiled code where we can't do optimistic
     // hoisting of checks.
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
index 8010098..7164e20 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -16,6 +16,7 @@
 #include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/frontend/kernel_to_il.h"
 #include "vm/compiler/jit/jit_call_specializer.h"
+#include "vm/flags.h"
 #include "vm/log.h"
 #include "vm/object.h"
 #include "vm/parser.h"
@@ -270,7 +271,7 @@
       Function::ZoneHandle(GetFunction(lib, "blackhole"));
 
   using compiler::BlockBuilder;
-  CompilerState S(thread);
+  CompilerState S(thread, /*is_aot=*/false);
   FlowGraphBuilderHelper H;
 
   // We are going to build the following graph:
@@ -432,7 +433,7 @@
       Function::ZoneHandle(GetFunction(lib, "blackhole"));
 
   using compiler::BlockBuilder;
-  CompilerState S(thread);
+  CompilerState S(thread, /*is_aot=*/false);
   FlowGraphBuilderHelper H;
 
   // We are going to build the following graph:
@@ -587,7 +588,7 @@
 // https://github.com/flutter/flutter/issues/48114.
 ISOLATE_UNIT_TEST_CASE(LoadOptimizer_AliasingViaTypedDataAndUntaggedTypedData) {
   using compiler::BlockBuilder;
-  CompilerState S(thread);
+  CompilerState S(thread, /*is_aot=*/false);
   FlowGraphBuilderHelper H;
 
   const auto& lib = Library::Handle(Library::TypedDataLibrary());
diff --git a/runtime/vm/compiler/backend/slot.cc b/runtime/vm/compiler/backend/slot.cc
index b5572d7..3f13a8c 100644
--- a/runtime/vm/compiler/backend/slot.cc
+++ b/runtime/vm/compiler/backend/slot.cc
@@ -255,7 +255,7 @@
     } else {
       // In precompiled mode we use guarded_cid field for type information
       // inferred by TFA.
-      ASSERT(FLAG_precompiled_mode);
+      ASSERT(CompilerState::Current().is_aot());
     }
   }
 
diff --git a/runtime/vm/compiler/backend/slot_test.cc b/runtime/vm/compiler/backend/slot_test.cc
index f8b3637..7dea9b7 100644
--- a/runtime/vm/compiler/backend/slot_test.cc
+++ b/runtime/vm/compiler/backend/slot_test.cc
@@ -63,7 +63,7 @@
   field.set_is_nullable(false);
 
   // Enter compiler state.
-  CompilerState compiler_state(thread);
+  CompilerState compiler_state(thread, /*is_aot=*/false);
 
   const Field& field_clone_1 = Field::ZoneHandle(field.CloneFromOriginal());
   const Field& field_clone_2 = Field::ZoneHandle(field.CloneFromOriginal());
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 7b65475..629c9b0 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -815,17 +815,13 @@
   if (other.IsTopTypeForAssignability()) {
     return true;
   }
-
   if (IsNone()) {
     return false;
   }
-
-  // Consider the compile type of the value.
-  const AbstractType& compile_type = *ToAbstractType();
-  if (compile_type.IsNullType()) {
-    return Instance::NullIsAssignableTo(other);
+  if (is_nullable() && !Instance::NullIsAssignableTo(other)) {
+    return false;
   }
-  return compile_type.IsSubtypeOf(other, Heap::kOld);
+  return ToAbstractType()->IsSubtypeOf(other, Heap::kOld);
 }
 
 bool CompileType::IsInstanceOf(const AbstractType& other) {
diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc
index 33fa26d..b68ee83 100644
--- a/runtime/vm/compiler/backend/type_propagator_test.cc
+++ b/runtime/vm/compiler/backend/type_propagator_test.cc
@@ -26,7 +26,7 @@
 using compiler::BlockBuilder;
 
 ISOLATE_UNIT_TEST_CASE(TypePropagator_RedefinitionAfterStrictCompareWithNull) {
-  CompilerState S(thread);
+  CompilerState S(thread, /*is_aot=*/false);
 
   FlowGraphBuilderHelper H;
 
@@ -101,7 +101,7 @@
 
 ISOLATE_UNIT_TEST_CASE(
     TypePropagator_RedefinitionAfterStrictCompareWithLoadClassId) {
-  CompilerState S(thread);
+  CompilerState S(thread, /*is_aot=*/false);
 
   FlowGraphBuilderHelper H;
 
@@ -164,7 +164,7 @@
 }
 
 ISOLATE_UNIT_TEST_CASE(TypePropagator_Refinement) {
-  CompilerState S(thread);
+  CompilerState S(thread, /*is_aot=*/false);
 
   const Class& object_class =
       Class::Handle(thread->isolate()->object_store()->object_class());
@@ -266,7 +266,7 @@
 // This test verifies that mutable compile types are not incorrectly cached
 // as reaching types after inference.
 ISOLATE_UNIT_TEST_CASE(TypePropagator_Regress36156) {
-  CompilerState S(thread);
+  CompilerState S(thread, /*is_aot=*/false);
   FlowGraphBuilderHelper H;
 
   // We are going to build the following graph:
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index f519b11..9a353cc 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -113,7 +113,7 @@
 
   const Token::Kind op_kind = call->token_kind();
   if (FLAG_guess_icdata_cid) {
-    if (FLAG_precompiled_mode) {
+    if (CompilerState::Current().is_aot()) {
       // In precompiler speculate that both sides of bitwise operation
       // are Smi-s.
       if (Token::IsBinaryBitwiseOperator(op_kind) &&
@@ -757,7 +757,7 @@
                    call->env(), call);
       break;
     case FlowGraph::ToCheck::kCheckCid:
-      if (FLAG_precompiled_mode) {
+      if (CompilerState::Current().is_aot()) {
         return false;  // AOT cannot class check
       }
       AddReceiverCheck(call);
@@ -813,7 +813,7 @@
                    instr->env(), instr);
       break;
     case FlowGraph::ToCheck::kCheckCid:
-      if (FLAG_precompiled_mode) {
+      if (CompilerState::Current().is_aot()) {
         return false;  // AOT cannot class check
       }
       AddReceiverCheck(instr);
@@ -824,7 +824,7 @@
 
   // True if we can use unchecked entry into the setter.
   bool is_unchecked_call = false;
-  if (!FLAG_precompiled_mode) {
+  if (!CompilerState::Current().is_aot()) {
     if (targets.IsMonomorphic() && targets.MonomorphicExactness().IsExact()) {
       if (targets.MonomorphicExactness().IsTriviallyExact()) {
         flow_graph()->AddExactnessGuard(instr,
@@ -1113,8 +1113,9 @@
       is_subtype = unwrapped_type.IsTopType() || unwrapped_type.IsNullable() ||
                    (unwrapped_type.IsLegacy() && unwrapped_type.IsNeverType());
     } else {
-      is_subtype = Class::IsSubtypeOf(cls, Object::null_type_arguments(), type,
-                                      Heap::kOld);
+      is_subtype =
+          Class::IsSubtypeOf(cls, Object::null_type_arguments(),
+                             Nullability::kNonNullable, type, Heap::kOld);
     }
     results->Add(cls.id());
     results->Add(static_cast<intptr_t>(is_subtype));
@@ -1147,7 +1148,7 @@
   // Private classes cannot be subclassed by later loaded libs.
   if (!type_class.IsPrivate()) {
     // In AOT mode we can't use CHA deoptimizations.
-    ASSERT(!FLAG_precompiled_mode || !FLAG_use_cha_deopt);
+    ASSERT(!CompilerState::Current().is_aot() || !FLAG_use_cha_deopt);
     if (FLAG_use_cha_deopt || isolate()->all_classes_finalized()) {
       if (FLAG_trace_cha) {
         THR_Print(
@@ -1296,7 +1297,7 @@
         new (Z) ZoneGrowableArray<intptr_t>(number_of_checks * 2);
     const Bool& as_bool =
         Bool::ZoneHandle(Z, InstanceOfAsBool(unary_checks, type, results));
-    if (as_bool.IsNull() || FLAG_precompiled_mode) {
+    if (as_bool.IsNull() || CompilerState::Current().is_aot()) {
       if (results->length() == number_of_checks * 2) {
         const bool can_deopt = SpecializeTestCidsForNumericTypes(results, type);
         if (can_deopt &&
@@ -1451,8 +1452,9 @@
   const ClassTable& class_table = *Isolate::Current()->class_table();
   if ((*results)[0] != kSmiCid) {
     const Class& smi_class = Class::Handle(class_table.At(kSmiCid));
-    const bool smi_is_subtype = Class::IsSubtypeOf(
-        smi_class, Object::null_type_arguments(), type, Heap::kOld);
+    const bool smi_is_subtype =
+        Class::IsSubtypeOf(smi_class, Object::null_type_arguments(),
+                           Nullability::kNonNullable, type, Heap::kOld);
     results->Add((*results)[results->length() - 2]);
     results->Add((*results)[results->length() - 2]);
     for (intptr_t i = results->length() - 3; i > 1; --i) {
diff --git a/runtime/vm/compiler/compiler_pass.cc b/runtime/vm/compiler/compiler_pass.cc
index 8d79cc1..ed13b59 100644
--- a/runtime/vm/compiler/compiler_pass.cc
+++ b/runtime/vm/compiler/compiler_pass.cc
@@ -482,7 +482,8 @@
               { TypedDataSpecializer::Optimize(flow_graph); });
 
 COMPILER_PASS(TryCatchOptimization, {
-  OptimizeCatchEntryStates(flow_graph, /*is_aot=*/FLAG_precompiled_mode);
+  OptimizeCatchEntryStates(flow_graph,
+                           /*is_aot=*/CompilerState::Current().is_aot());
 });
 
 COMPILER_PASS(EliminateEnvironments, { flow_graph->EliminateEnvironments(); });
diff --git a/runtime/vm/compiler/compiler_state.h b/runtime/vm/compiler/compiler_state.h
index e1a5f5c..4b3a590 100644
--- a/runtime/vm/compiler/compiler_state.h
+++ b/runtime/vm/compiler/compiler_state.h
@@ -57,8 +57,8 @@
 // Global compiler state attached to the thread.
 class CompilerState : public ThreadStackResource {
  public:
-  explicit CompilerState(Thread* thread)
-      : ThreadStackResource(thread), cha_(thread) {
+  CompilerState(Thread* thread, bool is_aot)
+      : ThreadStackResource(thread), cha_(thread), is_aot_(is_aot) {
     previous_ = thread->SetCompilerState(this);
   }
 
@@ -119,6 +119,8 @@
   // share id 255.
   LocalVariable* GetDummyCapturedVariable(intptr_t context_id, intptr_t index);
 
+  bool is_aot() const { return is_aot_; }
+
  private:
   CHA cha_;
   intptr_t deopt_id_ = 0;
@@ -131,6 +133,8 @@
   ZoneGrowableArray<ZoneGrowableArray<const Slot*>*>* dummy_slots_ = nullptr;
   ZoneGrowableArray<LocalVariable*>* dummy_captured_vars_ = nullptr;
 
+  bool is_aot_;
+
   CompilerState* previous_;
 };
 
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index 6ee4ead..da73826 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -1014,7 +1014,7 @@
   // reconsider this heuristic if we identify non-inlined type-checks in
   // hotspots of new benchmarks.
   if (!IsInlining() && (parsed_function_->function().IsClosureFunction() ||
-                        !FLAG_precompiled_mode)) {
+                        !CompilerState::Current().is_aot())) {
     graph_entry->set_unchecked_entry(unchecked_entry);
   } else if (InliningUncheckedEntry()) {
     graph_entry->set_normal_entry(unchecked_entry);
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index b1c25bb..1d16d3b 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -822,7 +822,7 @@
       BuildFfiAsFunction();
       return;
     case MethodRecognizer::kFfiNativeCallbackFunction:
-      if (FLAG_precompiled_mode) {
+      if (CompilerState::Current().is_aot()) {
         BuildFfiNativeCallbackFunction();
         return;
       }
@@ -1409,7 +1409,8 @@
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
   }
 
-  const String& selector = String::Cast(ConstantAt(DecodeOperandD()).value());
+  const String& selector =
+      String::CheckedZoneHandle(Z, ConstantAt(DecodeOperandD()).value().raw());
 
   LocalVariable* receiver_temp = B->MakeTemporary();
   code_ +=
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index dda878c..d0381e0 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -15,6 +15,7 @@
 #include "vm/dart_api_impl.h"  // For Api::IsFfiEnabled().
 #include "vm/dart_entry.h"
 #include "vm/debugger.h"
+#include "vm/flags.h"
 #include "vm/hash.h"
 #include "vm/longjump.h"
 #include "vm/object_store.h"
@@ -2445,7 +2446,7 @@
       if (!cls.IsTopLevel()) {
         scoped_function_class_ = H.GetExpressionEvaluationRealClass();
       }
-      CompilerState compiler_state(thread_);
+      CompilerState compiler_state(thread_, FLAG_precompiled_mode);
       ReadCode(function, function.bytecode_offset());
     }
 
@@ -3427,7 +3428,7 @@
     } else if (function.is_declared_in_bytecode()) {
       const intptr_t code_offset = function.bytecode_offset();
       if (code_offset != 0) {
-        CompilerState compiler_state(thread);
+        CompilerState compiler_state(thread, FLAG_precompiled_mode);
 
         const Script& script = Script::Handle(zone, function.script());
         TranslationHelper translation_helper(thread);
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 54c2e4b..4e4df30 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -2326,7 +2326,7 @@
   }
 
   if (!direct_call.target_.IsNull()) {
-    ASSERT(FLAG_precompiled_mode);
+    ASSERT(CompilerState::Current().is_aot());
     instructions +=
         StaticCall(position, direct_call.target_, 1, Array::null_array(),
                    ICData::kNoRebind, &result_type);
@@ -2413,7 +2413,7 @@
   }
 
   if (!direct_call_target->IsNull()) {
-    ASSERT(FLAG_precompiled_mode);
+    ASSERT(CompilerState::Current().is_aot());
     instructions +=
         StaticCall(position, *direct_call_target, 2, Array::null_array(),
                    ICData::kNoRebind, /*result_type=*/nullptr,
@@ -3005,7 +3005,7 @@
     // Even if TFA infers a concrete receiver type, the static type of the
     // call-site may still be dynamic and we need to call the dynamic invocation
     // forwarder to ensure type-checks are performed.
-    ASSERT(FLAG_precompiled_mode);
+    ASSERT(CompilerState::Current().is_aot());
     instructions +=
         StaticCall(position, *direct_call_target, argument_count,
                    argument_names, ICData::kNoRebind, &result_type,
@@ -3266,7 +3266,7 @@
   const auto recognized_kind = target.recognized_kind();
   if (recognized_kind == MethodRecognizer::kFfiAsFunctionInternal) {
     return BuildFfiAsFunctionInternal();
-  } else if (FLAG_precompiled_mode &&
+  } else if (CompilerState::Current().is_aot() &&
              recognized_kind == MethodRecognizer::kFfiNativeCallbackFunction) {
     return BuildFfiNativeCallbackFunction();
   }
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 4b59c97..6b311fb 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -8,6 +8,7 @@
 #include "vm/compiler/aot/precompiler.h"
 #include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/compiler/frontend/constant_reader.h"
+#include "vm/flags.h"
 #include "vm/log.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"  // for ParsedFunction
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 260c822..1d7e9c8 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -290,7 +290,7 @@
         parsed_function_->set_receiver_var(variable);
       }
       if (is_setter) {
-        if (FLAG_precompiled_mode) {
+        if (CompilerState::Current().is_aot()) {
           const intptr_t kernel_offset = field.kernel_offset();
           const InferredTypeMetadata parameter_type =
               inferred_type_metadata_helper_.GetInferredType(kernel_offset);
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index 401c96d..ea9e245 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -347,7 +347,7 @@
     compiler::Assembler* assembler,
     FlowGraphCompiler* graph_compiler,
     FlowGraph* flow_graph) {
-  ASSERT(!FLAG_precompiled_mode);
+  ASSERT(!CompilerState::Current().is_aot());
   const Function& function = parsed_function()->function();
   Zone* const zone = thread()->zone();
 
@@ -531,7 +531,7 @@
       FlowGraph* flow_graph = nullptr;
       ZoneGrowableArray<const ICData*>* ic_data_array = nullptr;
 
-      CompilerState compiler_state(thread());
+      CompilerState compiler_state(thread(), /*is_aot=*/false);
 
       {
         if (optimized()) {
@@ -750,7 +750,6 @@
 
     CompileParsedFunctionHelper helper(parsed_function, optimized, osr_id);
 
-
     const Code& result = Code::Handle(helper.Compile(pipeline));
 
     if (result.IsNull()) {
@@ -948,6 +947,7 @@
 
 void Compiler::ComputeLocalVarDescriptors(const Code& code) {
   ASSERT(!code.is_optimized());
+  ASSERT(!FLAG_precompiled_mode);
   const Function& function = Function::Handle(code.function());
   ASSERT(code.var_descriptors() == Object::null());
   // IsIrregexpFunction have eager var descriptors generation.
@@ -956,7 +956,7 @@
   // if state changed while compiling in background.
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
-  CompilerState state(thread);
+  CompilerState state(thread, /*is_aot=*/false);
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     ParsedFunction* parsed_function =
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index 0f637de..490f4c1 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -2960,9 +2960,8 @@
     Assembler* assembler) {
   Label done;
 
-  const Register kInstanceReg = R0;
   // Fast case for 'null'.
-  __ CompareObject(kInstanceReg, NullObject());
+  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
   __ BranchIf(EQUAL, &done);
 
   __ ldr(CODE_REG, Address(THR, target::Thread::slow_type_test_stub_offset()));
@@ -3014,10 +3013,9 @@
 // Used instead of LazySpecializeTypeTestStub when null is assignable.
 void StubCodeCompiler::GenerateLazySpecializeNullableTypeTestStub(
     Assembler* assembler) {
-  const Register kInstanceReg = R0;
   Label done;
 
-  __ CompareObject(kInstanceReg, NullObject());
+  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
   __ BranchIf(EQUAL, &done);
 
   __ ldr(CODE_REG,
@@ -3033,43 +3031,41 @@
 void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
   Label done, call_runtime;
 
-  const Register kInstanceReg = R0;
-  const Register kDstTypeReg = R8;
-  const Register kSubtypeTestCacheReg = R3;
-
   __ EnterStubFrame();
 
   // If the subtype-cache is null, it needs to be lazily-created by the runtime.
-  __ CompareObject(kSubtypeTestCacheReg, NullObject());
+  __ CompareObject(TypeTestABI::kSubtypeTestCacheReg, NullObject());
   __ BranchIf(EQUAL, &call_runtime);
 
   const Register kTmp = R9;
 
   // If this is not a [Type] object, we'll go to the runtime.
   Label is_simple_case, is_complex_case;
-  __ LoadClassId(kTmp, kDstTypeReg);
+  __ LoadClassId(kTmp, TypeTestABI::kDstTypeReg);
   __ cmp(kTmp, Operand(kTypeCid));
   __ BranchIf(NOT_EQUAL, &is_complex_case);
 
   // Check whether this [Type] is instantiated/uninstantiated.
-  __ ldrb(kTmp, FieldAddress(kDstTypeReg, target::Type::type_state_offset()));
+  __ ldrb(kTmp, FieldAddress(TypeTestABI::kDstTypeReg,
+                             target::Type::type_state_offset()));
   __ cmp(kTmp,
          Operand(target::RawAbstractType::kTypeStateFinalizedInstantiated));
   __ BranchIf(NOT_EQUAL, &is_complex_case);
 
   // Check whether this [Type] is a function type.
-  __ ldr(kTmp, FieldAddress(kDstTypeReg, target::Type::signature_offset()));
+  __ ldr(kTmp, FieldAddress(TypeTestABI::kDstTypeReg,
+                            target::Type::signature_offset()));
   __ CompareObject(kTmp, NullObject());
   __ BranchIf(NOT_EQUAL, &is_complex_case);
 
   // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
-  __ BranchIfSmi(kInstanceReg, &is_complex_case);
+  __ BranchIfSmi(TypeTestABI::kInstanceReg, &is_complex_case);
 
   // Fall through to &is_simple_case
 
-  const intptr_t kRegsToSave = (1 << kSubtypeTestCacheReg) |
-                               (1 << kDstTypeReg) |
-                               (1 << kFunctionTypeArgumentsReg);
+  const intptr_t kRegsToSave = (1 << TypeTestABI::kSubtypeTestCacheReg) |
+                               (1 << TypeTestABI::kDstTypeReg) |
+                               (1 << TypeTestABI::kFunctionTypeArgumentsReg);
 
   __ Bind(&is_simple_case);
   {
@@ -3565,7 +3561,7 @@
     Assembler* assembler) {
   // Lookup cache before calling runtime.
   __ ldr(R0, compiler::FieldAddress(
-                 kUninstantiatedTypeArgumentsReg,
+                 InstantiationABI::kUninstantiatedTypeArgumentsReg,
                  target::TypeArguments::instantiations_offset()));
   __ AddImmediate(R0, compiler::target::Array::data_offset() - kHeapObjectTag);
   // The instantiations cache is initialized with Object::zero_array() and is
@@ -3575,13 +3571,14 @@
   __ ldr(R4, compiler::Address(
                  R0, TypeArguments::Instantiation::kInstantiatorTypeArgsIndex *
                          target::kWordSize));
-  __ cmp(R4, compiler::Operand(kInstantiatorTypeArgumentsReg));
+  __ cmp(R4,
+         compiler::Operand(InstantiationABI::kInstantiatorTypeArgumentsReg));
   __ b(&next, NE);
   // Using IP as destination register and reading it immediately is safe.
   __ ldr(IP, compiler::Address(
                  R0, TypeArguments::Instantiation::kFunctionTypeArgsIndex *
                          target::kWordSize));
-  __ cmp(IP, compiler::Operand(kFunctionTypeArgumentsReg));
+  __ cmp(IP, compiler::Operand(InstantiationABI::kFunctionTypeArgumentsReg));
   __ b(&found, EQ);
   __ Bind(&next);
   __ AddImmediate(
@@ -3593,21 +3590,22 @@
   // A runtime call to instantiate the type arguments is required.
   __ EnterStubFrame();
   __ PushObject(Object::null_object());  // Make room for the result.
-  static_assert(
-      (kUninstantiatedTypeArgumentsReg > kInstantiatorTypeArgumentsReg) &&
-          (kInstantiatorTypeArgumentsReg > kFunctionTypeArgumentsReg),
-      "Should be ordered to push arguments with one instruction");
-  __ PushList((1 << kUninstantiatedTypeArgumentsReg) |
-              (1 << kInstantiatorTypeArgumentsReg) |
-              (1 << kFunctionTypeArgumentsReg));
+  static_assert((InstantiationABI::kUninstantiatedTypeArgumentsReg >
+                 InstantiationABI::kInstantiatorTypeArgumentsReg) &&
+                    (InstantiationABI::kInstantiatorTypeArgumentsReg >
+                     InstantiationABI::kFunctionTypeArgumentsReg),
+                "Should be ordered to push arguments with one instruction");
+  __ PushList((1 << InstantiationABI::kUninstantiatedTypeArgumentsReg) |
+              (1 << InstantiationABI::kInstantiatorTypeArgumentsReg) |
+              (1 << InstantiationABI::kFunctionTypeArgumentsReg));
   __ CallRuntime(kInstantiateTypeArgumentsRuntimeEntry, 3);
   __ Drop(3);  // Drop 2 type vectors, and uninstantiated type.
-  __ Pop(kResultTypeArgumentsReg);  // Pop instantiated type arguments.
+  __ Pop(InstantiationABI::kResultTypeArgumentsReg);
   __ LeaveStubFrame();
   __ Ret();
 
   __ Bind(&found);
-  __ ldr(kResultTypeArgumentsReg,
+  __ ldr(InstantiationABI::kResultTypeArgumentsReg,
          compiler::Address(
              R0, TypeArguments::Instantiation::kInstantiatedTypeArgsIndex *
                      target::kWordSize));
@@ -3620,16 +3618,17 @@
   // Return the instantiator type arguments if its nullability is compatible for
   // sharing, otherwise proceed to instantiation cache lookup.
   compiler::Label cache_lookup;
-  __ ldr(R0,
-         compiler::FieldAddress(kUninstantiatedTypeArgumentsReg,
-                                target::TypeArguments::nullability_offset()));
+  __ ldr(R0, compiler::FieldAddress(
+                 InstantiationABI::kUninstantiatedTypeArgumentsReg,
+                 target::TypeArguments::nullability_offset()));
   __ ldr(R4,
-         compiler::FieldAddress(kInstantiatorTypeArgumentsReg,
+         compiler::FieldAddress(InstantiationABI::kInstantiatorTypeArgumentsReg,
                                 target::TypeArguments::nullability_offset()));
   __ and_(R4, R4, Operand(R0));
   __ cmp(R4, Operand(R0));
   __ b(&cache_lookup, NE);
-  __ mov(kResultTypeArgumentsReg, Operand(kInstantiatorTypeArgumentsReg));
+  __ mov(InstantiationABI::kResultTypeArgumentsReg,
+         Operand(InstantiationABI::kInstantiatorTypeArgumentsReg));
   __ Ret();
 
   __ Bind(&cache_lookup);
@@ -3641,16 +3640,17 @@
   // Return the function type arguments if its nullability is compatible for
   // sharing, otherwise proceed to instantiation cache lookup.
   compiler::Label cache_lookup;
-  __ ldr(R0,
-         compiler::FieldAddress(kUninstantiatedTypeArgumentsReg,
-                                target::TypeArguments::nullability_offset()));
+  __ ldr(R0, compiler::FieldAddress(
+                 InstantiationABI::kUninstantiatedTypeArgumentsReg,
+                 target::TypeArguments::nullability_offset()));
   __ ldr(R4,
-         compiler::FieldAddress(kFunctionTypeArgumentsReg,
+         compiler::FieldAddress(InstantiationABI::kFunctionTypeArgumentsReg,
                                 target::TypeArguments::nullability_offset()));
   __ and_(R4, R4, Operand(R0));
   __ cmp(R4, Operand(R0));
   __ b(&cache_lookup, NE);
-  __ mov(kResultTypeArgumentsReg, Operand(kFunctionTypeArgumentsReg));
+  __ mov(InstantiationABI::kResultTypeArgumentsReg,
+         Operand(InstantiationABI::kFunctionTypeArgumentsReg));
   __ Ret();
 
   __ Bind(&cache_lookup);
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 2a12a90..a477f9e 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -3081,10 +3081,8 @@
     Assembler* assembler) {
   Label done;
 
-  const Register kInstanceReg = R0;
-
   // Fast case for 'null'.
-  __ CompareObject(kInstanceReg, NullObject());
+  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
   __ BranchIf(EQUAL, &done);
 
   // Tail call the [SubtypeTestCache]-based implementation.
@@ -3138,10 +3136,9 @@
 // Used instead of LazySpecializeTypeTestStub when null is assignable.
 void StubCodeCompiler::GenerateLazySpecializeNullableTypeTestStub(
     Assembler* assembler) {
-  const Register kInstanceReg = R0;
   Label done;
 
-  __ CompareObject(kInstanceReg, NullObject());
+  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
   __ BranchIf(EQUAL, &done);
 
   __ ldr(CODE_REG,
@@ -3157,57 +3154,60 @@
 void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
   Label done, call_runtime;
 
-  const Register kInstanceReg = R0;
-  const Register kSubtypeTestCacheReg = R3;
-  const Register kDstTypeReg = R8;
-
   __ EnterStubFrame();
 
   // If the subtype-cache is null, it needs to be lazily-created by the runtime.
-  __ CompareObject(kSubtypeTestCacheReg, NullObject());
+  __ CompareObject(TypeTestABI::kSubtypeTestCacheReg, NullObject());
   __ BranchIf(EQUAL, &call_runtime);
 
   const Register kTmp = R9;
 
   // If this is not a [Type] object, we'll go to the runtime.
   Label is_simple_case, is_complex_case;
-  __ LoadClassId(kTmp, kDstTypeReg);
+  __ LoadClassId(kTmp, TypeTestABI::kDstTypeReg);
   __ cmp(kTmp, Operand(kTypeCid));
   __ BranchIf(NOT_EQUAL, &is_complex_case);
 
   // Check whether this [Type] is instantiated/uninstantiated.
-  __ ldr(kTmp, FieldAddress(kDstTypeReg, target::Type::type_state_offset()),
-         kByte);
+  __ ldr(
+      kTmp,
+      FieldAddress(TypeTestABI::kDstTypeReg, target::Type::type_state_offset()),
+      kByte);
   __ cmp(kTmp,
          Operand(target::RawAbstractType::kTypeStateFinalizedInstantiated));
   __ BranchIf(NOT_EQUAL, &is_complex_case);
 
   // Check whether this [Type] is a function type.
-  __ ldr(kTmp, FieldAddress(kDstTypeReg, target::Type::signature_offset()));
+  __ ldr(kTmp, FieldAddress(TypeTestABI::kDstTypeReg,
+                            target::Type::signature_offset()));
   __ CompareObject(kTmp, NullObject());
   __ BranchIf(NOT_EQUAL, &is_complex_case);
 
   // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
-  __ BranchIfSmi(kInstanceReg, &is_complex_case);
+  __ BranchIfSmi(TypeTestABI::kInstanceReg, &is_complex_case);
 
   // Fall through to &is_simple_case
 
   __ Bind(&is_simple_case);
   {
-    __ PushPair(kFunctionTypeArgumentsReg, kSubtypeTestCacheReg);
+    __ PushPair(TypeTestABI::kFunctionTypeArgumentsReg,
+                TypeTestABI::kSubtypeTestCacheReg);
     __ BranchLink(StubCodeSubtype2TestCache());
     __ CompareObject(R1, CastHandle<Object>(TrueObject()));
-    __ PopPair(kFunctionTypeArgumentsReg, kSubtypeTestCacheReg);
+    __ PopPair(TypeTestABI::kFunctionTypeArgumentsReg,
+               TypeTestABI::kSubtypeTestCacheReg);
     __ BranchIf(EQUAL, &done);  // Cache said: yes.
     __ Jump(&call_runtime);
   }
 
   __ Bind(&is_complex_case);
   {
-    __ PushPair(kFunctionTypeArgumentsReg, kSubtypeTestCacheReg);
+    __ PushPair(TypeTestABI::kFunctionTypeArgumentsReg,
+                TypeTestABI::kSubtypeTestCacheReg);
     __ BranchLink(StubCodeSubtype6TestCache());
     __ CompareObject(R1, CastHandle<Object>(TrueObject()));
-    __ PopPair(kFunctionTypeArgumentsReg, kSubtypeTestCacheReg);
+    __ PopPair(TypeTestABI::kFunctionTypeArgumentsReg,
+               TypeTestABI::kSubtypeTestCacheReg);
     __ BranchIf(EQUAL, &done);  // Cache said: yes.
     // Fall through to runtime_call
   }
@@ -3685,7 +3685,7 @@
 void StubCodeCompiler::GenerateInstantiateTypeArgumentsStub(
     Assembler* assembler) {
   // Lookup cache before calling runtime.
-  __ LoadFieldFromOffset(R0, kUninstantiatedTypeArgumentsReg,
+  __ LoadFieldFromOffset(R0, InstantiationABI::kUninstantiatedTypeArgumentsReg,
                          target::TypeArguments::instantiations_offset());
   __ AddImmediate(R0, Array::data_offset() - kHeapObjectTag);
   // The instantiations cache is initialized with Object::zero_array() and is
@@ -3695,12 +3695,12 @@
   __ LoadFromOffset(R5, R0,
                     TypeArguments::Instantiation::kInstantiatorTypeArgsIndex *
                         target::kWordSize);
-  __ CompareRegisters(R5, kInstantiatorTypeArgumentsReg);
+  __ CompareRegisters(R5, InstantiationABI::kInstantiatorTypeArgumentsReg);
   __ b(&next, NE);
   __ LoadFromOffset(
       R4, R0,
       TypeArguments::Instantiation::kFunctionTypeArgsIndex * target::kWordSize);
-  __ CompareRegisters(R4, kFunctionTypeArgumentsReg);
+  __ CompareRegisters(R4, InstantiationABI::kFunctionTypeArgumentsReg);
   __ b(&found, EQ);
   __ Bind(&next);
   __ AddImmediate(
@@ -3711,16 +3711,17 @@
   // Instantiate non-null type arguments.
   // A runtime call to instantiate the type arguments is required.
   __ EnterStubFrame();
-  __ PushPair(kUninstantiatedTypeArgumentsReg, NULL_REG);
-  __ PushPair(kFunctionTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
+  __ PushPair(InstantiationABI::kUninstantiatedTypeArgumentsReg, NULL_REG);
+  __ PushPair(InstantiationABI::kFunctionTypeArgumentsReg,
+              InstantiationABI::kInstantiatorTypeArgumentsReg);
   __ CallRuntime(kInstantiateTypeArgumentsRuntimeEntry, 3);
   __ Drop(3);  // Drop 2 type vectors, and uninstantiated type.
-  __ Pop(kResultTypeArgumentsReg);  // Pop instantiated type arguments.
+  __ Pop(InstantiationABI::kResultTypeArgumentsReg);
   __ LeaveStubFrame();
   __ Ret();
 
   __ Bind(&found);
-  __ LoadFromOffset(kResultTypeArgumentsReg, R0,
+  __ LoadFromOffset(InstantiationABI::kResultTypeArgumentsReg, R0,
                     TypeArguments::Instantiation::kInstantiatedTypeArgsIndex *
                         target::kWordSize);
   __ Ret();
@@ -3732,14 +3733,15 @@
   // Return the instantiator type arguments if its nullability is compatible for
   // sharing, otherwise proceed to instantiation cache lookup.
   compiler::Label cache_lookup;
-  __ LoadFieldFromOffset(R0, kUninstantiatedTypeArgumentsReg,
+  __ LoadFieldFromOffset(R0, InstantiationABI::kUninstantiatedTypeArgumentsReg,
                          target::TypeArguments::nullability_offset());
-  __ LoadFieldFromOffset(R4, kInstantiatorTypeArgumentsReg,
+  __ LoadFieldFromOffset(R4, InstantiationABI::kInstantiatorTypeArgumentsReg,
                          target::TypeArguments::nullability_offset());
   __ and_(R4, R4, Operand(R0));
   __ cmp(R4, Operand(R0));
   __ b(&cache_lookup, NE);
-  __ mov(kResultTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
+  __ mov(InstantiationABI::kResultTypeArgumentsReg,
+         InstantiationABI::kInstantiatorTypeArgumentsReg);
   __ Ret();
 
   __ Bind(&cache_lookup);
@@ -3751,14 +3753,15 @@
   // Return the function type arguments if its nullability is compatible for
   // sharing, otherwise proceed to instantiation cache lookup.
   compiler::Label cache_lookup;
-  __ LoadFieldFromOffset(R0, kUninstantiatedTypeArgumentsReg,
+  __ LoadFieldFromOffset(R0, InstantiationABI::kUninstantiatedTypeArgumentsReg,
                          target::TypeArguments::nullability_offset());
-  __ LoadFieldFromOffset(R4, kFunctionTypeArgumentsReg,
+  __ LoadFieldFromOffset(R4, InstantiationABI::kFunctionTypeArgumentsReg,
                          target::TypeArguments::nullability_offset());
   __ and_(R4, R4, Operand(R0));
   __ cmp(R4, Operand(R0));
   __ b(&cache_lookup, NE);
-  __ mov(kResultTypeArgumentsReg, kFunctionTypeArgumentsReg);
+  __ mov(InstantiationABI::kResultTypeArgumentsReg,
+         InstantiationABI::kFunctionTypeArgumentsReg);
   __ Ret();
 
   __ Bind(&cache_lookup);
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index c132c5e..328a17a 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -2385,14 +2385,12 @@
   static intptr_t kInstanceOffsetInBytes = 3 * target::kWordSize;
   static intptr_t kCacheOffsetInBytes = 4 * target::kWordSize;
 
-  const Register kInstanceReg = EAX;
-
   const Register kInstanceCidOrFunction = ECX;
   const Register kInstanceInstantiatorTypeArgumentsReg = EBX;
 
   const auto& raw_null = Immediate(target::ToRawPointer(NullObject()));
 
-  __ movl(kInstanceReg, Address(ESP, kInstanceOffsetInBytes));
+  __ movl(TypeTestABI::kInstanceReg, Address(ESP, kInstanceOffsetInBytes));
 
   // Loop initialization (moved up here to avoid having all dependent loads
   // after each other)
@@ -2402,9 +2400,9 @@
 
   Label loop, not_closure;
   if (n >= 4) {
-    __ LoadClassIdMayBeSmi(kInstanceCidOrFunction, kInstanceReg);
+    __ LoadClassIdMayBeSmi(kInstanceCidOrFunction, TypeTestABI::kInstanceReg);
   } else {
-    __ LoadClassId(kInstanceCidOrFunction, kInstanceReg);
+    __ LoadClassId(kInstanceCidOrFunction, TypeTestABI::kInstanceReg);
   }
   __ cmpl(kInstanceCidOrFunction, Immediate(kClosureCid));
   __ j(NOT_EQUAL, &not_closure, Assembler::kNearJump);
@@ -2412,17 +2410,20 @@
   // Closure handling.
   {
     __ movl(kInstanceCidOrFunction,
-            FieldAddress(kInstanceReg, target::Closure::function_offset()));
+            FieldAddress(TypeTestABI::kInstanceReg,
+                         target::Closure::function_offset()));
     if (n >= 2) {
       __ movl(
           kInstanceInstantiatorTypeArgumentsReg,
-          FieldAddress(kInstanceReg,
+          FieldAddress(TypeTestABI::kInstanceReg,
                        target::Closure::instantiator_type_arguments_offset()));
       if (n >= 6) {
-        __ pushl(FieldAddress(
-            kInstanceReg, target::Closure::delayed_type_arguments_offset()));
-        __ pushl(FieldAddress(
-            kInstanceReg, target::Closure::function_type_arguments_offset()));
+        __ pushl(
+            FieldAddress(TypeTestABI::kInstanceReg,
+                         target::Closure::delayed_type_arguments_offset()));
+        __ pushl(
+            FieldAddress(TypeTestABI::kInstanceReg,
+                         target::Closure::function_type_arguments_offset()));
       }
     }
     __ jmp(&loop, Assembler::kNearJump);
@@ -2442,7 +2443,7 @@
       __ cmpl(EDI, Immediate(target::Class::kNoTypeArguments));
       __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
       __ movl(kInstanceInstantiatorTypeArgumentsReg,
-              FieldAddress(kInstanceReg, EDI, TIMES_4, 0));
+              FieldAddress(TypeTestABI::kInstanceReg, EDI, TIMES_4, 0));
       __ Bind(&has_no_type_arguments);
 
       if (n >= 6) {
@@ -2915,9 +2916,9 @@
 void StubCodeCompiler::GenerateInstantiateTypeArgumentsStub(
     Assembler* assembler) {
   // Lookup cache before calling runtime.
-  __ pushl(kUninstantiatedTypeArgumentsReg);  // Preserve reg.
+  __ pushl(InstantiationABI::kUninstantiatedTypeArgumentsReg);  // Preserve reg.
   __ movl(EAX, compiler::FieldAddress(
-                   kUninstantiatedTypeArgumentsReg,
+                   InstantiationABI::kUninstantiatedTypeArgumentsReg,
                    target::TypeArguments::instantiations_offset()));
   __ leal(EAX, compiler::FieldAddress(EAX, Array::data_offset()));
   // The instantiations cache is initialized with Object::zero_array() and is
@@ -2928,12 +2929,12 @@
           compiler::Address(
               EAX, TypeArguments::Instantiation::kInstantiatorTypeArgsIndex *
                        target::kWordSize));
-  __ cmpl(EDI, kInstantiatorTypeArgumentsReg);
+  __ cmpl(EDI, InstantiationABI::kInstantiatorTypeArgumentsReg);
   __ j(NOT_EQUAL, &next, compiler::Assembler::kNearJump);
   __ movl(EBX, compiler::Address(
                    EAX, TypeArguments::Instantiation::kFunctionTypeArgsIndex *
                             target::kWordSize));
-  __ cmpl(EBX, kFunctionTypeArgumentsReg);
+  __ cmpl(EBX, InstantiationABI::kFunctionTypeArgumentsReg);
   __ j(EQUAL, &found, compiler::Assembler::kNearJump);
   __ Bind(&next);
   __ addl(EAX, compiler::Immediate(TypeArguments::Instantiation::kSizeInWords *
@@ -2944,21 +2945,21 @@
 
   // Instantiate non-null type arguments.
   // A runtime call to instantiate the type arguments is required.
-  __ popl(kUninstantiatedTypeArgumentsReg);  // Restore reg.
+  __ popl(InstantiationABI::kUninstantiatedTypeArgumentsReg);  // Restore reg.
   __ EnterStubFrame();
   __ PushObject(Object::null_object());  // Make room for the result.
-  __ pushl(kUninstantiatedTypeArgumentsReg);
-  __ pushl(kInstantiatorTypeArgumentsReg);  // Push instantiator type arguments.
-  __ pushl(kFunctionTypeArgumentsReg);      // Push function type arguments.
+  __ pushl(InstantiationABI::kUninstantiatedTypeArgumentsReg);
+  __ pushl(InstantiationABI::kInstantiatorTypeArgumentsReg);
+  __ pushl(InstantiationABI::kFunctionTypeArgumentsReg);
   __ CallRuntime(kInstantiateTypeArgumentsRuntimeEntry, 3);
   __ Drop(3);  // Drop 2 type vectors, and uninstantiated args.
-  __ popl(kResultTypeArgumentsReg);  // Pop instantiated type arguments.
+  __ popl(InstantiationABI::kResultTypeArgumentsReg);
   __ LeaveFrame();
   __ ret();
 
   __ Bind(&found);
-  __ popl(kUninstantiatedTypeArgumentsReg);  // Drop reg.
-  __ movl(kResultTypeArgumentsReg,
+  __ popl(InstantiationABI::kUninstantiatedTypeArgumentsReg);  // Drop reg.
+  __ movl(InstantiationABI::kResultTypeArgumentsReg,
           compiler::Address(
               EAX, TypeArguments::Instantiation::kInstantiatedTypeArgsIndex *
                        target::kWordSize));
@@ -2971,16 +2972,17 @@
   // Return the instantiator type arguments if its nullability is compatible for
   // sharing, otherwise proceed to instantiation cache lookup.
   compiler::Label cache_lookup;
-  __ movl(EAX,
-          compiler::FieldAddress(kUninstantiatedTypeArgumentsReg,
-                                 target::TypeArguments::nullability_offset()));
-  __ movl(EDI,
-          compiler::FieldAddress(kInstantiatorTypeArgumentsReg,
-                                 target::TypeArguments::nullability_offset()));
+  __ movl(EAX, compiler::FieldAddress(
+                   InstantiationABI::kUninstantiatedTypeArgumentsReg,
+                   target::TypeArguments::nullability_offset()));
+  __ movl(EDI, compiler::FieldAddress(
+                   InstantiationABI::kInstantiatorTypeArgumentsReg,
+                   target::TypeArguments::nullability_offset()));
   __ andl(EDI, EAX);
   __ cmpl(EDI, EAX);
   __ j(NOT_EQUAL, &cache_lookup, compiler::Assembler::kNearJump);
-  __ movl(kResultTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
+  __ movl(InstantiationABI::kResultTypeArgumentsReg,
+          InstantiationABI::kInstantiatorTypeArgumentsReg);
   __ ret();
 
   __ Bind(&cache_lookup);
@@ -2992,16 +2994,17 @@
   // Return the function type arguments if its nullability is compatible for
   // sharing, otherwise proceed to instantiation cache lookup.
   compiler::Label cache_lookup;
-  __ movl(EAX,
-          compiler::FieldAddress(kUninstantiatedTypeArgumentsReg,
-                                 target::TypeArguments::nullability_offset()));
+  __ movl(EAX, compiler::FieldAddress(
+                   InstantiationABI::kUninstantiatedTypeArgumentsReg,
+                   target::TypeArguments::nullability_offset()));
   __ movl(EDI,
-          compiler::FieldAddress(kFunctionTypeArgumentsReg,
+          compiler::FieldAddress(InstantiationABI::kFunctionTypeArgumentsReg,
                                  target::TypeArguments::nullability_offset()));
   __ andl(EDI, EAX);
   __ cmpl(EDI, EAX);
   __ j(NOT_EQUAL, &cache_lookup, compiler::Assembler::kNearJump);
-  __ movl(kResultTypeArgumentsReg, kFunctionTypeArgumentsReg);
+  __ movl(InstantiationABI::kResultTypeArgumentsReg,
+          InstantiationABI::kFunctionTypeArgumentsReg);
   __ ret();
 
   __ Bind(&cache_lookup);
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 9e91624..8bcf076 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -3030,10 +3030,8 @@
     Assembler* assembler) {
   Label done;
 
-  const Register kInstanceReg = RAX;
-
   // Fast case for 'null'.
-  __ CompareObject(kInstanceReg, NullObject());
+  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
   __ BranchIf(EQUAL, &done);
 
   __ movq(CODE_REG, Address(THR, target::Thread::slow_type_test_stub_offset()));
@@ -3086,12 +3084,10 @@
 // Used instead of LazySpecializeTypeTestStub when null is assignable.
 void StubCodeCompiler::GenerateLazySpecializeNullableTypeTestStub(
     Assembler* assembler) {
-  const Register kInstanceReg = RAX;
-
   Label done;
 
   // Fast case for 'null'.
-  __ CompareObject(kInstanceReg, NullObject());
+  __ CompareObject(TypeTestABI::kInstanceReg, NullObject());
   __ BranchIf(EQUAL, &done);
 
   __ movq(
@@ -3108,36 +3104,34 @@
 void StubCodeCompiler::GenerateSlowTypeTestStub(Assembler* assembler) {
   Label done, call_runtime;
 
-  const Register kInstanceReg = RAX;
-  const Register kDstTypeReg = RBX;
-  const Register kSubtypeTestCacheReg = R9;
-
   __ EnterStubFrame();
 
   // If the subtype-cache is null, it needs to be lazily-created by the runtime.
-  __ CompareObject(kSubtypeTestCacheReg, NullObject());
+  __ CompareObject(TypeTestABI::kSubtypeTestCacheReg, NullObject());
   __ BranchIf(EQUAL, &call_runtime);
 
   const Register kTmp = RDI;
 
   // If this is not a [Type] object, we'll go to the runtime.
   Label is_simple_case, is_complex_case;
-  __ LoadClassId(kTmp, kDstTypeReg);
+  __ LoadClassId(kTmp, TypeTestABI::kDstTypeReg);
   __ cmpq(kTmp, Immediate(kTypeCid));
   __ BranchIf(NOT_EQUAL, &is_complex_case);
 
   // Check whether this [Type] is instantiated/uninstantiated.
-  __ cmpb(FieldAddress(kDstTypeReg, target::Type::type_state_offset()),
-          Immediate(target::RawAbstractType::kTypeStateFinalizedInstantiated));
+  __ cmpb(
+      FieldAddress(TypeTestABI::kDstTypeReg, target::Type::type_state_offset()),
+      Immediate(target::RawAbstractType::kTypeStateFinalizedInstantiated));
   __ BranchIf(NOT_EQUAL, &is_complex_case);
 
   // Check whether this [Type] is a function type.
-  __ movq(kTmp, FieldAddress(kDstTypeReg, target::Type::signature_offset()));
+  __ movq(kTmp, FieldAddress(TypeTestABI::kDstTypeReg,
+                             target::Type::signature_offset()));
   __ CompareObject(kTmp, NullObject());
   __ BranchIf(NOT_EQUAL, &is_complex_case);
 
   // This [Type] could be a FutureOr. Subtype2TestCache does not support Smi.
-  __ BranchIfSmi(kInstanceReg, &is_complex_case);
+  __ BranchIfSmi(TypeTestABI::kInstanceReg, &is_complex_case);
 
   // Fall through to &is_simple_case
 
@@ -3622,7 +3616,7 @@
     Assembler* assembler) {
   // Lookup cache before calling runtime.
   __ movq(RAX, compiler::FieldAddress(
-                   kUninstantiatedTypeArgumentsReg,
+                   InstantiationABI::kUninstantiatedTypeArgumentsReg,
                    target::TypeArguments::instantiations_offset()));
   __ leaq(RAX, compiler::FieldAddress(RAX, Array::data_offset()));
   // The instantiations cache is initialized with Object::zero_array() and is
@@ -3633,12 +3627,12 @@
           compiler::Address(
               RAX, TypeArguments::Instantiation::kInstantiatorTypeArgsIndex *
                        target::kWordSize));
-  __ cmpq(RDI, kInstantiatorTypeArgumentsReg);
+  __ cmpq(RDI, InstantiationABI::kInstantiatorTypeArgumentsReg);
   __ j(NOT_EQUAL, &next, compiler::Assembler::kNearJump);
   __ movq(R10, compiler::Address(
                    RAX, TypeArguments::Instantiation::kFunctionTypeArgsIndex *
                             target::kWordSize));
-  __ cmpq(R10, kFunctionTypeArgumentsReg);
+  __ cmpq(R10, InstantiationABI::kFunctionTypeArgumentsReg);
   __ j(EQUAL, &found, compiler::Assembler::kNearJump);
   __ Bind(&next);
   __ addq(RAX, compiler::Immediate(TypeArguments::Instantiation::kSizeInWords *
@@ -3651,17 +3645,17 @@
   // A runtime call to instantiate the type arguments is required.
   __ EnterStubFrame();
   __ PushObject(Object::null_object());  // Make room for the result.
-  __ pushq(kUninstantiatedTypeArgumentsReg);
-  __ pushq(kInstantiatorTypeArgumentsReg);  // Push instantiator type arguments.
-  __ pushq(kFunctionTypeArgumentsReg);      // Push function type arguments.
+  __ pushq(InstantiationABI::kUninstantiatedTypeArgumentsReg);
+  __ pushq(InstantiationABI::kInstantiatorTypeArgumentsReg);
+  __ pushq(InstantiationABI::kFunctionTypeArgumentsReg);
   __ CallRuntime(kInstantiateTypeArgumentsRuntimeEntry, 3);
   __ Drop(3);  // Drop 2 type vectors, and uninstantiated type.
-  __ popq(kResultTypeArgumentsReg);  // Pop instantiated type arguments.
+  __ popq(InstantiationABI::kResultTypeArgumentsReg);
   __ LeaveStubFrame();
   __ ret();
 
   __ Bind(&found);
-  __ movq(kResultTypeArgumentsReg,
+  __ movq(InstantiationABI::kResultTypeArgumentsReg,
           compiler::Address(
               RAX, TypeArguments::Instantiation::kInstantiatedTypeArgsIndex *
                        target::kWordSize));
@@ -3674,16 +3668,17 @@
   // Return the instantiator type arguments if its nullability is compatible for
   // sharing, otherwise proceed to instantiation cache lookup.
   compiler::Label cache_lookup;
-  __ movq(RAX,
-          compiler::FieldAddress(kUninstantiatedTypeArgumentsReg,
-                                 target::TypeArguments::nullability_offset()));
-  __ movq(RDI,
-          compiler::FieldAddress(kInstantiatorTypeArgumentsReg,
-                                 target::TypeArguments::nullability_offset()));
+  __ movq(RAX, compiler::FieldAddress(
+                   InstantiationABI::kUninstantiatedTypeArgumentsReg,
+                   target::TypeArguments::nullability_offset()));
+  __ movq(RDI, compiler::FieldAddress(
+                   InstantiationABI::kInstantiatorTypeArgumentsReg,
+                   target::TypeArguments::nullability_offset()));
   __ andq(RDI, RAX);
   __ cmpq(RDI, RAX);
   __ j(NOT_EQUAL, &cache_lookup, compiler::Assembler::kNearJump);
-  __ movq(kResultTypeArgumentsReg, kInstantiatorTypeArgumentsReg);
+  __ movq(InstantiationABI::kResultTypeArgumentsReg,
+          InstantiationABI::kInstantiatorTypeArgumentsReg);
   __ ret();
 
   __ Bind(&cache_lookup);
@@ -3695,16 +3690,17 @@
   // Return the function type arguments if its nullability is compatible for
   // sharing, otherwise proceed to instantiation cache lookup.
   compiler::Label cache_lookup;
-  __ movq(RAX,
-          compiler::FieldAddress(kUninstantiatedTypeArgumentsReg,
-                                 target::TypeArguments::nullability_offset()));
+  __ movq(RAX, compiler::FieldAddress(
+                   InstantiationABI::kUninstantiatedTypeArgumentsReg,
+                   target::TypeArguments::nullability_offset()));
   __ movq(RDI,
-          compiler::FieldAddress(kFunctionTypeArgumentsReg,
+          compiler::FieldAddress(InstantiationABI::kFunctionTypeArgumentsReg,
                                  target::TypeArguments::nullability_offset()));
   __ andq(RDI, RAX);
   __ cmpq(RDI, RAX);
   __ j(NOT_EQUAL, &cache_lookup, compiler::Assembler::kNearJump);
-  __ movq(kResultTypeArgumentsReg, kFunctionTypeArgumentsReg);
+  __ movq(InstantiationABI::kResultTypeArgumentsReg,
+          InstantiationABI::kFunctionTypeArgumentsReg);
   __ ret();
 
   __ Bind(&cache_lookup);
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 7967439..714db54 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -311,10 +311,13 @@
 const Register kAllocationStubTypeArgumentsReg = R3;
 
 // ABI for instantiation stubs.
-const Register kUninstantiatedTypeArgumentsReg = R3;
-const Register kInstantiatorTypeArgumentsReg = R2;
-const Register kFunctionTypeArgumentsReg = R1;
-const Register kResultTypeArgumentsReg = R0;
+struct InstantiationABI {
+  static const Register kUninstantiatedTypeArgumentsReg = R3;
+  static const Register kInstantiatorTypeArgumentsReg = R2;
+  static const Register kFunctionTypeArgumentsReg = R1;
+  static const Register kResultTypeArgumentsReg = R0;
+  static const Register kResultTypeReg = R0;
+};
 
 // Calling convention when calling TypeTestingStub and SubtypeTestCacheStub.
 struct TypeTestABI {
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 743d7ee..775e670 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -143,10 +143,13 @@
 const Register kAllocationStubTypeArgumentsReg = R1;
 
 // ABI for instantiation stubs.
-const Register kUninstantiatedTypeArgumentsReg = R3;
-const Register kInstantiatorTypeArgumentsReg = R2;
-const Register kFunctionTypeArgumentsReg = R1;
-const Register kResultTypeArgumentsReg = R0;
+struct InstantiationABI {
+  static const Register kUninstantiatedTypeArgumentsReg = R3;
+  static const Register kInstantiatorTypeArgumentsReg = R2;
+  static const Register kFunctionTypeArgumentsReg = R1;
+  static const Register kResultTypeArgumentsReg = R0;
+  static const Register kResultTypeReg = R0;
+};
 
 // Calling convention when calling TypeTestingStub and SubtypeTestCacheStub.
 struct TypeTestABI {
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index 29dc2b5..44b45b6 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -92,13 +92,24 @@
 const Register kAllocationStubTypeArgumentsReg = EDX;
 
 // ABI for instantiation stubs.
-const Register kUninstantiatedTypeArgumentsReg = EBX;
-const Register kInstantiatorTypeArgumentsReg = EDX;
-const Register kFunctionTypeArgumentsReg = ECX;
-const Register kResultTypeArgumentsReg = EAX;
+struct InstantiationABI {
+  static const Register kUninstantiatedTypeArgumentsReg = EBX;
+  static const Register kInstantiatorTypeArgumentsReg = EDX;
+  static const Register kFunctionTypeArgumentsReg = ECX;
+  static const Register kResultTypeArgumentsReg = EAX;
+  static const Register kResultTypeReg = EAX;
+};
 
-// TODO(regis): Add ABIs for type testing stubs and is-type test stubs instead
-// of reusing the constants of the instantiation stubs ABI.
+// Calling convention when calling SubtypeTestCacheStub.
+// Although ia32 uses a stack-based calling convention, we keep the same
+// 'TypeTestABI' name for symmetry with other architectures with a proper ABI.
+// Note that ia32 has no support for type testing stubs.
+struct TypeTestABI {
+  static const Register kInstanceReg = EAX;
+  static const Register kDstTypeReg = EBX;
+  static const Register kInstantiatorTypeArgumentsReg = EDX;
+  static const Register kFunctionTypeArgumentsReg = ECX;
+};
 
 typedef uint32_t RegList;
 const RegList kAllCpuRegistersList = 0xFF;
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index fe9d561..2073583 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -133,10 +133,13 @@
 const Register kAllocationStubTypeArgumentsReg = RDX;
 
 // ABI for instantiation stubs.
-const Register kUninstantiatedTypeArgumentsReg = RBX;
-const Register kInstantiatorTypeArgumentsReg = RDX;
-const Register kFunctionTypeArgumentsReg = RCX;
-const Register kResultTypeArgumentsReg = RAX;
+struct InstantiationABI {
+  static const Register kUninstantiatedTypeArgumentsReg = RBX;
+  static const Register kInstantiatorTypeArgumentsReg = RDX;
+  static const Register kFunctionTypeArgumentsReg = RCX;
+  static const Register kResultTypeArgumentsReg = RAX;
+  static const Register kResultTypeReg = RAX;
+};
 
 // Calling convention when calling TypeTestingStub and SubtypeTestCacheStub.
 struct TypeTestABI {
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 833f9c8..468a3b1 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -160,7 +160,8 @@
     const Instance& instance = Instance::Cast(obj);
     const Class& obj_class = Class::Handle(zone, obj.clazz());
     if (Class::IsSubtypeOf(obj_class, Object::null_type_arguments(),
-                           list_rare_type, Heap::kNew)) {
+                           Nullability::kNonNullable, list_rare_type,
+                           Heap::kNew)) {
       return instance.raw();
     }
   }
@@ -183,7 +184,8 @@
     const Instance& instance = Instance::Cast(obj);
     const Class& obj_class = Class::Handle(zone, obj.clazz());
     if (Class::IsSubtypeOf(obj_class, Object::null_type_arguments(),
-                           map_rare_type, Heap::kNew)) {
+                           Nullability::kNonNullable, map_rare_type,
+                           Heap::kNew)) {
       return instance.raw();
     }
   }
@@ -2389,7 +2391,8 @@
     }
     const Class& obj_class = Class::Handle(Z, obj.clazz());
     bool is_future = Class::IsSubtypeOf(
-        obj_class, Object::null_type_arguments(), future_rare_type, Heap::kNew);
+        obj_class, Object::null_type_arguments(), Nullability::kNonNullable,
+        future_rare_type, Heap::kNew);
     return is_future;
   }
   return false;
@@ -6378,6 +6381,7 @@
     return result;
   }
   CHECK_CALLBACK_STATE(T);
+  CompilerState state(Thread::Current(), /*is_aot=*/true);
   CHECK_ERROR_HANDLE(Precompiler::CompileAll());
   return Api::Success();
 #endif
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index bf0ad70..d9d98f0 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1505,21 +1505,6 @@
     return nullptr;
   }
 
-  // Now we register the isolate in the group. From this point on any GC would
-  // traverse the isolate roots (before this point, the roots are only pointing
-  // to vm-isolate objects, e.g. null)
-  isolate_group->RegisterIsolate(result);
-
-  if (ServiceIsolate::NameEquals(name_prefix)) {
-    ASSERT(!ServiceIsolate::Exists());
-    ServiceIsolate::SetServiceIsolate(result);
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  } else if (KernelIsolate::NameEquals(name_prefix)) {
-    ASSERT(!KernelIsolate::Exists());
-    KernelIsolate::SetKernelIsolate(result);
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-  }
-
   // Setup the isolate message handler.
   MessageHandler* handler = new IsolateMessageHandler(result);
   ASSERT(handler != nullptr);
@@ -1535,6 +1520,21 @@
   result->set_pause_capability(result->random()->NextUInt64());
   result->set_terminate_capability(result->random()->NextUInt64());
 
+  // Now we register the isolate in the group. From this point on any GC would
+  // traverse the isolate roots (before this point, the roots are only pointing
+  // to vm-isolate objects, e.g. null)
+  isolate_group->RegisterIsolate(result);
+
+  if (ServiceIsolate::NameEquals(name_prefix)) {
+    ASSERT(!ServiceIsolate::Exists());
+    ServiceIsolate::SetServiceIsolate(result);
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  } else if (KernelIsolate::NameEquals(name_prefix)) {
+    ASSERT(!KernelIsolate::Exists());
+    KernelIsolate::SetKernelIsolate(result);
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+  }
+
 #if !defined(PRODUCT)
   result->debugger_ = new Debugger(result);
 #endif
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index fd193c8..98e5421 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1221,7 +1221,9 @@
     // Only instance fields could be covariant.
     ASSERT(!field_helper.IsCovariant() &&
            !field_helper.IsGenericCovariantImpl());
-    const bool is_late = field_helper.IsLate();
+    // In NNBD libraries, static fields act like late fields
+    // regardless of whether they're marked late.
+    const bool is_late = field_helper.IsLate() || library.is_nnbd();
     const bool is_extension_member = field_helper.IsExtensionMember();
     const Field& field = Field::Handle(
         Z, Field::NewTopLevel(name, is_final, field_helper.IsConst(), is_late,
@@ -1577,7 +1579,10 @@
       // In the VM all const fields are implicitly final whereas in Kernel they
       // are not final because they are not explicitly declared that way.
       const bool is_final = field_helper.IsConst() || field_helper.IsFinal();
-      const bool is_late = field_helper.IsLate();
+      // In NNBD libraries, static fields act like late fields
+      // regardless of whether they're marked late.
+      const bool is_late = field_helper.IsLate() ||
+                           (field_helper.IsStatic() && library.is_nnbd());
       const bool is_extension_member = field_helper.IsExtensionMember();
       Field& field = Field::Handle(
           Z, Field::New(name, field_helper.IsStatic(), is_final,
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index b841c86..d2044b8 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -18,6 +18,7 @@
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler.h"
 #include "vm/compiler/assembler/disassembler_kbc.h"
+#include "vm/compiler/compiler_state.h"
 #include "vm/compiler/frontend/bytecode_fingerprints.h"
 #include "vm/compiler/frontend/bytecode_reader.h"
 #include "vm/compiler/frontend/kernel_fingerprints.h"
@@ -4852,13 +4853,13 @@
          (library() == Library::AsyncLibrary());
 }
 
-// Checks if type T0 is a subtype of type T1, assuming that T0 is non-nullable.
-// Type T0 is specified by class 'cls' parameterized with 'type_arguments', and
-// type T1 is specified by 'other' and must have a type class.
-// This class and class 'other' do not need to be finalized, however, they must
-// be resolved as well as their interfaces.
+// Checks if type T0 is a subtype of type T1.
+// Type T0 is specified by class 'cls' parameterized with 'type_arguments' and
+// by 'nullability', and type T1 is specified by 'other' and must have a type
+// class.
 bool Class::IsSubtypeOf(const Class& cls,
                         const TypeArguments& type_arguments,
+                        Nullability nullability,
                         const AbstractType& other,
                         Heap::Space space) {
   // This function does not support Null, Never, dynamic, or void as type T0.
@@ -4868,13 +4869,21 @@
   // Type T1 must have a type class (e.g. not a type parameter).
   ASSERT(other.HasTypeClass());
   const classid_t other_cid = other.type_class_id();
-  // Since T0 is assumed non-nullable, the nullability of T1 is irrelevant.
-  if (other_cid == kDynamicCid || other_cid == kVoidCid ||
-      other_cid == kObjectCid) {
+  if (other_cid == kDynamicCid || other_cid == kVoidCid) {
     return true;
   }
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
+  // Nullability of left and right hand sides is verified in strong mode only.
+  const bool verified_nullability = !isolate->null_safety() ||
+                                    nullability != Nullability::kNullable ||
+                                    !other.IsNonNullable();
+
+  // Right Object.
+  if (other_cid == kObjectCid) {
+    return verified_nullability;
+  }
   const Class& other_class = Class::Handle(zone, other.type_class());
   const TypeArguments& other_type_arguments =
       TypeArguments::Handle(zone, other.arguments());
@@ -4895,12 +4904,13 @@
       ASSERT(!future_class.IsNull() && future_class.NumTypeParameters() == 1 &&
              this_class.NumTypeParameters() == 1);
       ASSERT(type_arguments.IsNull() || type_arguments.Length() >= 1);
-      if (Class::IsSubtypeOf(future_class, type_arguments, other, space)) {
+      if (Class::IsSubtypeOf(future_class, type_arguments,
+                             Nullability::kNonNullable, other, space)) {
         // Check S0 <: T1.
         const AbstractType& type_arg =
             AbstractType::Handle(zone, type_arguments.TypeAtNullSafe(0));
         if (type_arg.IsSubtypeOf(other, space)) {
-          return true;
+          return verified_nullability;
         }
       }
     }
@@ -4924,18 +4934,27 @@
             AbstractType::Handle(zone, type_arguments.TypeAtNullSafe(0));
         // If T0 is Future<S0>, then T0 <: Future<S1>, iff S0 <: S1.
         if (type_arg.IsSubtypeOf(other_type_arg, space)) {
-          return true;
+          if (verified_nullability) {
+            return true;
+          }
         }
       }
       // Check T0 <: Future<S1> when T0 is FutureOr<S0> is already done.
       // Check T0 <: S1.
       if (other_type_arg.HasTypeClass() &&
-          Class::IsSubtypeOf(this_class, type_arguments, other_type_arg,
-                             space)) {
+          Class::IsSubtypeOf(this_class, type_arguments, nullability,
+                             other_type_arg, space)) {
         return true;
       }
     }
 
+    // Left nullable:
+    //   if T0 is S0? then:
+    //     T0 <: T1 iff S0 <: T1 and Null <: T1
+    if (!verified_nullability) {
+      return false;
+    }
+
     // Check for reflexivity.
     if (this_class.raw() == other_class.raw()) {
       const intptr_t num_type_params = this_class.NumTypeParameters();
@@ -4990,7 +5009,8 @@
       if (interface_class.IsDartFunctionClass()) {
         continue;
       }
-      if (Class::IsSubtypeOf(interface_class, interface_args, other, space)) {
+      if (Class::IsSubtypeOf(interface_class, interface_args,
+                             Nullability::kNonNullable, other, space)) {
         return true;
       }
     }
@@ -7366,7 +7386,7 @@
   // functions cannot deoptimize to unoptimized frames we prevent them from
   // being inlined (for now).
   if (ForceOptimize()) {
-    return FLAG_precompiled_mode;
+    return CompilerState::Current().is_aot();
   }
 #if defined(PRODUCT)
   return is_inlinable() && !is_external() && !is_generated_body();
@@ -7949,6 +7969,7 @@
   }
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
   // Check the result type.
   const AbstractType& other_res_type =
       AbstractType::Handle(zone, other.result_type());
@@ -7996,7 +8017,7 @@
       return false;
     }
   }
-  if (FLAG_null_safety) {
+  if (isolate->null_safety()) {
     // Check that for each required named parameter in this function, there's a
     // corresponding required named parameter in the other function.
     String& param_name = other_param_name;
@@ -8443,6 +8464,7 @@
                               ZoneTextBuffer* printer) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
   String& name = String::Handle(zone);
   const TypeArguments& type_params =
       TypeArguments::Handle(zone, type_parameters());
@@ -8458,8 +8480,9 @@
       printer->AddString(name.ToCString());
       bound = type_param.bound();
       // Do not print default bound or non-nullable Object bound in weak mode.
-      if (!bound.IsNull() && (!bound.IsObjectType() ||
-                              (FLAG_null_safety && bound.IsNonNullable()))) {
+      if (!bound.IsNull() &&
+          (!bound.IsObjectType() ||
+           (isolate->null_safety() && bound.IsNonNullable()))) {
         printer->AddString(" extends ");
         bound.PrintName(name_visibility, printer);
       }
@@ -17801,8 +17824,8 @@
   }
   // RuntimeType of non-null instance is non-nullable, so there is no need to
   // check nullability of other type.
-  return Class::IsSubtypeOf(cls, type_arguments, instantiated_other,
-                            Heap::kOld);
+  return Class::IsSubtypeOf(cls, type_arguments, Nullability::kNonNullable,
+                            instantiated_other, Heap::kOld);
 }
 
 bool Instance::IsFutureOrInstanceOf(Zone* zone,
@@ -18637,15 +18660,15 @@
   if (other.IsTypeParameter()) {
     return false;
   }
-  if (isolate->null_safety() && IsNullable() && other.IsNonNullable()) {
-    return false;
-  }
   const Class& type_cls = Class::Handle(zone, type_class());
   const Class& other_type_cls = Class::Handle(zone, other.type_class());
   // Function types cannot be handled by Class::IsSubtypeOf().
   const bool other_is_dart_function_type = other.IsDartFunctionType();
   if (other_is_dart_function_type || other.IsFunctionType()) {
     if (IsFunctionType()) {
+      if (isolate->null_safety() && IsNullable() && other.IsNonNullable()) {
+        return false;
+      }
       if (other_is_dart_function_type) {
         return true;
       }
@@ -18677,7 +18700,7 @@
     return false;
   }
   return Class::IsSubtypeOf(type_cls, TypeArguments::Handle(zone, arguments()),
-                            other, space);
+                            nullability(), other, space);
 }
 
 bool AbstractType::IsSubtypeOfFutureOr(Zone* zone,
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 1c620c9..3da041d 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -888,7 +888,7 @@
 
 // The NNBDMode reflects the opted-in status of libraries.
 // Note that the weak or strong testing mode is not reflected in NNBDMode, but
-// imposed globally by the value of FLAG_null_safety.
+// imposed globally by the value of --null-safety.
 enum class NNBDMode {
   // Status of the library:
   kLegacyLib = 0,   // Library is legacy.
@@ -1230,10 +1230,11 @@
         cls->ptr()->library_->ptr()->flags_);
   }
 
-  // Returns true if the type specified by cls and type_arguments is a subtype
-  // of the other type.
+  // Returns true if the type specified by cls, type_arguments, and nullability
+  // is a subtype of the other type.
   static bool IsSubtypeOf(const Class& cls,
                           const TypeArguments& type_arguments,
+                          Nullability nullability,
                           const AbstractType& other,
                           Heap::Space space);
 
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index b753b96..b9fbe72 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -265,4 +265,10 @@
 #endif
 }
 
+void ObjectStore::PostLoad() {
+  resume_capabilities_ = GrowableObjectArray::New();
+  exit_listeners_ = GrowableObjectArray::New();
+  error_listeners_ = GrowableObjectArray::New();
+}
+
 }  // namespace dart
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 0b95138..04e6e70 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -145,9 +145,6 @@
   RW(Array, libraries_map)                                                     \
   RW(GrowableObjectArray, closure_functions)                                   \
   RW(GrowableObjectArray, pending_classes)                                     \
-  R_(GrowableObjectArray, resume_capabilities)                                 \
-  R_(GrowableObjectArray, exit_listeners)                                      \
-  R_(GrowableObjectArray, error_listeners)                                     \
   RW(Instance, stack_overflow)                                                 \
   RW(Instance, out_of_memory)                                                  \
   RW(UnhandledException, preallocated_unhandled_exception)                     \
@@ -186,6 +183,9 @@
   RW(Code, array_write_barrier_stub)                                           \
   R_(Code, megamorphic_miss_code)                                              \
   R_(Function, megamorphic_miss_function)                                      \
+  R_(GrowableObjectArray, resume_capabilities)                                 \
+  R_(GrowableObjectArray, exit_listeners)                                      \
+  R_(GrowableObjectArray, error_listeners)                                     \
   RW(Array, dispatch_table_code_entries)                                       \
   RW(Array, code_order_table)                                                  \
   RW(Array, obfuscation_map)                                                   \
@@ -263,6 +263,8 @@
 
   void InitKnownObjects();
 
+  void PostLoad();
+
   static void Init(Isolate* isolate);
 
 #ifndef PRODUCT
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 8834c9e..eeb5264 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2309,7 +2309,7 @@
 ISOLATE_UNIT_TEST_CASE(ContextScope) {
   // We need an active compiler context to manipulate scopes, since local
   // variables and slots can be canonicalized in the compiler state.
-  CompilerState compiler_state(Thread::Current());
+  CompilerState compiler_state(Thread::Current(), /*is_aot=*/false);
 
   const intptr_t parent_scope_function_level = 0;
   LocalScope* parent_scope =
diff --git a/sdk/lib/_http/overrides.dart b/sdk/lib/_http/overrides.dart
index 4112c3c..8b63209 100644
--- a/sdk/lib/_http/overrides.dart
+++ b/sdk/lib/_http/overrides.dart
@@ -51,27 +51,20 @@
   static R runZoned<R>(R body(),
       {HttpClient Function(SecurityContext) createHttpClient,
       String Function(Uri uri, Map<String, String> environment)
-          findProxyFromEnvironment,
-      ZoneSpecification zoneSpecification,
-      Function onError}) {
+          findProxyFromEnvironment}) {
     HttpOverrides overrides =
         new _HttpOverridesScope(createHttpClient, findProxyFromEnvironment);
     return _asyncRunZoned<R>(body,
-        zoneValues: {_httpOverridesToken: overrides},
-        zoneSpecification: zoneSpecification,
-        onError: onError);
+        zoneValues: {_httpOverridesToken: overrides});
   }
 
   /// Runs [body] in a fresh [Zone] using the overrides found in [overrides].
   ///
   /// Note that [overrides] should be an instance of a class that extends
   /// [HttpOverrides].
-  static R runWithHttpOverrides<R>(R body(), HttpOverrides overrides,
-      {ZoneSpecification zoneSpecification, Function onError}) {
+  static R runWithHttpOverrides<R>(R body(), HttpOverrides overrides) {
     return _asyncRunZoned<R>(body,
-        zoneValues: {_httpOverridesToken: overrides},
-        zoneSpecification: zoneSpecification,
-        onError: onError);
+        zoneValues: {_httpOverridesToken: overrides});
   }
 
   /// Returns a new [HttpClient] using the given [context].
diff --git a/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart
index 0000252..a220dac 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart
@@ -182,7 +182,7 @@
   }
 
   @patch
-  factory int.fromEnvironment(String name, {int defaultValue}) {
+  factory int.fromEnvironment(String name, {int defaultValue = 0}) {
     // ignore: const_constructor_throws_exception
     throw UnsupportedError(
         'int.fromEnvironment can only be used as a const constructor');
@@ -556,7 +556,7 @@
   }
 
   @patch
-  factory String.fromEnvironment(String name, {String defaultValue}) {
+  factory String.fromEnvironment(String name, {String defaultValue = ""}) {
     // ignore: const_constructor_throws_exception
     throw UnsupportedError(
         'String.fromEnvironment can only be used as a const constructor');
diff --git a/sdk/lib/_internal/vm/lib/integers_patch.dart b/sdk/lib/_internal/vm/lib/integers_patch.dart
index 9a2fb54..5582dfc 100644
--- a/sdk/lib/_internal/vm/lib/integers_patch.dart
+++ b/sdk/lib/_internal/vm/lib/integers_patch.dart
@@ -10,7 +10,7 @@
 @patch
 class int {
   @patch
-  const factory int.fromEnvironment(String name, {int defaultValue})
+  const factory int.fromEnvironment(String name, {int defaultValue = 0})
       native "Integer_fromEnvironment";
 
   int _bitAndFromSmi(_Smi other);
diff --git a/sdk/lib/_internal/vm/lib/string_patch.dart b/sdk/lib/_internal/vm/lib/string_patch.dart
index 0503720..34c5bac 100644
--- a/sdk/lib/_internal/vm/lib/string_patch.dart
+++ b/sdk/lib/_internal/vm/lib/string_patch.dart
@@ -47,7 +47,7 @@
   }
 
   @patch
-  const factory String.fromEnvironment(String name, {String defaultValue})
+  const factory String.fromEnvironment(String name, {String defaultValue = ""})
       native "String_fromEnvironment";
 
   bool get _isOneByte;
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index 82626a6..fa77273 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -1467,43 +1467,91 @@
  *       var future2 = future.then((_) { throw "error in first error-zone"; });
  *       runZoned(() {
  *         var future3 = future2.catchError((e) { print("Never reached!"); });
- *       }, onError: (e) { print("unused error handler"); });
- *     }, onError: (e) { print("catches error of first error-zone."); });
+ *       }, onError: (e, s) { print("unused error handler"); });
+ *     }, onError: (e, s) { print("catches error of first error-zone."); });
  *
  * Example:
  *
  *     runZoned(() {
  *       new Future(() { throw "asynchronous error"; });
- *     }, onError: print);  // Will print "asynchronous error".
+ *     }, onError: (e, s) => print(e));  // Will print "asynchronous error".
  *
  * It is possible to manually pass an error from one error zone to another
  * by re-throwing it in the new zone. If [onError] throws, that error will
  * occur in the original zone where [runZoned] was called.
  */
 R runZoned<R>(R body(),
-    {Map zoneValues, ZoneSpecification zoneSpecification, Function onError}) {
-  if (onError == null) {
-    return _runZoned<R>(body, zoneValues, zoneSpecification);
+    {Map zoneValues,
+    ZoneSpecification zoneSpecification,
+    @Deprecated("Use runZonedGuarded instead") Function onError}) {
+  ArgumentError.checkNotNull(body, "body");
+
+  if (onError != null) {
+    void Function(Object, StackTrace) typedOnError;
+    if (onError is void Function(Object, StackTrace)) {
+      typedOnError = onError;
+    } else if (onError is void Function(Object)) {
+      typedOnError = (Object e, StackTrace _) => onError(e);
+    } else {
+      throw ArgumentError.value(onError, "onError",
+          "Should accept one error, or one error and a stack trace");
+    }
+    return runZonedGuarded(body, typedOnError,
+        zoneValues: zoneValues, zoneSpecification: zoneSpecification);
   }
-  void Function(Object) unaryOnError;
-  void Function(Object, StackTrace) binaryOnError;
-  if (onError is void Function(Object, StackTrace)) {
-    binaryOnError = onError;
-  } else if (onError is void Function(Object)) {
-    unaryOnError = onError;
-  } else {
-    throw new ArgumentError("onError callback must take either an Object "
-        "(the error), or both an Object (the error) and a StackTrace.");
-  }
+  return _runZoned<R>(body, zoneValues, zoneSpecification);
+}
+
+/**
+ * Runs [body] in its own error zone.
+ *
+ * Creates a new zone using [Zone.fork] based on [zoneSpecification] and
+ * [zoneValues], then runs [body] in that zone and returns the result.
+ *
+ * The [onError] function is used *both* to handle asynchronous errors
+ * by overriding [ZoneSpecification.handleUncaughtError] in [zoneSpecification],
+ * if any, *and* to handle errors thrown synchronously by the call to [body].
+ *
+ * If an error occurs synchronously in [body],
+ * then throwing in the [onError] handler
+ * makes the call to `runZonedGuarded` throw that error,
+ * and otherwise the call to `runZonedGuarded` returns `null`.
+ *
+ * If the zone specification has a `handleUncaughtError` value or the [onError]
+ * parameter is provided, the zone becomes an error-zone.
+ *
+ * Errors will never cross error-zone boundaries by themselves.
+ * Errors that try to cross error-zone boundaries are considered uncaught in
+ * their originating error zone.
+ *
+ *     var future = new Future.value(499);
+ *     runZoned(() {
+ *       var future2 = future.then((_) { throw "error in first error-zone"; });
+ *       runZoned(() {
+ *         var future3 = future2.catchError((e) { print("Never reached!"); });
+ *       }, onError: (e, s) { print("unused error handler"); });
+ *     }, onError: (e, s) { print("catches error of first error-zone."); });
+ *
+ * Example:
+ *
+ *     runZoned(() {
+ *       new Future(() { throw "asynchronous error"; });
+ *     }, onError: (e, s) => print(e));  // Will print "asynchronous error".
+ *
+ * It is possible to manually pass an error from one error zone to another
+ * by re-throwing it in the new zone. If [onError] throws, that error will
+ * occur in the original zone where [runZoned] was called.
+ */
+@Since("2.8")
+R runZonedGuarded<R>(R body(), void onError(Object error, StackTrace stack),
+    {Map zoneValues, ZoneSpecification zoneSpecification}) {
+  ArgumentError.checkNotNull(body, "body");
+  ArgumentError.checkNotNull(onError, "onError");
+
   HandleUncaughtErrorHandler errorHandler = (Zone self, ZoneDelegate parent,
       Zone zone, error, StackTrace stackTrace) {
     try {
-      if (binaryOnError != null) {
-        self.parent.runBinary(binaryOnError, error, stackTrace);
-      } else {
-        assert(unaryOnError != null);
-        self.parent.runUnary(unaryOnError, error);
-      }
+      self.parent.runBinary(onError, error, stackTrace);
     } catch (e, s) {
       if (identical(e, error)) {
         parent.handleUncaughtError(zone, error, stackTrace);
@@ -1521,13 +1569,8 @@
   }
   try {
     return _runZoned<R>(body, zoneValues, zoneSpecification);
-  } catch (e, stackTrace) {
-    if (binaryOnError != null) {
-      binaryOnError(e, stackTrace);
-    } else {
-      assert(unaryOnError != null);
-      unaryOnError(e);
-    }
+  } catch (error, stackTrace) {
+    onError(error, stackTrace);
   }
   return null;
 }
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index e1a2672..6ee6431 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -119,6 +119,7 @@
 /**
  * Error thrown by the runtime system when a cast operation fails.
  */
+@Deprecated("Use TypeError instead")
 class CastError extends Error {}
 
 /**
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index a6253c0..8708886 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -44,7 +44,8 @@
   // Disable those static errors.
   //ignore: const_constructor_with_body
   //ignore: const_factory
-  external const factory int.fromEnvironment(String name, {int defaultValue});
+  external const factory int.fromEnvironment(String name,
+      {int defaultValue = 0});
 
   /**
    * Bit-wise and operator.
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index dc3718a..de44234 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -146,12 +146,16 @@
    * [defaultValue].
    *
    * Example of getting a value:
-   *
-   *     const String.fromEnvironment("defaultFloo", defaultValue: "no floo")
-   *
-   * Example of checking whether a declaration is there at all:
-   *
-   *     var isDeclared = const String.fromEnvironment("maybeDeclared") != null;
+   * ```
+   * const String.fromEnvironment("defaultFloo", defaultValue: "no floo")
+   * ```
+   * In order to check whether a declaration is there at all, use
+   * [bool.hasEnvironment]. Example:
+   * ```
+   * const maybeDeclared = bool.hasEnvironment("maybeDeclared")
+   *     ? String.fromEnvironment("maybeDeclared")
+   *     : null;
+   * ```
    */
   // The .fromEnvironment() constructors are special in that we do not want
   // users to call them using "new". We prohibit that by giving them bodies
@@ -160,7 +164,7 @@
   //ignore: const_constructor_with_body
   //ignore: const_factory
   external const factory String.fromEnvironment(String name,
-      {String defaultValue});
+      {String defaultValue = ""});
 
   /**
    * Gets the character (as a single-code-unit [String]) at the given [index].
diff --git a/sdk/lib/io/overrides.dart b/sdk/lib/io/overrides.dart
index 0692f9d..eecda8e 100644
--- a/sdk/lib/io/overrides.dart
+++ b/sdk/lib/io/overrides.dart
@@ -92,11 +92,7 @@
       // ServerSocket
       Future<ServerSocket> Function(dynamic, int,
               {int backlog, bool v6Only, bool shared})
-          serverSocketBind,
-
-      // Optional Zone parameters
-      ZoneSpecification zoneSpecification,
-      Function onError}) {
+          serverSocketBind}) {
     IOOverrides overrides = new _IOOverridesScope(
       // Directory
       createDirectory,
@@ -131,22 +127,15 @@
       // ServerSocket
       serverSocketBind,
     );
-    return _asyncRunZoned<R>(body,
-        zoneValues: {_ioOverridesToken: overrides},
-        zoneSpecification: zoneSpecification,
-        onError: onError);
+    return _asyncRunZoned<R>(body, zoneValues: {_ioOverridesToken: overrides});
   }
 
   /// Runs [body] in a fresh [Zone] using the overrides found in [overrides].
   ///
   /// Note that [overrides] should be an instance of a class that extends
   /// [IOOverrides].
-  static R runWithIOOverrides<R>(R body(), IOOverrides overrides,
-      {ZoneSpecification zoneSpecification, Function onError}) {
-    return _asyncRunZoned<R>(body,
-        zoneValues: {_ioOverridesToken: overrides},
-        zoneSpecification: zoneSpecification,
-        onError: onError);
+  static R runWithIOOverrides<R>(R body(), IOOverrides overrides) {
+    return _asyncRunZoned<R>(body, zoneValues: {_ioOverridesToken: overrides});
   }
 
   // Directory
diff --git a/sdk_nnbd/lib/_http/overrides.dart b/sdk_nnbd/lib/_http/overrides.dart
index be658c1..bbd21ee 100644
--- a/sdk_nnbd/lib/_http/overrides.dart
+++ b/sdk_nnbd/lib/_http/overrides.dart
@@ -49,27 +49,20 @@
   static R runZoned<R>(R body(),
       {HttpClient Function(SecurityContext?)? createHttpClient,
       String Function(Uri uri, Map<String, String>? environment)?
-          findProxyFromEnvironment,
-      ZoneSpecification? zoneSpecification,
-      Function? onError}) {
+          findProxyFromEnvironment}) {
     HttpOverrides overrides =
         new _HttpOverridesScope(createHttpClient, findProxyFromEnvironment);
     return _asyncRunZoned<R>(body,
-        zoneValues: {_httpOverridesToken: overrides},
-        zoneSpecification: zoneSpecification,
-        onError: onError);
+        zoneValues: {_httpOverridesToken: overrides});
   }
 
   /// Runs [body] in a fresh [Zone] using the overrides found in [overrides].
   ///
   /// Note that [overrides] should be an instance of a class that extends
   /// [HttpOverrides].
-  static R runWithHttpOverrides<R>(R body(), HttpOverrides overrides,
-      {ZoneSpecification? zoneSpecification, Function? onError}) {
+  static R runWithHttpOverrides<R>(R body(), HttpOverrides overrides) {
     return _asyncRunZoned<R>(body,
-        zoneValues: {_httpOverridesToken: overrides},
-        zoneSpecification: zoneSpecification,
-        onError: onError);
+        zoneValues: {_httpOverridesToken: overrides});
   }
 
   /// Returns a new [HttpClient] using the given [context].
diff --git a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
index 53bfbc1b..028ed06 100644
--- a/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
+++ b/sdk_nnbd/lib/_internal/js_dev_runtime/private/js_array.dart
@@ -582,13 +582,7 @@
 
   Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
 
-  List<E> operator +(List<E> other) {
-    int totalLength = this.length + other.length;
-    return <E>[]
-      ..length = totalLength
-      ..setRange(0, this.length, this)
-      ..setRange(this.length, totalLength, other);
-  }
+  List<E> operator +(List<E> other) => [...this, ...other];
 
   int indexWhere(bool Function(E) test, [int start = 0]) {
     if (start >= this.length) return -1;
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
index 8d177bf..e7e4332 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_array.dart
@@ -643,13 +643,7 @@
 
   Iterable<T> whereType<T>() => new WhereTypeIterable<T>(this);
 
-  List<E> operator +(List<E> other) {
-    int totalLength = this.length + other.length;
-    return <E>[]
-      ..length = totalLength
-      ..setRange(0, this.length, this)
-      ..setRange(this.length, totalLength, other);
-  }
+  List<E> operator +(List<E> other) => [...this, ...other];
 
   int indexWhere(bool test(E element), [int start = 0]) {
     if (start >= this.length) return -1;
diff --git a/sdk_nnbd/lib/_internal/vm/bin/builtin.dart b/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
index a524560..1befe5a 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/builtin.dart
@@ -467,8 +467,7 @@
         _log("$packagesFile exists: $exists");
       }
       if (exists) {
-        _loadPackagesFile(traceLoading, packagesFile);
-        return;
+        return _loadPackagesFile(traceLoading, packagesFile);
       }
       // Move up one level.
       prev = dir;
diff --git a/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart b/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart
index 64fff0b..67ba9b2 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/compact_hash.dart
@@ -120,7 +120,7 @@
   static int _nextProbe(int i, int sizeMask) => (i + 1) & sizeMask;
 
   // A self-loop is used to mark a deleted key or value.
-  static bool _isDeleted(List data, Object keyOrValue) =>
+  static bool _isDeleted(List data, Object? keyOrValue) =>
       identical(keyOrValue, data);
   static void _setDeletedAt(List data, int d) {
     data[d] = data;
@@ -486,7 +486,7 @@
 
   E get first {
     for (int offset = 0; offset < _usedData; offset++) {
-      Object current = _data[offset];
+      Object? current = _data[offset];
       if (!_HashBase._isDeleted(_data, current)) {
         return current as E;
       }
@@ -496,7 +496,7 @@
 
   E get last {
     for (int offset = _usedData - 1; offset >= 0; offset--) {
-      Object current = _data[offset];
+      Object? current = _data[offset];
       if (!_HashBase._isDeleted(_data, current)) {
         return current as E;
       }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
index d4c2a46..4780200 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
@@ -519,7 +519,7 @@
    * The parser is closed by calling [close] or calling [addSourceChunk] with
    * `true` as second (`isLast`) argument.
    */
-  Object get result {
+  dynamic get result {
     return listener.result;
   }
 
diff --git a/sdk_nnbd/lib/async/zone.dart b/sdk_nnbd/lib/async/zone.dart
index 53ad166..3c50e19 100644
--- a/sdk_nnbd/lib/async/zone.dart
+++ b/sdk_nnbd/lib/async/zone.dart
@@ -1465,7 +1465,7 @@
  * If an error occurs synchronously in [body],
  * then throwing in the [onError] handler
  * makes the call to `runZone` throw that error,
- * and otherwise the call to `runZoned` returns `null`.
+ * and otherwise the call to `runZoned` attempt to return `null`.
  *
  * If the zone specification has a `handleUncaughtError` value or the [onError]
  * parameter is provided, the zone becomes an error-zone.
@@ -1474,19 +1474,19 @@
  * Errors that try to cross error-zone boundaries are considered uncaught in
  * their originating error zone.
  *
- *     var future = Future.value(499);
+ *     var future = new Future.value(499);
  *     runZoned(() {
  *       var future2 = future.then((_) { throw "error in first error-zone"; });
  *       runZoned(() {
  *         var future3 = future2.catchError((e) { print("Never reached!"); });
- *       }, onError: (e) { print("unused error handler"); });
- *     }, onError: (e) { print("catches error of first error-zone."); });
+ *       }, onError: (e, s) { print("unused error handler"); });
+ *     }, onError: (e, s) { print("catches error of first error-zone."); });
  *
  * Example:
  *
  *     runZoned(() {
  *       new Future(() { throw "asynchronous error"; });
- *     }, onError: print);  // Will print "asynchronous error".
+ *     }, onError: (e, s) => print(e));  // Will print "asynchronous error".
  *
  * It is possible to manually pass an error from one error zone to another
  * by re-throwing it in the new zone. If [onError] throws, that error will
@@ -1495,30 +1495,74 @@
 R runZoned<R>(R body(),
     {Map<Object?, Object?>? zoneValues,
     ZoneSpecification? zoneSpecification,
-    Function? onError}) {
-  if (onError == null) {
-    return _runZoned<R>(body, zoneValues, zoneSpecification);
+    @Deprecated("Use runZonedGuarded instead") Function? onError}) {
+  ArgumentError.checkNotNull(body, "body");
+  if (onError != null) {
+    // TODO: Remove this when code have been migrated off using [onError].
+    if (onError is! void Function(Object, StackTrace)) {
+      if (onError is void Function(Object)) {
+        var originalOnError = onError;
+        onError = (Object error, StackTrace stack) => originalOnError(error);
+      } else {
+        throw ArgumentError.value(onError, "onError",
+            "Must be Function(Object) or Function(Object, StackTrace)");
+      }
+    }
+    return runZonedGuarded(body, onError,
+        zoneSpecification: zoneSpecification, zoneValues: zoneValues) as R;
   }
-  void Function(Object)? unaryOnError;
-  void Function(Object, StackTrace)? binaryOnError;
-  if (onError is void Function(Object, StackTrace)) {
-    binaryOnError = onError;
-  } else if (onError is void Function(Object)) {
-    unaryOnError = onError;
-  } else {
-    throw new ArgumentError("onError callback must take either an Object "
-        "(the error), or both an Object (the error) and a StackTrace.");
-  }
+  return _runZoned<R>(body, zoneValues, zoneSpecification);
+}
+
+/**
+ * Runs [body] in its own error zone.
+ *
+ * Creates a new zone using [Zone.fork] based on [zoneSpecification] and
+ * [zoneValues], then runs [body] in that zone and returns the result.
+ *
+ * The [onError] function is used *both* to handle asynchronous errors
+ * by overriding [ZoneSpecification.handleUncaughtError] in [zoneSpecification],
+ * if any, *and* to handle errors thrown synchronously by the call to [body].
+ *
+ * If an error occurs synchronously in [body],
+ * then throwing in the [onError] handler
+ * makes the call to `runZonedGuarded` throw that error,
+ * and otherwise the call to `runZonedGuarded` returns `null`.
+ *
+ * The zone will always be an error-zone.
+ *
+ * Errors will never cross error-zone boundaries by themselves.
+ * Errors that try to cross error-zone boundaries are considered uncaught in
+ * their originating error zone.
+ * ```dart
+ * var future = Future.value(499);
+ * runZonedGuarded(() {
+ *   var future2 = future.then((_) { throw "error in first error-zone"; });
+ *   runZonedGuarded(() {
+ *     var future3 = future2.catchError((e) { print("Never reached!"); });
+ *   }, (e, s) { print("unused error handler"); });
+ * }, (e, s) { print("catches error of first error-zone."); });
+ * ```
+ * Example:
+ * ```dart
+ * runZonedGuarded(() {
+ *   new Future(() { throw "asynchronous error"; });
+ * }, (e, s) => print(e));  // Will print "asynchronous error".
+ * ```
+ * It is possible to manually pass an error from one error zone to another
+ * by re-throwing it in the new zone. If [onError] throws, that error will
+ * occur in the original zone where [runZoned] was called.
+ */
+@Since("2.8")
+R? runZonedGuarded<R>(R body(), void onError(Object error, StackTrace stack),
+    {Map<Object?, Object?>? zoneValues, ZoneSpecification? zoneSpecification}) {
+  ArgumentError.checkNotNull(body, "body");
+  ArgumentError.checkNotNull(onError, "onError");
   _Zone parentZone = Zone._current;
   HandleUncaughtErrorHandler errorHandler = (Zone self, ZoneDelegate parent,
       Zone zone, Object error, StackTrace stackTrace) {
     try {
-      if (binaryOnError != null) {
-        parentZone.runBinary(binaryOnError, error, stackTrace);
-      } else {
-        assert(unaryOnError != null);
-        parentZone.runUnary(unaryOnError!, error);
-      }
+      parentZone.runBinary(onError, error, stackTrace);
     } catch (e, s) {
       if (identical(e, error)) {
         parent.handleUncaughtError(zone, error, stackTrace);
@@ -1536,17 +1580,10 @@
   }
   try {
     return _runZoned<R>(body, zoneValues, zoneSpecification);
-  } catch (e, stackTrace) {
-    if (binaryOnError != null) {
-      binaryOnError(e, stackTrace);
-    } else {
-      assert(unaryOnError != null);
-      unaryOnError!(e);
-    }
+  } catch (error, stackTrace) {
+    onError(error, stackTrace);
   }
-  // TODO(lrn): Change behavior to throw the actual resulting error,
-  // perhaps even synchronously.
-  return null as R;
+  return null;
 }
 
 /// Runs [body] in a new zone based on [zoneValues] and [specification].
diff --git a/sdk_nnbd/lib/core/errors.dart b/sdk_nnbd/lib/core/errors.dart
index 005cb84..80d29c7 100644
--- a/sdk_nnbd/lib/core/errors.dart
+++ b/sdk_nnbd/lib/core/errors.dart
@@ -117,6 +117,7 @@
 /**
  * Error thrown by the runtime system when a cast operation fails.
  */
+@Deprecated("Use TypeError instead")
 class CastError extends Error {}
 
 /**
diff --git a/sdk_nnbd/lib/core/string.dart b/sdk_nnbd/lib/core/string.dart
index e65f8e9..c9cc847 100644
--- a/sdk_nnbd/lib/core/string.dart
+++ b/sdk_nnbd/lib/core/string.dart
@@ -144,12 +144,16 @@
    * [defaultValue].
    *
    * Example of getting a value:
-   *
-   *     const String.fromEnvironment("defaultFloo", defaultValue: "no floo")
-   *
-   * Example of checking whether a declaration is there at all:
-   *
-   *     var isDeclared = const String.fromEnvironment("maybeDeclared") != null;
+   * ```
+   * const String.fromEnvironment("defaultFloo", defaultValue: "no floo")
+   * ```
+   * In order to check whether a declaration is there at all, use
+   * [bool.hasEnvironment]. Example:
+   * ```
+   * const maybeDeclared = bool.hasEnvironment("maybeDeclared")
+   *     ? String.fromEnvironment("maybeDeclared")
+   *     : null;
+   * ```
    */
   // The .fromEnvironment() constructors are special in that we do not want
   // users to call them using "new". We prohibit that by giving them bodies
diff --git a/sdk_nnbd/lib/io/link.dart b/sdk_nnbd/lib/io/link.dart
index 97addfb..3f2896f 100644
--- a/sdk_nnbd/lib/io/link.dart
+++ b/sdk_nnbd/lib/io/link.dart
@@ -271,7 +271,7 @@
     return result;
   }
 
-  static throwIfError(Object result, String msg, [String path = ""]) {
+  static throwIfError(Object? result, String msg, [String path = ""]) {
     if (result is OSError) {
       throw new FileSystemException(msg, path, result);
     }
diff --git a/sdk_nnbd/lib/io/overrides.dart b/sdk_nnbd/lib/io/overrides.dart
index 1fd0f06..4b7deaa 100644
--- a/sdk_nnbd/lib/io/overrides.dart
+++ b/sdk_nnbd/lib/io/overrides.dart
@@ -90,11 +90,7 @@
       // ServerSocket
       Future<ServerSocket> Function(dynamic, int,
               {int backlog, bool v6Only, bool shared})?
-          serverSocketBind,
-
-      // Optional Zone parameters
-      ZoneSpecification? zoneSpecification,
-      Function? onError}) {
+          serverSocketBind}) {
     IOOverrides overrides = new _IOOverridesScope(
       // Directory
       createDirectory,
@@ -129,22 +125,15 @@
       // ServerSocket
       serverSocketBind,
     );
-    return _asyncRunZoned<R>(body,
-        zoneValues: {_ioOverridesToken: overrides},
-        zoneSpecification: zoneSpecification,
-        onError: onError);
+    return _asyncRunZoned<R>(body, zoneValues: {_ioOverridesToken: overrides});
   }
 
   /// Runs [body] in a fresh [Zone] using the overrides found in [overrides].
   ///
   /// Note that [overrides] should be an instance of a class that extends
   /// [IOOverrides].
-  static R runWithIOOverrides<R>(R body(), IOOverrides overrides,
-      {ZoneSpecification? zoneSpecification, Function? onError}) {
-    return _asyncRunZoned<R>(body,
-        zoneValues: {_ioOverridesToken: overrides},
-        zoneSpecification: zoneSpecification,
-        onError: onError);
+  static R runWithIOOverrides<R>(R body(), IOOverrides overrides) {
+    return _asyncRunZoned<R>(body, zoneValues: {_ioOverridesToken: overrides});
   }
 
   // Directory
diff --git a/tests/co19/update.sh b/tests/co19/update.sh
index eb4dba3..940db04 100755
--- a/tests/co19/update.sh
+++ b/tests/co19/update.sh
@@ -63,8 +63,5 @@
 set +x
 cat << EOF
 
-Wait for the builders to finish. If any failed, pre-approve them:
-
-  tools/sdks/dart-sdk/bin/dart tools/approve_results.dart \
-    -p https://dart-review.googlesource.com/c/sdk/+/$ISSUE
+Wait for the builders to finish. If any failed, pre-approve them.
 EOF
diff --git a/tests/co19_2/update.sh b/tests/co19_2/update.sh
index a482bf3..3bac8ab 100755
--- a/tests/co19_2/update.sh
+++ b/tests/co19_2/update.sh
@@ -64,8 +64,5 @@
 set +x
 cat << EOF
 
-Wait for the builders to finish. If any failed, pre-approve them:
-
-  tools/sdks/dart-sdk/bin/dart tools/approve_results.dart \
-    -p https://dart-review.googlesource.com/c/sdk/+/$ISSUE
+Wait for the builders to finish. If any failed, pre-approve them.
 EOF
diff --git a/tests/corelib/date_time11_test.dart b/tests/corelib/date_time11_test.dart
index 0a1790c..75c2c34 100644
--- a/tests/corelib/date_time11_test.dart
+++ b/tests/corelib/date_time11_test.dart
@@ -122,7 +122,7 @@
   }
 }
 
-void main(List<String> args) {
+void main() {
   // The following code constructs a String with all timezones that are
   // relevant for this test.
   // This can be helpful for running tests in multiple timezones.
diff --git a/tests/corelib/expando_test.dart b/tests/corelib/expando_test.dart
index 3189c9b..04d6ad4 100644
--- a/tests/corelib/expando_test.dart
+++ b/tests/corelib/expando_test.dart
@@ -31,7 +31,7 @@
   }
 
   static visit(object) {
-    int count = visits[object]!;
+    int? count = visits[object];
     count = (count == null) ? 1 : count + 1;
     visits[object] = count;
   }
diff --git a/tests/corelib/iterable_followed_by_test.dart b/tests/corelib/iterable_followed_by_test.dart
index 33a37c5..a2e352d 100644
--- a/tests/corelib/iterable_followed_by_test.dart
+++ b/tests/corelib/iterable_followed_by_test.dart
@@ -29,8 +29,9 @@
           expect, iterable.elementAt(index), "$name: elementAt($index)");
       Expect.isTrue(iterable.contains(expect), "$name:contains $index");
     }
-    Expect.isFalse(it.moveNext(),
-        "$name: extra element at ${expects.length}: ${it.current}");
+    var hasNext = it.moveNext();
+    Expect.isFalse(hasNext,
+        "$name: extra element at ${expects.length}: ${hasNext ? it.current : ''}");
   } on Error {
     print("Failed during: $name");
     rethrow;
@@ -50,9 +51,9 @@
   for (int i = 0; i <= length; i++) {
     for (int j = 0; j <= length - i; j++) {
       test(expects.sublist(i, i + j), follow.skip(i).take(j),
-          "$name.skiptake($i,${i+j})");
+          "$name.skiptake($i,${i + j})");
       test(expects.sublist(i, i + j), follow.take(i + j).skip(i),
-          "$name.takeskip($i,${i+j})");
+          "$name.takeskip($i,${i + j})");
     }
   }
 }
@@ -99,4 +100,4 @@
   types(<int>[1, 2, 3, 4], const <int>[], const <int>[1, 2, 3, 4], "0+4");
   types(<int>[1, 2, 3, 4], const <int>[1, 2], const <int>[3, 4], "2+2");
   types(<int>[1, 2, 3, 4], const <int>[1, 2, 3, 4], const <int>[], "4+0");
-}
+}
\ No newline at end of file
diff --git a/tests/corelib/iterable_to_list_test.dart b/tests/corelib/iterable_to_list_test.dart
index 63e5954..112d9cd 100644
--- a/tests/corelib/iterable_to_list_test.dart
+++ b/tests/corelib/iterable_to_list_test.dart
@@ -20,7 +20,6 @@
   testIterable(<int?>[1, 2, 3], <int?>[1, 2, 3]);
   testIterable(const [1, 2], [1, 2], 0);
   testIterable(const <int>[1, 2], <int>[1, 2], 0);
-  testIterable(const <int?>[1, 2], <int?>[1, 2]);
   testIterable(<dynamic, dynamic>{"x": 1, "y": 1}.keys, <dynamic>["x", "y"]);
   testIterable(<String, int>{"x": 1, "y": 1}.keys, <String>["x", "y"], "");
   testIterable(<String?, int>{"x": 1, "y": 1}.keys, <String?>["x", "y"]);
@@ -41,10 +40,10 @@
   testIterable(new Queue<int>.from(<int>[1, 2, 3]), <int>[1, 2, 3], 0);
   testIterable(new Queue<int?>.from(<int?>[1, 2, 3]), <int?>[1, 2, 3]);
   testIterable(new Uint8List.fromList(<int>[1, 2, 3]), //    //# 01: ok
-      <int>[1, 2, 3], 0); //                                    //# 01: continued
+      <int>[1, 2, 3], 0); //                                 //# 01: continued
   testIterable(new Float32List.fromList([1.0, 2.0, 3.0]), // //# 01: continued
-      <double>[1.0, 2.0, 3.0], 0.1); //                           //# 01: continued
-  testIterable("abc".codeUnits, <int>[97, 98, 99]); //       //# 01: continued
+      <double>[1.0, 2.0, 3.0], 0.1); //                      //# 01: continued
+  testIterable("abc".codeUnits, <int>[97, 98, 99], 99); //   //# 01: continued
   testIterable("abc".runes, <int>[97, 98, 99], 99);
 }
 
@@ -88,4 +87,4 @@
       list.add(element);
     });
   }
-}
+}
\ No newline at end of file
diff --git a/tests/corelib/map_test.dart b/tests/corelib/map_test.dart
index 74f0577..09b9311 100644
--- a/tests/corelib/map_test.dart
+++ b/tests/corelib/map_test.dart
@@ -160,7 +160,7 @@
 
 void testMap<K, V>(
     Map<K, V> typedMap, key1, key2, key3, key4, key5, key6, key7, key8) {
-  Map map = typedMap;
+  var map = typedMap;
   int value1 = 10;
   int value2 = 20;
   int value3 = 30;
diff --git a/tests/corelib/map_unmodifiable_cast_test.dart b/tests/corelib/map_unmodifiable_cast_test.dart
index 2eca99f..31466ef 100644
--- a/tests/corelib/map_unmodifiable_cast_test.dart
+++ b/tests/corelib/map_unmodifiable_cast_test.dart
@@ -31,16 +31,16 @@
   testNum(m2.cast<int, int>(), "Map<num>.unmod.cast<int>");
 
   Map<Symbol, dynamic> nsm = new NsmMap().foo(a: 0);
-  test(nsm, #a, 0, "nsm", noSuchMethodMap: true);
-  test(nsm.cast<Object, int>(), #a, 0, "nsm.cast", noSuchMethodMap: true);
+  test<Symbol, dynamic>(nsm, #a, 0, "nsm", noSuchMethodMap: true);
+  test<Object, int>(nsm.cast<Object, int>(), #a, 0, "nsm.cast",
+      noSuchMethodMap: true);
 }
 
 void testNum(Map<Object, Object> map, String name) {
-  test(map, 1, 37, name);
+  test<int, int>(map, 1, 37, name);
 }
 
-void test(
-    Map<Object?, Object?> map, Object firstKey, Object firstValue, String name,
+void test<K, V>(map, firstKey, firstValue, String name,
     {bool noSuchMethodMap: false}) {
   if (!noSuchMethodMap) {
     Expect.isTrue(map.containsKey(firstKey), "$name.containsKey");
@@ -54,10 +54,10 @@
     map.remove(firstKey);
   }, "$name.remove");
   Expect.throwsUnsupportedError(() {
-    map[null] = null;
+    map[firstKey] = firstValue;
   }, "$name[]=");
   Expect.throwsUnsupportedError(() {
-    map.addAll(<Null, Null>{null: null});
+    map.addAll(<K, V>{firstKey: firstValue});
   }, "$name.addAll");
 }
 
diff --git a/tests/corelib/regexp/capture-3_test.dart b/tests/corelib/regexp/capture-3_test.dart
index 06cfbdc..74fc791 100644
--- a/tests/corelib/regexp/capture-3_test.dart
+++ b/tests/corelib/regexp/capture-3_test.dart
@@ -40,7 +40,7 @@
   assertEquals("acdacd", "abcdabcd".replaceAll(new RegExp(r"b"), ""));
 
   dynamic captureMatch(re) {
-    var match = firstMatch("abcd", re);
+    var match = firstMatch("abcd", re)!;
     assertEquals("b", match.group(1));
     assertEquals("c", match.group(2));
   }
@@ -93,7 +93,7 @@
 
   var s = "Don't prune based on a repetition of length 0";
   assertEquals(null, firstMatch(s, new RegExp(r"å{1,1}prune")));
-  assertEquals("prune", (firstMatch(s, new RegExp(r"å{0,0}prune"))[0]));
+  assertEquals("prune", (firstMatch(s, new RegExp(r"å{0,0}prune"))![0]));
 
   // Some very deep regexps where FilterASCII gives up in order not to make the
   // stack overflow.
diff --git a/tests/corelib/regexp/global_test.dart b/tests/corelib/regexp/global_test.dart
index b6e20cb..2ca88ce 100644
--- a/tests/corelib/regexp/global_test.dart
+++ b/tests/corelib/regexp/global_test.dart
@@ -121,9 +121,9 @@
   re_string = re_string + "1";
   // re_string = "(((...((a))...)))1"
 
-  var regexps = new List();
-  var last_match_expectations = new List();
-  var first_capture_expectations = new List();
+  var regexps = [];
+  var last_match_expectations = [];
+  var first_capture_expectations = [];
 
   // Atomic regexp.
   regexps.add(new RegExp(r"a1"));
diff --git a/tests/corelib/regexp/lookbehind_test.dart b/tests/corelib/regexp/lookbehind_test.dart
index 3fd11af..161d65d 100644
--- a/tests/corelib/regexp/lookbehind_test.dart
+++ b/tests/corelib/regexp/lookbehind_test.dart
@@ -41,7 +41,7 @@
     }
   }
 
-  void execRE(RegExp re, String input, List<String> expectedResult) {
+  void execRE(RegExp re, String input, List<String?> expectedResult) {
     assertTrue(re.hasMatch(input));
     shouldBe(re.firstMatch(input), expectedResult);
   }
diff --git a/tests/corelib/regexp/non-capturing-groups_test.dart b/tests/corelib/regexp/non-capturing-groups_test.dart
index f192b15..d335799 100644
--- a/tests/corelib/regexp/non-capturing-groups_test.dart
+++ b/tests/corelib/regexp/non-capturing-groups_test.dart
@@ -41,9 +41,12 @@
   assertEquals("y".indexOf(new RegExp(r"(x)?\1y")), 0);
   assertEquals("y".replaceAll(new RegExp(r"(x)?\1y"), "z"), "z");
   assertEquals(
-      "y".replaceAllMapped(new RegExp(r"(x)?y"), (m) => m.group(1)!), "null");
+      "y".replaceAllMapped(new RegExp(r"(x)?y"), (m) => m.group(1) ?? "null"),
+      "null");
   assertEquals(
-      "y".replaceAllMapped(new RegExp(r"(x)?\1y"), (m) => m.group(1)!), "null");
+      "y".replaceAllMapped(new RegExp(r"(x)?\1y"), (m) => m.group(1) ?? "null"),
+      "null");
   assertEquals(
-      "y".replaceAllMapped(new RegExp(r"(x)?y"), (m) => m.group(1)!), "null");
+      "y".replaceAllMapped(new RegExp(r"(x)?y"), (m) => m.group(1) ?? "null"),
+      "null");
 }
diff --git a/tests/corelib/regexp/v8_regexp_utils.dart b/tests/corelib/regexp/v8_regexp_utils.dart
index c9959e2..dc4293b 100644
--- a/tests/corelib/regexp/v8_regexp_utils.dart
+++ b/tests/corelib/regexp/v8_regexp_utils.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+ // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
@@ -6,27 +6,27 @@
 
 import "package:expect/expect.dart";
 
-void assertEquals(actual, expected, [String? message = null]) {
+void assertEquals(actual, expected, [String message = '']) {
   Expect.equals(actual, expected, message);
 }
 
-void assertTrue(actual, [String? message = null]) {
+void assertTrue(actual, [String message = '']) {
   Expect.isTrue(actual, message);
 }
 
-void assertFalse(actual, [String? message = null]) {
+void assertFalse(actual, [String message = '']) {
   Expect.isFalse(actual, message);
 }
 
 void assertThrows(fn, [num? testid = null]) {
-  Expect.throws(fn, null, "Test $testid");
+  Expect.throws(fn, (_) => true, "Test $testid");
 }
 
 void assertDoesNotThrow(fn, [num? testid = null]) {
   fn();
 }
 
-void assertNull(actual, [num testid = null]) {
+void assertNull(actual, [num? testid = null]) {
   Expect.isNull(actual, "Test $testid");
 }
 
@@ -51,7 +51,7 @@
   Expect.isNull(actual);
 }
 
-void shouldBe(actual, expected, [String? message = null]) {
+void shouldBe(actual, expected, [String message = '']) {
   if (expected == null) {
     Expect.isNull(actual, message);
   } else {
@@ -62,8 +62,8 @@
   }
 }
 
-Match firstMatch(String str, RegExp pattern) => pattern.firstMatch(str);
-List<String> allStringMatches(String str, RegExp pattern) =>
+Match? firstMatch(String str, RegExp pattern) => pattern.firstMatch(str);
+List<String?> allStringMatches(String str, RegExp pattern) =>
     pattern.allMatches(str).map((Match m) => m.group(0)).toList();
 
 void description(str) {}
diff --git a/tests/corelib/set_test.dart b/tests/corelib/set_test.dart
index 5c8a12c..18deeb3 100644
--- a/tests/corelib/set_test.dart
+++ b/tests/corelib/set_test.dart
@@ -61,7 +61,7 @@
   Expect.isTrue(set.containsAll(set));
 
   // Test Set.map.
-  bool testMap(dynamic val) {
+  int testMap(dynamic val) {
     return (val as int) * val;
   }
 
diff --git a/tests/corelib/string_operations_with_null_test.dart b/tests/corelib/string_operations_with_null_test.dart
index 8c07025..462ecd5 100644
--- a/tests/corelib/string_operations_with_null_test.dart
+++ b/tests/corelib/string_operations_with_null_test.dart
@@ -11,7 +11,8 @@
 }
 
 main() {
-  Expect.throwsArgumentError(() => 'foo' + returnStringOrNull());
+  Expect.throws(() => 'foo' + returnStringOrNull(),
+      (e) => e is ArgumentError || e is TypeError);
   Expect.throws(() => 'foo'.split(returnStringOrNull()),
-      (e) => e is ArgumentError || e is NoSuchMethodError);
+      (e) => e is ArgumentError || e is NoSuchMethodError || e is TypeError);
 }
diff --git a/tests/corelib/uri_test.dart b/tests/corelib/uri_test.dart
index 386838a..bb45fe0 100644
--- a/tests/corelib/uri_test.dart
+++ b/tests/corelib/uri_test.dart
@@ -42,7 +42,7 @@
 }
 
 testEncodeDecodeQueryComponent(String orig, String encodedUTF8,
-    String encodedLatin1, String encodedAscii) {
+    String encodedLatin1, String? encodedAscii) {
   var e, d;
   e = Uri.encodeQueryComponent(orig);
   Expect.stringEquals(encodedUTF8, e);
diff --git a/tests/language/assign/to_type_test.dart b/tests/language/assign/to_type_test.dart
index b8e4480..f6f8f29 100644
--- a/tests/language/assign/to_type_test.dart
+++ b/tests/language/assign/to_type_test.dart
@@ -10,7 +10,7 @@
     T = Null;
 //  ^
 // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_TYPE
-// [cfe] Setter not found: 'T'.
+// [cfe] Can't assign to a type literal.
   }
 }
 
@@ -25,13 +25,13 @@
   D = Null;
 //^
 // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_TYPE
-// [cfe] Setter not found: 'D'.
+// [cfe] Can't assign to a type literal.
   E = Null;
 //^
 // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_TYPE
-// [cfe] Setter not found: 'E'.
+// [cfe] Can't assign to a type literal.
   F = Null;
 //^
 // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_TYPE
-// [cfe] Setter not found: 'F'.
+// [cfe] Can't assign to a type literal.
 }
diff --git a/tests/language/nnbd/static_errors/default_list_constructor_test.dart b/tests/language/nnbd/static_errors/default_list_constructor_test.dart
index 7263438..c15b01e 100644
--- a/tests/language/nnbd/static_errors/default_list_constructor_test.dart
+++ b/tests/language/nnbd/static_errors/default_list_constructor_test.dart
@@ -6,17 +6,18 @@
 
 import 'opted_out_library.dart';
 
-// Test that it is an error to call the default List constructor with a length
-// argument and a type argument which is potentially non-nullable.
+// Test that it is an error to call the default List constructor.
 main() {
   var a = new List<int>(3); //# 01: compile-time error
-  var b = new List<String?>(3);
-  List<C> c = List(5); //# 02: compile-time error
-  consumeListOfStringStar(new List(3)); //# 03: compile-time error
+  var b = new List<int?>(3); //# 02: compile-time-error
+  var c = new List<int>(); //# 03: compile-time error
+  var d = new List<int?>(); //# 04: compile-time error
+  List<C> c = new List(5); //# 05: compile-time error
+  consumeListOfStringStar(new List(3)); //# 06: compile-time error
 }
 
 class A<T> {
-  var l = new List<T>(3); //# 04: compile-time error
+  var l = new List<T>(3); //# 07: compile-time error
 }
 
 class C {}
diff --git a/tests/language_2/assign/to_type_test.dart b/tests/language_2/assign/to_type_test.dart
index 3b09b48..0fc076a 100644
--- a/tests/language_2/assign/to_type_test.dart
+++ b/tests/language_2/assign/to_type_test.dart
@@ -10,7 +10,7 @@
     T = null;
 //  ^
 // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_TYPE
-// [cfe] Setter not found: 'T'.
+// [cfe] Can't assign to a type literal.
   }
 }
 
@@ -25,13 +25,13 @@
   D = null;
 //^
 // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_TYPE
-// [cfe] Setter not found: 'D'.
+// [cfe] Can't assign to a type literal.
   E = null;
 //^
 // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_TYPE
-// [cfe] Setter not found: 'E'.
+// [cfe] Can't assign to a type literal.
   F = null;
 //^
 // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_TYPE
-// [cfe] Setter not found: 'F'.
+// [cfe] Can't assign to a type literal.
 }
diff --git a/tests/language_2/final/variable_assignment_test.dart b/tests/language_2/final/variable_assignment_test.dart
index d56db9332..f001d40 100644
--- a/tests/language_2/final/variable_assignment_test.dart
+++ b/tests/language_2/final/variable_assignment_test.dart
@@ -9,17 +9,17 @@
   x = 0;
 //^
 // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_LOCAL
-// [cfe] Setter not found: 'x'.
+// [cfe] Can't assign to the final variable 'x'.
   x += 1;
 //^
 // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_LOCAL
-// [cfe] Setter not found: 'x'.
+// [cfe] Can't assign to the final variable 'x'.
   ++x;
   //^
   // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_LOCAL
-  // [cfe] Setter not found: 'x'.
+  // [cfe] Can't assign to the final variable 'x'.
   x++;
 //^
 // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_LOCAL
-// [cfe] Setter not found: 'x'.
+// [cfe] Can't assign to the final variable 'x'.
 }
diff --git a/tests/language_2/if_null/assignment_behavior_test.dart b/tests/language_2/if_null/assignment_behavior_test.dart
index 0cd4e67..a95aa57 100644
--- a/tests/language_2/if_null/assignment_behavior_test.dart
+++ b/tests/language_2/if_null/assignment_behavior_test.dart
@@ -164,11 +164,11 @@
   { final l = 1; l ??= null; }
   //             ^
   // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_FINAL_LOCAL
-  // [cfe] Setter not found: 'l'.
+  // [cfe] Can't assign to the final variable 'l'.
   C ??= null;
 //^
 // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_TYPE
-// [cfe] Setter not found: 'C'.
+// [cfe] Can't assign to a type literal.
   h ??= null;
 //^
 // [analyzer] COMPILE_TIME_ERROR.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT
diff --git a/tests/language_2/nonfunction_type_aliases/aliased_cyclic_superclass_error_test.dart b/tests/language_2/nonfunction_type_aliases/aliased_cyclic_superclass_error_test.dart
new file mode 100644
index 0000000..0000f30
--- /dev/null
+++ b/tests/language_2/nonfunction_type_aliases/aliased_cyclic_superclass_error_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=nonfunction-type-aliases
+
+typedef T = C;
+
+class C extends T {}
+//    ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+main() => C();
diff --git a/tests/language_2/nonfunction_type_aliases/generic_aliased_supertype_test.dart b/tests/language_2/nonfunction_type_aliases/generic_aliased_supertype_test.dart
new file mode 100644
index 0000000..3eed540
--- /dev/null
+++ b/tests/language_2/nonfunction_type_aliases/generic_aliased_supertype_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=nonfunction-type-aliases
+
+class A<X> {}
+
+typedef A1<Y> = A<Y>;
+typedef A2<U, Z> = A1<A<Z>>;
+typedef A3<W> = A2<int, A<W>>;
+
+class B extends A3<B> {}
+
+void f(A<A<A<B>>> a) {}
+
+void main() {
+  f(B());
+}
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_class_error_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_class_error_test.dart
index 1501dad..db5c366 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_class_error_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_class_error_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -21,56 +18,21 @@
 
 // Use the aliased type.
 
-T<int> v1;
-List<T<void>> v2 = [];
-final T<String> v3 = throw "Anything";
-const List<T<C>> v4 = [];
-const v5 = <Type, Type>{T: T};
+abstract class C {}
 
-abstract class C {
-  static T<C> v1;
-  static List<T<T>> v2 = [];
-  static final T<Null> v3 = throw "Anything";
-  static const List<T<List>> v4 = [];
-
-  T<C> v5;
-  List<T<T>> v6 = [];
-  final T<Null> v7;
-
-  C(): v7 = T();
-  C.name1(this.v5, this.v7);
-  factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
-
-  T<double> operator +(T<double> other);
-  T<FutureOr<FutureOr<void>>> get g;
-  set g(T<FutureOr<FutureOr<void>>> value);
-  Map<T<C>, T<C>> m1(covariant T<C> arg1, [Set<Set<T<C>>> arg2]);
-  void m2({T arg1, Map<T, T> arg2(T Function(T) arg21, T arg22)});
-}
-
-class D1<X> extends T<X> {}
 abstract class D2 extends C with T<int> {}
-abstract class D3<X, Y> implements T<T> {}
+//             ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
 abstract class D4 = C with T<void>;
-
-extension E on T<dynamic> {
-  T<dynamic> foo(T<dynamic> t) => t;
-}
-
-X foo<X>(X x) => x;
-
-T<Type> Function(T<Type>) id;
+//             ^
+// [analyzer] unspecified
+// [cfe] unspecified
 
 main() {
-  var v8 = <T<C>>[];
-  var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
-  var v10 = {v8};
-  v9[{}] = {T<T>()};
-  Set<List<T<C>>> v11 = v10;
-  v10 = v11;
-  T<Null>();
-  T<Null>.named();
-  T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
   T<List<List<List<List>>>>.staticMethod<T<int>>();
+  //                        ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_class_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_class_test.dart
index 1501dad..85ab43d 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_class_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_class_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -49,9 +46,7 @@
 }
 
 class D1<X> extends T<X> {}
-abstract class D2 extends C with T<int> {}
 abstract class D3<X, Y> implements T<T> {}
-abstract class D4 = C with T<void>;
 
 extension E on T<dynamic> {
   T<dynamic> foo(T<dynamic> t) => t;
@@ -72,5 +67,5 @@
   T<Null>.named();
   T<Object> v12 = foo<T<bool>>(T<bool>());
   id(v12);
-  T<List<List<List<List>>>>.staticMethod<T<int>>();
+  T.staticMethod<T<int>>();
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_dynamic_error_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_dynamic_error_test.dart
index 66c0903..fd700d0 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_dynamic_error_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_dynamic_error_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -15,56 +12,61 @@
 
 // Use the aliased type.
 
-T<int> v1;
-List<T<void>> v2 = [];
-final T<String> v3 = throw "Anything";
-const List<T<C>> v4 = [];
-const v5 = <Type, Type>{T: T};
-
 abstract class C {
-  static T<C> v1;
-  static List<T<T>> v2 = [];
-  static final T<Null> v3 = throw "Anything";
-  static const List<T<List>> v4 = [];
-
-  T<C> v5;
-  List<T<T>> v6 = [];
   final T<Null> v7;
 
   C(): v7 = T();
-  C.name1(this.v5, this.v7);
-  factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
-
-  T<double> operator +(T<double> other);
-  T<FutureOr<FutureOr<void>>> get g;
-  set g(T<FutureOr<FutureOr<void>>> value);
-  Map<T<C>, T<C>> m1(covariant T<C> arg1, [Set<Set<T<C>>> arg2]);
-  void m2({T arg1, Map<T, T> arg2(T Function(T) arg21, T arg22)});
+  //        ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
 }
 
 class D1<X> extends T<X> {}
-abstract class D2 extends C with T<int> {}
-abstract class D3<X, Y> implements T<T> {}
-abstract class D4 = C with T<void>;
+//    ^
+// [analyzer] unspecified
+// [cfe] unspecified
 
-extension E on T<dynamic> {
-  T<dynamic> foo(T<dynamic> t) => t;
-}
+abstract class D2 extends C with T<int> {}
+//             ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D3<X, Y> implements T<T> {}
+//             ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D4 = C with T<void>;
+//             ^
+// [analyzer] unspecified
+// [cfe] unspecified
 
 X foo<X>(X x) => x;
 
-T<Type> Function(T<Type>) id;
-
 main() {
-  var v8 = <T<C>>[];
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
-  var v10 = {v8};
   v9[{}] = {T<T>()};
-  Set<List<T<C>>> v11 = v10;
-  v10 = v11;
+  //        ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T<Null>();
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
   T<Null>.named();
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
   T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
+  //                           ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T<List<List<List<List>>>>.staticMethod<T<int>>();
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_dynamic_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_dynamic_test.dart
index 66c0903..f812ca2 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_dynamic_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_dynamic_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -31,7 +28,6 @@
   List<T<T>> v6 = [];
   final T<Null> v7;
 
-  C(): v7 = T();
   C.name1(this.v5, this.v7);
   factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
 
@@ -42,11 +38,6 @@
   void m2({T arg1, Map<T, T> arg2(T Function(T) arg21, T arg22)});
 }
 
-class D1<X> extends T<X> {}
-abstract class D2 extends C with T<int> {}
-abstract class D3<X, Y> implements T<T> {}
-abstract class D4 = C with T<void>;
-
 extension E on T<dynamic> {
   T<dynamic> foo(T<dynamic> t) => t;
 }
@@ -59,12 +50,7 @@
   var v8 = <T<C>>[];
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
   var v10 = {v8};
-  v9[{}] = {T<T>()};
+  v9[{}] = {};
   Set<List<T<C>>> v11 = v10;
   v10 = v11;
-  T<Null>();
-  T<Null>.named();
-  T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
-  T<List<List<List<List>>>>.staticMethod<T<int>>();
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_function_error_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_function_error_test.dart
index d167da5..9251d61 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_function_error_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_function_error_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -15,56 +12,41 @@
 
 // Use the aliased type.
 
-T<int> v1;
-List<T<void>> v2 = [];
-final T<String> v3 = throw "Anything";
-const List<T<C>> v4 = [];
-const v5 = <Type, Type>{T: T};
-
 abstract class C {
-  static T<C> v1;
-  static List<T<T>> v2 = [];
-  static final T<Null> v3 = throw "Anything";
-  static const List<T<List>> v4 = [];
-
-  T<C> v5;
-  List<T<T>> v6 = [];
   final T<Null> v7;
 
   C(): v7 = T();
-  C.name1(this.v5, this.v7);
-  factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
-
-  T<double> operator +(T<double> other);
-  T<FutureOr<FutureOr<void>>> get g;
-  set g(T<FutureOr<FutureOr<void>>> value);
-  Map<T<C>, T<C>> m1(covariant T<C> arg1, [Set<Set<T<C>>> arg2]);
-  void m2({T arg1, Map<T, T> arg2(T Function(T) arg21, T arg22)});
-}
-
-class D1<X> extends T<X> {}
-abstract class D2 extends C with T<int> {}
-abstract class D3<X, Y> implements T<T> {}
-abstract class D4 = C with T<void>;
-
-extension E on T<dynamic> {
-  T<dynamic> foo(T<dynamic> t) => t;
+  //        ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
 }
 
 X foo<X>(X x) => x;
 
-T<Type> Function(T<Type>) id;
-
 main() {
-  var v8 = <T<C>>[];
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
-  var v10 = {v8};
   v9[{}] = {T<T>()};
-  Set<List<T<C>>> v11 = v10;
-  v10 = v11;
+  //        ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T<Null>();
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
   T<Null>.named();
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
   T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
+  //                           ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T<List<List<List<List>>>>.staticMethod<T<int>>();
+  //                        ^^^^^^^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_function_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_function_test.dart
index d167da5..20049ea 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_function_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_function_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -31,7 +28,7 @@
   List<T<T>> v6 = [];
   final T<Null> v7;
 
-  C(): v7 = T();
+  C(): v7 = print;
   C.name1(this.v5, this.v7);
   factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
 
@@ -59,12 +56,7 @@
   var v8 = <T<C>>[];
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
   var v10 = {v8};
-  v9[{}] = {T<T>()};
+  v9[{}] = {};
   Set<List<T<C>>> v11 = v10;
   v10 = v11;
-  T<Null>();
-  T<Null>.named();
-  T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
-  T<List<List<List<List>>>>.staticMethod<T<int>>();
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_futureor_error_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_futureor_error_test.dart
index 123547f..fd5939c 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_futureor_error_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_futureor_error_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -15,56 +12,62 @@
 
 // Use the aliased type.
 
-T<int> v1;
-List<T<void>> v2 = [];
-final T<String> v3 = throw "Anything";
-const List<T<C>> v4 = [];
-const v5 = <Type, Type>{T: T};
-
 abstract class C {
-  static T<C> v1;
-  static List<T<T>> v2 = [];
-  static final T<Null> v3 = throw "Anything";
-  static const List<T<List>> v4 = [];
-
-  T<C> v5;
-  List<T<T>> v6 = [];
   final T<Null> v7;
 
   C(): v7 = T();
-  C.name1(this.v5, this.v7);
-  factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
-
-  T<double> operator +(T<double> other);
-  T<FutureOr<FutureOr<void>>> get g;
-  set g(T<FutureOr<FutureOr<void>>> value);
-  Map<T<C>, T<C>> m1(covariant T<C> arg1, [Set<Set<T<C>>> arg2]);
-  void m2({T arg1, Map<T, T> arg2(T Function(T) arg21, T arg22)});
+  //        ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
 }
 
 class D1<X> extends T<X> {}
-abstract class D2 extends C with T<int> {}
-abstract class D3<X, Y> implements T<T> {}
-abstract class D4 = C with T<void>;
+//                  ^
+// [analyzer] unspecified
+// [cfe] unspecified
 
-extension E on T<dynamic> {
-  T<dynamic> foo(T<dynamic> t) => t;
-}
+abstract class D2 extends C with T<int> {}
+//                               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D3<X, Y> implements T<T> {}
+//                                 ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D4 = C with T<void>;
+//                         ^
+// [analyzer] unspecified
+// [cfe] unspecified
 
 X foo<X>(X x) => x;
 
-T<Type> Function(T<Type>) id;
-
 main() {
-  var v8 = <T<C>>[];
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
-  var v10 = {v8};
   v9[{}] = {T<T>()};
-  Set<List<T<C>>> v11 = v10;
-  v10 = v11;
+  //        ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T<Null>();
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
   T<Null>.named();
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+
   T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
+  //                           ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T<List<List<List<List>>>>.staticMethod<T<int>>();
+  //                        ^^^^^^^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_futureor_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_futureor_test.dart
index 123547f..8b9f4e1 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_futureor_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_futureor_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -31,7 +28,7 @@
   List<T<T>> v6 = [];
   final T<Null> v7;
 
-  C(): v7 = T();
+  C(): v7 = null;
   C.name1(this.v5, this.v7);
   factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
 
@@ -42,11 +39,6 @@
   void m2({T arg1, Map<T, T> arg2(T Function(T) arg21, T arg22)});
 }
 
-class D1<X> extends T<X> {}
-abstract class D2 extends C with T<int> {}
-abstract class D3<X, Y> implements T<T> {}
-abstract class D4 = C with T<void>;
-
 extension E on T<dynamic> {
   T<dynamic> foo(T<dynamic> t) => t;
 }
@@ -59,12 +51,7 @@
   var v8 = <T<C>>[];
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
   var v10 = {v8};
-  v9[{}] = {T<T>()};
+  v9[{}] = {};
   Set<List<T<C>>> v11 = v10;
   v10 = v11;
-  T<Null>();
-  T<Null>.named();
-  T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
-  T<List<List<List<List>>>>.staticMethod<T<int>>();
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_null_error_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_null_error_test.dart
index ad52fe3..af1a1b7 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_null_error_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_null_error_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -15,56 +12,61 @@
 
 // Use the aliased type.
 
-T<int> v1;
-List<T<void>> v2 = [];
-final T<String> v3 = throw "Anything";
-const List<T<C>> v4 = [];
-const v5 = <Type, Type>{T: T};
-
 abstract class C {
-  static T<C> v1;
-  static List<T<T>> v2 = [];
-  static final T<Null> v3 = throw "Anything";
-  static const List<T<List>> v4 = [];
-
-  T<C> v5;
-  List<T<T>> v6 = [];
   final T<Null> v7;
 
   C(): v7 = T();
-  C.name1(this.v5, this.v7);
-  factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
-
-  T<double> operator +(T<double> other);
-  T<FutureOr<FutureOr<void>>> get g;
-  set g(T<FutureOr<FutureOr<void>>> value);
-  Map<T<C>, T<C>> m1(covariant T<C> arg1, [Set<Set<T<C>>> arg2]);
-  void m2({T arg1, Map<T, T> arg2(T Function(T) arg21, T arg22)});
+  //        ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
 }
 
 class D1<X> extends T<X> {}
-abstract class D2 extends C with T<int> {}
-abstract class D3<X, Y> implements T<T> {}
-abstract class D4 = C with T<void>;
+//                  ^
+// [analyzer] unspecified
+// [cfe] unspecified
 
-extension E on T<dynamic> {
-  T<dynamic> foo(T<dynamic> t) => t;
-}
+abstract class D2 extends C with T<int> {}
+//                               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D3<X, Y> implements T<T> {}
+//                                 ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D4 = C with T<void>;
+//                         ^
+// [analyzer] unspecified
+// [cfe] unspecified
 
 X foo<X>(X x) => x;
 
-T<Type> Function(T<Type>) id;
-
 main() {
-  var v8 = <T<C>>[];
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
-  var v10 = {v8};
   v9[{}] = {T<T>()};
-  Set<List<T<C>>> v11 = v10;
-  v10 = v11;
+  //        ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T<Null>();
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
   T<Null>.named();
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
   T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
+  //                           ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T<List<List<List<List>>>>.staticMethod<T<int>>();
+  //                        ^^^^^^^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_null_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_null_test.dart
index ad52fe3..48e8721 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_null_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_null_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -31,7 +28,7 @@
   List<T<T>> v6 = [];
   final T<Null> v7;
 
-  C(): v7 = T();
+  C(): v7 = null;
   C.name1(this.v5, this.v7);
   factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
 
@@ -42,11 +39,6 @@
   void m2({T arg1, Map<T, T> arg2(T Function(T) arg21, T arg22)});
 }
 
-class D1<X> extends T<X> {}
-abstract class D2 extends C with T<int> {}
-abstract class D3<X, Y> implements T<T> {}
-abstract class D4 = C with T<void>;
-
 extension E on T<dynamic> {
   T<dynamic> foo(T<dynamic> t) => t;
 }
@@ -59,12 +51,7 @@
   var v8 = <T<C>>[];
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
   var v10 = {v8};
-  v9[{}] = {T<T>()};
+  v9[{}] = {};
   Set<List<T<C>>> v11 = v10;
   v10 = v11;
-  T<Null>();
-  T<Null>.named();
-  T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
-  T<List<List<List<List>>>>.staticMethod<T<int>>();
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_object_error_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_object_error_test.dart
index 1947781..9e72a9e 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_object_error_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_object_error_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -15,56 +12,26 @@
 
 // Use the aliased type.
 
-T<int> v1;
-List<T<void>> v2 = [];
-final T<String> v3 = throw "Anything";
-const List<T<C>> v4 = [];
-const v5 = <Type, Type>{T: T};
+abstract class C {}
 
-abstract class C {
-  static T<C> v1;
-  static List<T<T>> v2 = [];
-  static final T<Null> v3 = throw "Anything";
-  static const List<T<List>> v4 = [];
-
-  T<C> v5;
-  List<T<T>> v6 = [];
-  final T<Null> v7;
-
-  C(): v7 = T();
-  C.name1(this.v5, this.v7);
-  factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
-
-  T<double> operator +(T<double> other);
-  T<FutureOr<FutureOr<void>>> get g;
-  set g(T<FutureOr<FutureOr<void>>> value);
-  Map<T<C>, T<C>> m1(covariant T<C> arg1, [Set<Set<T<C>>> arg2]);
-  void m2({T arg1, Map<T, T> arg2(T Function(T) arg21, T arg22)});
-}
-
-class D1<X> extends T<X> {}
 abstract class D2 extends C with T<int> {}
-abstract class D3<X, Y> implements T<T> {}
+//                               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
 abstract class D4 = C with T<void>;
-
-extension E on T<dynamic> {
-  T<dynamic> foo(T<dynamic> t) => t;
-}
-
-X foo<X>(X x) => x;
-
-T<Type> Function(T<Type>) id;
+//                         ^
+// [analyzer] unspecified
+// [cfe] unspecified
 
 main() {
-  var v8 = <T<C>>[];
-  var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
-  var v10 = {v8};
-  v9[{}] = {T<T>()};
-  Set<List<T<C>>> v11 = v10;
-  v10 = v11;
-  T<Null>();
   T<Null>.named();
-  T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
+  //      ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T<List<List<List<List>>>>.staticMethod<T<int>>();
+  //                        ^^^^^^^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_object_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_object_test.dart
index 1947781..71a3461 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_object_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_object_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -22,17 +19,17 @@
 const v5 = <Type, Type>{T: T};
 
 abstract class C {
-  static T<C> v1;
-  static List<T<T>> v2 = [];
-  static final T<Null> v3 = throw "Anything";
-  static const List<T<List>> v4 = [];
+  static T<C> v6;
+  static List<T<T>> v7 = [];
+  static final T<Null> v8 = throw "Anything";
+  static const List<T<List>> v9 = [];
 
-  T<C> v5;
-  List<T<T>> v6 = [];
-  final T<Null> v7;
+  T<C> v10;
+  List<T<T>> v11 = [];
+  final T<Null> v12;
 
-  C(): v7 = T();
-  C.name1(this.v5, this.v7);
+  C(): v12 = T();
+  C.name1(this.v10, this.v12);
   factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
 
   T<double> operator +(T<double> other);
@@ -43,18 +40,17 @@
 }
 
 class D1<X> extends T<X> {}
-abstract class D2 extends C with T<int> {}
-abstract class D3<X, Y> implements T<T> {}
-abstract class D4 = C with T<void>;
+
+abstract class D3<X, Y> extends C implements T<T> {}
 
 extension E on T<dynamic> {
   T<dynamic> foo(T<dynamic> t) => t;
 }
 
-X foo<X>(X x) => x;
-
 T<Type> Function(T<Type>) id;
 
+X foo<X>(X x) => x;
+
 main() {
   var v8 = <T<C>>[];
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
@@ -63,8 +59,5 @@
   Set<List<T<C>>> v11 = v10;
   v10 = v11;
   T<Null>();
-  T<Null>.named();
   T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
-  T<List<List<List<List>>>>.staticMethod<T<int>>();
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_error_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_error_test.dart
index 139cad3..0075e3a 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_error_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_error_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -15,56 +12,61 @@
 
 // Use the aliased type.
 
-T<int> v1;
-List<T<void>> v2 = [];
-final T<String> v3 = throw "Anything";
-const List<T<C>> v4 = [];
-const v5 = <Type, Type>{T: T};
-
 abstract class C {
-  static T<C> v1;
-  static List<T<T>> v2 = [];
-  static final T<Null> v3 = throw "Anything";
-  static const List<T<List>> v4 = [];
-
-  T<C> v5;
-  List<T<T>> v6 = [];
   final T<Null> v7;
 
   C(): v7 = T();
-  C.name1(this.v5, this.v7);
-  factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
-
-  T<double> operator +(T<double> other);
-  T<FutureOr<FutureOr<void>>> get g;
-  set g(T<FutureOr<FutureOr<void>>> value);
-  Map<T<C>, T<C>> m1(covariant T<C> arg1, [Set<Set<T<C>>> arg2]);
-  void m2({T arg1, Map<T, T> arg2(T Function(T) arg21, T arg22)});
+  //        ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
 }
 
 class D1<X> extends T<X> {}
-abstract class D2 extends C with T<int> {}
-abstract class D3<X, Y> implements T<T> {}
-abstract class D4 = C with T<void>;
+//                  ^
+// [analyzer] unspecified
+// [cfe] unspecified
 
-extension E on T<dynamic> {
-  T<dynamic> foo(T<dynamic> t) => t;
-}
+abstract class D2 extends C with T<int> {}
+//                               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D3<X, Y> implements T<T> {}
+//                                 ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
+abstract class D4 = C with T<void>;
+//                         ^
+// [analyzer] unspecified
+// [cfe] unspecified
 
 X foo<X>(X x) => x;
 
-T<Type> Function(T<Type>) id;
-
 main() {
-  var v8 = <T<C>>[];
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
-  var v10 = {v8};
   v9[{}] = {T<T>()};
-  Set<List<T<C>>> v11 = v10;
-  v10 = v11;
+  //        ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T<Null>();
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
   T<Null>.named();
+  //      ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
+  //                           ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T<List<List<List<List>>>>.staticMethod<T<int>>();
+  //                        ^^^^^^^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_test.dart
index 139cad3..beb3a06 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_type_variable_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -27,13 +24,13 @@
   static final T<Null> v3 = throw "Anything";
   static const List<T<List>> v4 = [];
 
-  T<C> v5;
+  T<D> v5;
   List<T<T>> v6 = [];
   final T<Null> v7;
 
-  C(): v7 = T();
+  C(): v7 = T<D>();
   C.name1(this.v5, this.v7);
-  factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
+  factory C.name2(T<D> arg1, T<Null> arg2) = C.name1;
 
   T<double> operator +(T<double> other);
   T<FutureOr<FutureOr<void>>> get g;
@@ -42,29 +39,25 @@
   void m2({T arg1, Map<T, T> arg2(T Function(T) arg21, T arg22)});
 }
 
-class D1<X> extends T<X> {}
-abstract class D2 extends C with T<int> {}
-abstract class D3<X, Y> implements T<T> {}
-abstract class D4 = C with T<void>;
+class D {}
+mixin M {}
+
+abstract class D1<X> extends T<D> {}
+abstract class D2 extends C with T<M> {}
+abstract class D3<X, Y> implements T<T<D>> {}
+abstract class D4 = C with T<D>;
 
 extension E on T<dynamic> {
   T<dynamic> foo(T<dynamic> t) => t;
 }
 
-X foo<X>(X x) => x;
-
-T<Type> Function(T<Type>) id;
-
 main() {
   var v8 = <T<C>>[];
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
   var v10 = {v8};
-  v9[{}] = {T<T>()};
+  v9[{}] = {T<D>()};
   Set<List<T<C>>> v11 = v10;
   v10 = v11;
-  T<Null>();
-  T<Null>.named();
-  T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
-  T<List<List<List<List>>>>.staticMethod<T<int>>();
+  T<Object>();
+  T<C>.name1(D(), null);
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_void_error_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_void_error_test.dart
index ddcdcf7..1bddbc3 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_void_error_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_void_error_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -15,37 +12,34 @@
 
 // Use the aliased type.
 
-T<int> v1;
-List<T<void>> v2 = [];
-final T<String> v3 = throw "Anything";
-const List<T<C>> v4 = [];
-const v5 = <Type, Type>{T: T};
-
 abstract class C {
-  static T<C> v1;
-  static List<T<T>> v2 = [];
-  static final T<Null> v3 = throw "Anything";
-  static const List<T<List>> v4 = [];
-
-  T<C> v5;
-  List<T<T>> v6 = [];
   final T<Null> v7;
 
   C(): v7 = T();
-  C.name1(this.v5, this.v7);
-  factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
-
-  T<double> operator +(T<double> other);
-  T<FutureOr<FutureOr<void>>> get g;
-  set g(T<FutureOr<FutureOr<void>>> value);
-  Map<T<C>, T<C>> m1(covariant T<C> arg1, [Set<Set<T<C>>> arg2]);
-  void m2({T arg1, Map<T, T> arg2(T Function(T) arg21, T arg22)});
+  //        ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
 }
 
 class D1<X> extends T<X> {}
+//                  ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
 abstract class D2 extends C with T<int> {}
+//                               ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
 abstract class D3<X, Y> implements T<T> {}
+//                                 ^
+// [analyzer] unspecified
+// [cfe] unspecified
+
 abstract class D4 = C with T<void>;
+//                         ^
+// [analyzer] unspecified
+// [cfe] unspecified
 
 extension E on T<dynamic> {
   T<dynamic> foo(T<dynamic> t) => t;
@@ -53,18 +47,35 @@
 
 X foo<X>(X x) => x;
 
-T<Type> Function(T<Type>) id;
-
 main() {
   var v8 = <T<C>>[];
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
   var v10 = {v8};
   v9[{}] = {T<T>()};
+  //        ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   Set<List<T<C>>> v11 = v10;
   v10 = v11;
+
   T<Null>();
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
   T<Null>.named();
+//^
+// [analyzer] unspecified
+// [cfe] unspecified
+
   T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
+  //                           ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
   T<List<List<List<List>>>>.staticMethod<T<int>>();
+  //                        ^^^^^^^^^^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
 }
diff --git a/tests/language_2/nonfunction_type_aliases/generic_usage_void_test.dart b/tests/language_2/nonfunction_type_aliases/generic_usage_void_test.dart
index ddcdcf7..c867206 100644
--- a/tests/language_2/nonfunction_type_aliases/generic_usage_void_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/generic_usage_void_test.dart
@@ -4,9 +4,6 @@
 
 // SharedOptions=--enable-experiment=nonfunction-type-aliases
 
-// Test that a non-function type alias can be used as the denoted type in
-// many situations.
-
 import 'dart:async';
 
 // Introduce an aliased type.
@@ -31,7 +28,7 @@
   List<T<T>> v6 = [];
   final T<Null> v7;
 
-  C(): v7 = T();
+  C(): v7 = null;
   C.name1(this.v5, this.v7);
   factory C.name2(T<C> arg1, T<Null> arg2) = C.name1;
 
@@ -42,11 +39,6 @@
   void m2({T arg1, Map<T, T> arg2(T Function(T) arg21, T arg22)});
 }
 
-class D1<X> extends T<X> {}
-abstract class D2 extends C with T<int> {}
-abstract class D3<X, Y> implements T<T> {}
-abstract class D4 = C with T<void>;
-
 extension E on T<dynamic> {
   T<dynamic> foo(T<dynamic> t) => t;
 }
@@ -59,12 +51,7 @@
   var v8 = <T<C>>[];
   var v9 = <Set<T<T>>, Set<T<T>>>{{}: {}};
   var v10 = {v8};
-  v9[{}] = {T<T>()};
+  v9[{}] = {};
   Set<List<T<C>>> v11 = v10;
   v10 = v11;
-  T<Null>();
-  T<Null>.named();
-  T<Object> v12 = foo<T<bool>>(T<bool>());
-  id(v12);
-  T<List<List<List<List>>>>.staticMethod<T<int>>();
 }
diff --git a/tests/language_2/nonfunction_type_aliases/nnbd_syntax_test.dart b/tests/language_2/nonfunction_type_aliases/nnbd_syntax_test.dart
deleted file mode 100644
index 9939bb0..0000000
--- a/tests/language_2/nonfunction_type_aliases/nnbd_syntax_test.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// SharedOptions=--enable-experiment=nonfunction-type-aliases,non-nullable
-
-typedef T0 = Function?;
-typedef T1<X> = List<X?>?;
-typedef T2<X, Y> = Map<X?, Y?>?;
-typedef T3 = Never? Function(void)?;
-typedef T4<X> = X? Function(X?, {required X? name})?;
-typedef T5<X extends String, Y extends List<X?>> =
-    X? Function(Y?, [Map<Y, Y?>]);
-
-void main() {
-  // ignore:unused_local_variable
-  var ensure_usage = [T0, T1, T2, T3, T4, T5];
-}
diff --git a/tests/language_2/nonfunction_type_aliases/usage_type_variable_error_test.dart b/tests/language_2/nonfunction_type_aliases/usage_type_variable_error_test.dart
index e4257c7..08124c3 100644
--- a/tests/language_2/nonfunction_type_aliases/usage_type_variable_error_test.dart
+++ b/tests/language_2/nonfunction_type_aliases/usage_type_variable_error_test.dart
@@ -16,56 +16,14 @@
 
 // Use the aliased type.
 
-T v1;
-List<T> v2 = [];
-final T v3 = throw "Anything";
-const List<T> v4 = [];
-const v5 = <Type, Type>{T: T};
-
-abstract class C {
-  static T v6;
-  static List<T> v7 = [];
-  static final T v8 = throw "Anything";
-  static const List<T> v9 = [];
-
-  T v10;
-  List<T> v11 = [];
-  final T v12;
-
-  C(): v12 = T();
-  C.name1(this.v10, this.v12);
-  factory C.name2(T arg1, T arg2) = C.name1;
-
-  T operator +(T other);
-  T get g;
-  set g(T value);
-  Map<T, T> m1(covariant T arg1, [Set<Set<T>> arg2]);
-  void m2({T arg1, T arg2(T arg21, T arg22)});
-}
-
-class D1 extends T {}
-abstract class D2 extends C with T {}
-abstract class D3 implements T {}
-abstract class D4 = C with T;
-
-extension E on T {
-  T foo(T t) => t;
-}
-
-X foo<X>(X x) => x;
-
-T Function(T) id = (x) => x;
-
 main() {
-  var v13 = <T>[];
-  var v14 = <Set<T>, Set<T>>{{}: {}};
-  v14[{}] = {T()};
-  var v15 = {v13};
-  Set<List<T>> v16 = v15;
-  v15 = v16;
-  T();
-  T.named();
-  T v17 = foo<T>(T());
-  id(v17);
-  T.staticMethod<T>();
+  T().unknownInstanceMethod();
+  //  ^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+
+  T.unknownStaticMethod();
+//  ^
+// [analyzer] unspecified
+// [cfe] unspecified
 }
diff --git a/tests/language_2/type_object/first_class_types_literals_test.dart b/tests/language_2/type_object/first_class_types_literals_test.dart
index 77cf8b6..aa02a4d 100644
--- a/tests/language_2/type_object/first_class_types_literals_test.dart
+++ b/tests/language_2/type_object/first_class_types_literals_test.dart
@@ -52,13 +52,13 @@
   Expect.throwsNoSuchMethodError(() => C = 1);
   //                                   ^
   // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_TYPE
-  // [cfe] Setter not found: 'C'.
+  // [cfe] Can't assign to a type literal.
   //                                       ^
   // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
   Expect.throwsNoSuchMethodError(() => C++);
   //                                   ^
   // [analyzer] STATIC_WARNING.ASSIGNMENT_TO_TYPE
-  // [cfe] Setter not found: 'C'.
+  // [cfe] Can't assign to a type literal.
   //                                    ^^
   // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
   Expect.throwsNoSuchMethodError(() => C + 1);
@@ -75,12 +75,12 @@
   // [cfe] The operator '[]=' isn't defined for the class 'Type'.
   Expect.throwsNoSuchMethodError(() => dynamic = 1);
   //                                   ^
-  // [cfe] Setter not found: 'dynamic'.
+  // [cfe] Can't assign to a type literal.
   //                                             ^
   // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
   Expect.throwsNoSuchMethodError(() => dynamic++);
   //                                   ^
-  // [cfe] Setter not found: 'dynamic'.
+  // [cfe] Can't assign to a type literal.
   //                                          ^^
   // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_OPERATOR
   Expect.throwsNoSuchMethodError(() => dynamic + 1);
diff --git a/tests/lib/async/catch_errors.dart b/tests/lib/async/catch_errors.dart
index c684cf9..ff9260d 100644
--- a/tests/lib/async/catch_errors.dart
+++ b/tests/lib/async/catch_errors.dart
@@ -11,7 +11,7 @@
   }
 
   void onListen() {
-    runZoned(body, onError: onError);
+    runZonedGuarded(body, onError);
   }
 
   controller = new StreamController(onListen: onListen);
@@ -21,7 +21,7 @@
 runZonedScheduleMicrotask(body(),
     {void onScheduleMicrotask(void callback()), Function? onError}) {
   if (onScheduleMicrotask == null) {
-    return runZoned(body, onError: onError);
+    return runZonedGuarded(body, onError);
   }
   HandleUncaughtErrorHandler errorHandler;
   if (onError != null) {
diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart
index 790b1bd..c38da0f 100644
--- a/tests/lib/async/future_test.dart
+++ b/tests/lib/async/future_test.dart
@@ -868,7 +868,7 @@
   asyncStart();
   asyncStart();
   asyncStart();
-  runZoned(() {
+  runZonedGuarded(() {
     Future.wait([
       new Future.delayed(cms, () => 0),
       new Future.delayed(cms * 2, () => throw 1),
@@ -882,7 +882,7 @@
       Expect.equals(e, 1);
       asyncEnd();
     });
-  }, onError: (e, s) {
+  }, (e, s) {
     int index = e;
     Expect.isTrue(index == 0 || index == 2, "$index");
     Expect.isFalse(uncaughts[index]);
diff --git a/tests/lib/async/run_zoned4_test.dart b/tests/lib/async/run_zoned4_test.dart
index 9df955e..fb5166a 100644
--- a/tests/lib/async/run_zoned4_test.dart
+++ b/tests/lib/async/run_zoned4_test.dart
@@ -10,7 +10,7 @@
   // error handler is defined.
   Expect.equals(
       499,
-      runZoned(() => 499, onError: (e) {
+      runZonedGuarded(() => 499, (e, s) {
         throw "Unexpected";
       }));
 }
diff --git a/tests/lib/async/run_zoned5_test.dart b/tests/lib/async/run_zoned5_test.dart
index 7a7da9e..0787fd5 100644
--- a/tests/lib/async/run_zoned5_test.dart
+++ b/tests/lib/async/run_zoned5_test.dart
@@ -9,9 +9,9 @@
 main() {
   asyncStart();
   // Ensure that `runZoned`'s onError handles synchronous errors.
-  runZoned(() {
+  runZonedGuarded(() {
     throw 0;
-  }, onError: (e) {
+  }, (e, s) {
     Expect.equals(0, e);
     asyncEnd();
   });
diff --git a/tests/lib/async/run_zoned6_test.dart b/tests/lib/async/run_zoned6_test.dart
index 906c776..837e6f1 100644
--- a/tests/lib/async/run_zoned6_test.dart
+++ b/tests/lib/async/run_zoned6_test.dart
@@ -12,9 +12,9 @@
   // in the error handler at that point (when it is a synchronous error) yields
   // a synchronous error.
   try {
-    runZoned(() {
+    runZonedGuarded(() {
       throw 0;
-    }, onError: (e) {
+    }, (e, s) {
       Expect.equals(0, e);
       throw e;  //#01 : ok
       asyncEnd();
diff --git a/tests/lib/async/run_zoned8_test.dart b/tests/lib/async/run_zoned8_test.dart
index fca3989..9a6b917 100644
--- a/tests/lib/async/run_zoned8_test.dart
+++ b/tests/lib/async/run_zoned8_test.dart
@@ -13,7 +13,7 @@
 
   var events = [];
   // Test runZoned with periodic Timers.
-  runZoned(() {
+  runZonedGuarded(() {
     int counter = 0;
     new Timer.periodic(const Duration(milliseconds: 50), (timer) {
       if (counter == 1) {
@@ -24,7 +24,7 @@
       events.add(counter);
       throw counter;
     });
-  }, onError: (e, [s]) {
+  }, (e, [s]) {
     events.add("error: $e");
     Expect.isNotNull(s); // Regression test for http://dartbug.com/33589
   });
diff --git a/tests/lib/async/run_zoned9_test.dart b/tests/lib/async/run_zoned9_test.dart
index 1ab9795..a42b8df 100644
--- a/tests/lib/async/run_zoned9_test.dart
+++ b/tests/lib/async/run_zoned9_test.dart
@@ -12,15 +12,15 @@
   // to the next runZoned when the handler returns false.
   bool sawInnerHandler = false;
   try {
-    runZoned(() {
+    runZonedGuarded(() {
       runZoned(() {
         throw 0;
-      }, onError: (e) {
+      }, onError: (e, s) {
         Expect.equals(0, e);
         sawInnerHandler = true;
         throw e;
       });
-    }, onError: (e) {
+    }, (e, s) {
       Expect.equals(0, e);
       Expect.isTrue(sawInnerHandler);
       // If we are waiting for an error, don't asyncEnd, but let it time out.
diff --git a/tests/lib/async/stream_event_transformed_test.dart b/tests/lib/async/stream_event_transformed_test.dart
index a132aad..73de60e 100644
--- a/tests/lib/async/stream_event_transformed_test.dart
+++ b/tests/lib/async/stream_event_transformed_test.dart
@@ -267,7 +267,7 @@
 
     bool streamIsDone = false;
     int errorCount = 0;
-    runZoned(() {
+    runZonedGuarded(() {
       controller.stream
           .transform(new SinkTransformer((sink) =>
               new FutureWaitingTransformerSink(sink, closeCompleter.future)))
@@ -280,7 +280,7 @@
         Expect.listEquals([], events);
         streamIsDone = true;
       });
-    }, onError: (e) {
+    }, (e, s) {
       Expect.isTrue(e is StateError);
       errorCount++;
     });
diff --git a/tests/lib/async/stream_subscription_as_future_test.dart b/tests/lib/async/stream_subscription_as_future_test.dart
index d12c0ac..48309e3 100644
--- a/tests/lib/async/stream_subscription_as_future_test.dart
+++ b/tests/lib/async/stream_subscription_as_future_test.dart
@@ -114,7 +114,7 @@
   });
 
   test("subscription.asFuture failure in cancel", () {
-    runZoned(() {
+    runZonedGuarded(() {
       var completer = new Completer();
       var controller =
           new StreamController(onCancel: () => completer.future, sync: true);
@@ -135,7 +135,7 @@
         Expect.isFalse(catchErrorHasRun);
         completer.completeError(499);
       }));
-    }, onError: expectAsync((e) {
+    }, expectAsync2((e, s) {
       Expect.equals(499, e);
     }));
   });
diff --git a/tests/lib/async/stream_zones_test.dart b/tests/lib/async/stream_zones_test.dart
index 6d4582e..3a41e12 100644
--- a/tests/lib/async/stream_zones_test.dart
+++ b/tests/lib/async/stream_zones_test.dart
@@ -10,8 +10,8 @@
 test1() {
   var events = [];
   var done = new Completer();
-  runZoned(() {
-    runZoned(() {
+  runZonedGuarded(() {
+    runZonedGuarded(() {
       var c = new StreamController();
       c.stream.listen((x) => events.add("stream: $x"),
           onError: (x) => events.add("stream: error $x"),
@@ -19,8 +19,8 @@
       c.add(1);
       c.addError(2);
       c.close();
-    }, onError: (x) => events.add("rza: error $x"));
-  }, onError: (x) => events.add("rzb: error $x"));
+    }, (e, s) => events.add("rza: error $e"));
+  }, (e, s) => events.add("rzb: error $e"));
   return [
     done.future,
     () {
@@ -33,18 +33,18 @@
 test2() {
   var events = [];
   var done = new Completer();
-  runZoned(() {
+  runZonedGuarded(() {
     var c;
-    runZoned(() {
+    runZonedGuarded(() {
       c = new StreamController();
       c.stream.listen((x) => events.add("stream: $x"),
           onError: (x) => events.add("stream: error $x"),
           onDone: done.complete);
-    }, onError: (x) => events.add("rza: error $x"));
+    }, (e, s) => events.add("rza: error $e"));
     c.add(1);
     c.addError(2);
     c.close();
-  }, onError: (x) => events.add("rzb: error $x"));
+  }, (e, s) => events.add("rzb: error $e"));
   return [
     done.future,
     () {
@@ -57,16 +57,16 @@
 test3() {
   var events = [];
   var done = new Completer();
-  runZoned(() {
+  runZonedGuarded(() {
     var c = new StreamController();
     c.stream.listen((x) => events.add("stream: $x"),
         onError: (x) => events.add("stream: error $x"), onDone: done.complete);
-    runZoned(() {
+    runZonedGuarded(() {
       c.add(1);
       c.addError(2);
       c.close();
-    }, onError: (x) => events.add("rza: error $x"));
-  }, onError: (x) => events.add("rzb: error $x"));
+    }, (e, s) => events.add("rza: error $e"));
+  }, (e, s) => events.add("rzb: error $e"));
   return [
     done.future,
     () {
@@ -79,18 +79,18 @@
 test4() {
   var events = [];
   var done = new Completer();
-  runZoned(() {
+  runZonedGuarded(() {
     var c = new StreamController();
     c.stream.listen((x) => events.add("stream: $x"),
         onError: (x) => events.add("stream: error $x"), onDone: done.complete);
-    runZoned(() {
+    runZonedGuarded(() {
       var c2 = new StreamController();
       c.addStream(c2.stream).whenComplete(c.close);
       c2.add(1);
       c2.addError(2);
       c2.close();
-    }, onError: (x) => events.add("rza: error $x"));
-  }, onError: (x) => events.add("rzb: error $x"));
+    }, (e, s) => events.add("rza: error $e"));
+  }, (e, s) => events.add("rzb: error $e"));
   return [
     done.future,
     () {
@@ -104,20 +104,20 @@
 test5() {
   var events = [];
   var done = new Completer();
-  runZoned(() {
+  runZonedGuarded(() {
     var c;
-    runZoned(() {
+    runZonedGuarded(() {
       c = new StreamController();
       c.stream.listen((x) => events.add("stream: $x"),
           onError: (x) => events.add("stream: error $x"),
           onDone: done.complete);
-    }, onError: (x) => events.add("rza: error $x"));
+    }, (e, s) => events.add("rza: error $e"));
     var c2 = new StreamController();
     c.addStream(c2.stream).whenComplete(c.close);
     c2.add(1);
     c2.addError(2);
     c2.close();
-  }, onError: (x) => events.add("rzb: error $x"));
+  }, (e, s) => events.add("rzb: error $e"));
   return [
     done.future,
     () {
@@ -130,18 +130,18 @@
   var events = [];
   var done = new Completer();
   var c;
-  runZoned(() {
+  runZonedGuarded(() {
     c = new StreamController();
     c.stream.listen((x) => events.add("stream: $x"),
         onError: (x) => events.add("stream: error $x"), onDone: done.complete);
-  }, onError: (x) => events.add("rza: error $x"));
-  runZoned(() {
+  }, (e, s) => events.add("rza: error $e"));
+  runZonedGuarded(() {
     var c2 = new StreamController();
     c.addStream(c2.stream).whenComplete(c.close);
     c2.add(1);
     c2.addError(2);
     c2.close();
-  }, onError: (x) => events.add("rzb: error $x"));
+  }, (e, s) => events.add("rzb: error $e, s"));
   return [
     done.future,
     () {
@@ -155,16 +155,16 @@
   var events = [];
   var done = new Completer();
   var c;
-  runZoned(() {
+  runZonedGuarded(() {
     c = new StreamController();
     c.stream.listen((x) => events.add("stream: $x"),
         onError: (x) => events.add("stream: error $x"), onDone: done.complete);
-  }, onError: (x) => events.add("rza: error $x"));
-  runZoned(() {
+  }, (e, s) => events.add("rza: error $e"));
+  runZonedGuarded(() {
     c.add(1);
     c.addError(2);
     c.close();
-  }, onError: (x) => events.add("rzb: error $x"));
+  }, (e, s) => events.add("rzb: error $e"));
   return [
     done.future,
     () {
diff --git a/tests/lib/isolate/appjit_serialization_regression_test.dart b/tests/lib/isolate/appjit_serialization_regression_test.dart
new file mode 100644
index 0000000..e359e9f
--- /dev/null
+++ b/tests/lib/isolate/appjit_serialization_regression_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:isolate';
+
+main() {
+  // The SendPorts should not be serialized.
+  var port = new RawReceivePort();
+  Isolate.current.addErrorListener(port.sendPort);
+  Isolate.current.addOnExitListener(port.sendPort);
+  port.close();
+}
diff --git a/tests/lib/lib_dart2js.status b/tests/lib/lib_dart2js.status
index 360147c..14a0a1a 100644
--- a/tests/lib/lib_dart2js.status
+++ b/tests/lib/lib_dart2js.status
@@ -11,7 +11,7 @@
 html/custom/document_register_basic_test: Slow, Pass
 html/custom/document_register_type_extensions_test/construction: Slow, Pass
 html/custom/document_register_type_extensions_test/registration: Slow, Pass
-html/custom/entered_left_view_test/shadow_dom: Slow, Pass
+html/custom/entered_left_view/shadow_dom_test: Slow, Pass
 html/custom/js_custom_test: Skip # mirrors not supported, delete this test.
 html/custom/mirrors_2_test: Skip # mirrors not supported, delete this test.
 html/custom/mirrors_test: Skip # mirrors not supported, delete this test.
@@ -23,9 +23,6 @@
 html/xhr_test: Slow, Pass
 isolate/*: SkipByDesign # No support for dart:isolate in dart4web (http://dartbug.com/30538)
 mirrors/*: SkipByDesign # Mirrors not supported on web in Dart 2.0.
-typed_data/int64_list_load_store_test: SkipByDesign # dart2js does not support Int64List
-typed_data/typed_data_hierarchy_int64_test: SkipByDesign # dart2js does not support Int64List
-typed_data/unmodifiable_typed_data_test: SkipByDesign # dart2js does not support Int64List
 wasm/*: SkipByDesign # dart:wasm not currently supported on web.
 
 [ $compiler != dart2js ]
@@ -42,7 +39,7 @@
 html/input_element_datetime_test: Slow, Pass # TODO(dart2js-team): Please triage this failure.
 
 [ $compiler == dart2js && $runtime == d8 ]
-html/event_callback_test: Skip # Browser test
+html/*: SkipByDesign # Browser test
 
 [ $compiler == dart2js && $runtime == ff ]
 async/slow_consumer2_test: SkipSlow # Times out. Issue 22050
@@ -58,7 +55,7 @@
 html/file_sample_test: Skip # FileSystem not supported on FireFox.
 html/fileapi_supported_test: Skip # FileSystem not supported on FireFox.
 html/fileapi_supported_throws_test: Skip # FileSystem not supported on FireFox.
-html/history_test/history: Skip # Issue 22050
+html/history_test: Skip # Issue 22050
 html/request_animation_frame_test: Skip # Async test hangs.
 
 [ $compiler == dart2js && $runtime == safari ]
@@ -72,14 +69,14 @@
 
 [ $compiler == dart2js && $checked ]
 convert/utf85_test: Slow, Pass # Issue 12029.
-html/js_function_getter_trust_types_test: Skip # --trust-type-annotations incompatible with --checked
+html/js_function_getter_trust_types/function_test: Skip # --trust-type-annotations incompatible with --checked
 
 [ $compiler == dart2js && $csp && ($runtime == chrome || $runtime == chromeOnAndroid || $runtime == ff || $runtime == safari) ]
 html/event_customevent_test: SkipByDesign
 html/js_array_test: SkipByDesign
 html/js_dart_to_string_test: SkipByDesign
 html/js_function_getter_test: SkipByDesign
-html/js_function_getter_trust_types_test: SkipByDesign
+html/js_function_getter_trust_types/function_test: SkipByDesign
 html/js_interop_1_test: SkipByDesign
 html/js_typed_interop_bind_this_test: SkipByDesign
 html/js_typed_interop_callable_object_test: SkipByDesign
diff --git a/tests/lib/lib_dartdevc.status b/tests/lib/lib_dartdevc.status
index 4264211..61d487d 100644
--- a/tests/lib/lib_dartdevc.status
+++ b/tests/lib/lib_dartdevc.status
@@ -29,16 +29,9 @@
 html/custom/created_callback_test: Skip # Issue 31577
 html/custom/document_register_basic_test: Skip # Issue 31577
 html/custom/document_register_template_test: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/construction: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/constructors: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/createElement with type extension: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/functional: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/namespaces: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/parsing: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/registration: Skip # Issue 31577
-html/custom/document_register_type_extensions_test/single-parameter createElement: Skip # Issue 31577
+html/custom/document_register_type_extensions_test: Skip # Issue 31577
 html/custom/element_upgrade_test: Skip # Issue 31577
-html/custom/entered_left_view_test: Skip # Issue 31577
+html/custom/entered_left_view/*: Skip # Issue 31577
 html/custom/mirrors_2_test: Skip # Issue 31577
 html/custom_element_method_clash_test: Skip # Issue 29922
 html/custom_element_name_clash_test: Skip # Issue 29922
diff --git a/tests/lib_2/async/run_zoned4_test.dart b/tests/lib_2/async/run_zoned4_test.dart
index 9df955e..fb5166a 100644
--- a/tests/lib_2/async/run_zoned4_test.dart
+++ b/tests/lib_2/async/run_zoned4_test.dart
@@ -10,7 +10,7 @@
   // error handler is defined.
   Expect.equals(
       499,
-      runZoned(() => 499, onError: (e) {
+      runZonedGuarded(() => 499, (e, s) {
         throw "Unexpected";
       }));
 }
diff --git a/tests/lib_2/async/run_zoned5_test.dart b/tests/lib_2/async/run_zoned5_test.dart
index 7a7da9e..0787fd5 100644
--- a/tests/lib_2/async/run_zoned5_test.dart
+++ b/tests/lib_2/async/run_zoned5_test.dart
@@ -9,9 +9,9 @@
 main() {
   asyncStart();
   // Ensure that `runZoned`'s onError handles synchronous errors.
-  runZoned(() {
+  runZonedGuarded(() {
     throw 0;
-  }, onError: (e) {
+  }, (e, s) {
     Expect.equals(0, e);
     asyncEnd();
   });
diff --git a/tests/lib_2/async/run_zoned6_test.dart b/tests/lib_2/async/run_zoned6_test.dart
index 906c776..837e6f1 100644
--- a/tests/lib_2/async/run_zoned6_test.dart
+++ b/tests/lib_2/async/run_zoned6_test.dart
@@ -12,9 +12,9 @@
   // in the error handler at that point (when it is a synchronous error) yields
   // a synchronous error.
   try {
-    runZoned(() {
+    runZonedGuarded(() {
       throw 0;
-    }, onError: (e) {
+    }, (e, s) {
       Expect.equals(0, e);
       throw e;  //#01 : ok
       asyncEnd();
diff --git a/tests/lib_2/async/run_zoned9_test.dart b/tests/lib_2/async/run_zoned9_test.dart
index 1ab9795..be96ac8 100644
--- a/tests/lib_2/async/run_zoned9_test.dart
+++ b/tests/lib_2/async/run_zoned9_test.dart
@@ -12,15 +12,15 @@
   // to the next runZoned when the handler returns false.
   bool sawInnerHandler = false;
   try {
-    runZoned(() {
-      runZoned(() {
+    runZonedGuarded(() {
+      runZonedGuarded(() {
         throw 0;
-      }, onError: (e) {
+      }, (e, s) {
         Expect.equals(0, e);
         sawInnerHandler = true;
         throw e;
       });
-    }, onError: (e) {
+    }, (e, s) {
       Expect.equals(0, e);
       Expect.isTrue(sawInnerHandler);
       // If we are waiting for an error, don't asyncEnd, but let it time out.
diff --git a/tests/lib_2/async/stream_event_transformed_test.dart b/tests/lib_2/async/stream_event_transformed_test.dart
index 2a05683..2b22fad 100644
--- a/tests/lib_2/async/stream_event_transformed_test.dart
+++ b/tests/lib_2/async/stream_event_transformed_test.dart
@@ -267,7 +267,7 @@
 
     bool streamIsDone = false;
     int errorCount = 0;
-    runZoned(() {
+    runZonedGuarded(() {
       controller.stream
           .transform(new SinkTransformer((sink) =>
               new FutureWaitingTransformerSink(sink, closeCompleter.future)))
@@ -280,7 +280,7 @@
         Expect.listEquals([], events);
         streamIsDone = true;
       });
-    }, onError: (e) {
+    }, (e, s) {
       Expect.isTrue(e is StateError);
       errorCount++;
     });
diff --git a/tests/lib_2/async/stream_subscription_as_future_test.dart b/tests/lib_2/async/stream_subscription_as_future_test.dart
index 5be5c91..55f2c29 100644
--- a/tests/lib_2/async/stream_subscription_as_future_test.dart
+++ b/tests/lib_2/async/stream_subscription_as_future_test.dart
@@ -114,7 +114,7 @@
   });
 
   test("subscription.asFuture failure in cancel", () {
-    runZoned(() {
+    runZonedGuarded(() {
       var completer = new Completer();
       var controller =
           new StreamController(onCancel: () => completer.future, sync: true);
@@ -135,7 +135,7 @@
         Expect.isFalse(catchErrorHasRun);
         completer.completeError(499);
       }));
-    }, onError: expectAsync((e) {
+    }, expectAsync2((e, s) {
       Expect.equals(499, e);
     }));
   });
diff --git a/tests/lib_2/async/stream_zones_test.dart b/tests/lib_2/async/stream_zones_test.dart
index 6d4582e..9f382ba 100644
--- a/tests/lib_2/async/stream_zones_test.dart
+++ b/tests/lib_2/async/stream_zones_test.dart
@@ -10,8 +10,8 @@
 test1() {
   var events = [];
   var done = new Completer();
-  runZoned(() {
-    runZoned(() {
+  runZonedGuarded(() {
+    runZonedGuarded(() {
       var c = new StreamController();
       c.stream.listen((x) => events.add("stream: $x"),
           onError: (x) => events.add("stream: error $x"),
@@ -19,8 +19,8 @@
       c.add(1);
       c.addError(2);
       c.close();
-    }, onError: (x) => events.add("rza: error $x"));
-  }, onError: (x) => events.add("rzb: error $x"));
+    }, (e, s) => events.add("rza: error $e"));
+  }, (e, s) => events.add("rzb: error $e"));
   return [
     done.future,
     () {
@@ -33,18 +33,18 @@
 test2() {
   var events = [];
   var done = new Completer();
-  runZoned(() {
+  runZonedGuarded(() {
     var c;
-    runZoned(() {
+    runZonedGuarded(() {
       c = new StreamController();
       c.stream.listen((x) => events.add("stream: $x"),
           onError: (x) => events.add("stream: error $x"),
           onDone: done.complete);
-    }, onError: (x) => events.add("rza: error $x"));
+    }, (e, s) => events.add("rza: error $e"));
     c.add(1);
     c.addError(2);
     c.close();
-  }, onError: (x) => events.add("rzb: error $x"));
+  }, (e, s) => events.add("rzb: error $e"));
   return [
     done.future,
     () {
@@ -57,16 +57,16 @@
 test3() {
   var events = [];
   var done = new Completer();
-  runZoned(() {
+  runZonedGuarded(() {
     var c = new StreamController();
     c.stream.listen((x) => events.add("stream: $x"),
         onError: (x) => events.add("stream: error $x"), onDone: done.complete);
-    runZoned(() {
+    runZonedGuarded(() {
       c.add(1);
       c.addError(2);
       c.close();
-    }, onError: (x) => events.add("rza: error $x"));
-  }, onError: (x) => events.add("rzb: error $x"));
+    }, (e, s) => events.add("rza: error $e"));
+  }, (e, s) => events.add("rzb: error $e"));
   return [
     done.future,
     () {
@@ -79,18 +79,18 @@
 test4() {
   var events = [];
   var done = new Completer();
-  runZoned(() {
+  runZonedGuarded(() {
     var c = new StreamController();
     c.stream.listen((x) => events.add("stream: $x"),
         onError: (x) => events.add("stream: error $x"), onDone: done.complete);
-    runZoned(() {
+    runZonedGuarded(() {
       var c2 = new StreamController();
       c.addStream(c2.stream).whenComplete(c.close);
       c2.add(1);
       c2.addError(2);
       c2.close();
-    }, onError: (x) => events.add("rza: error $x"));
-  }, onError: (x) => events.add("rzb: error $x"));
+    }, (e, s) => events.add("rza: error $e"));
+  }, (e, s) => events.add("rzb: error $e"));
   return [
     done.future,
     () {
@@ -104,20 +104,20 @@
 test5() {
   var events = [];
   var done = new Completer();
-  runZoned(() {
+  runZonedGuarded(() {
     var c;
-    runZoned(() {
+    runZonedGuarded(() {
       c = new StreamController();
       c.stream.listen((x) => events.add("stream: $x"),
           onError: (x) => events.add("stream: error $x"),
           onDone: done.complete);
-    }, onError: (x) => events.add("rza: error $x"));
+    }, (e, s) => events.add("rza: error $e"));
     var c2 = new StreamController();
     c.addStream(c2.stream).whenComplete(c.close);
     c2.add(1);
     c2.addError(2);
     c2.close();
-  }, onError: (x) => events.add("rzb: error $x"));
+  }, (e, s) => events.add("rzb: error $e"));
   return [
     done.future,
     () {
@@ -130,18 +130,18 @@
   var events = [];
   var done = new Completer();
   var c;
-  runZoned(() {
+  runZonedGuarded(() {
     c = new StreamController();
     c.stream.listen((x) => events.add("stream: $x"),
         onError: (x) => events.add("stream: error $x"), onDone: done.complete);
-  }, onError: (x) => events.add("rza: error $x"));
-  runZoned(() {
+  }, (e, s) => events.add("rza: error $e"));
+  runZonedGuarded(() {
     var c2 = new StreamController();
     c.addStream(c2.stream).whenComplete(c.close);
     c2.add(1);
     c2.addError(2);
     c2.close();
-  }, onError: (x) => events.add("rzb: error $x"));
+  }, (e, s) => events.add("rzb: error $e"));
   return [
     done.future,
     () {
@@ -155,16 +155,16 @@
   var events = [];
   var done = new Completer();
   var c;
-  runZoned(() {
+  runZonedGuarded(() {
     c = new StreamController();
     c.stream.listen((x) => events.add("stream: $x"),
         onError: (x) => events.add("stream: error $x"), onDone: done.complete);
-  }, onError: (x) => events.add("rza: error $x"));
-  runZoned(() {
+  }, (e, s) => events.add("rza: error $e"));
+  runZonedGuarded(() {
     c.add(1);
     c.addError(2);
     c.close();
-  }, onError: (x) => events.add("rzb: error $x"));
+  }, (e, s) => events.add("rzb: error $e"));
   return [
     done.future,
     () {
diff --git a/tests/lib_2/isolate/appjit_serialization_regression_test.dart b/tests/lib_2/isolate/appjit_serialization_regression_test.dart
new file mode 100644
index 0000000..e359e9f
--- /dev/null
+++ b/tests/lib_2/isolate/appjit_serialization_regression_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:isolate';
+
+main() {
+  // The SendPorts should not be serialized.
+  var port = new RawReceivePort();
+  Isolate.current.addErrorListener(port.sendPort);
+  Isolate.current.addOnExitListener(port.sendPort);
+  port.close();
+}
diff --git a/tests/standalone/io/async_catch_errors_test.dart b/tests/standalone/io/async_catch_errors_test.dart
index 431057b..c039ad8 100644
--- a/tests/standalone/io/async_catch_errors_test.dart
+++ b/tests/standalone/io/async_catch_errors_test.dart
@@ -12,11 +12,11 @@
 
 Future testSocketException() {
   var completer = new Completer();
-  runZoned(() {
+  runZonedGuarded(() {
     Socket.connect("4", 1).then((Socket s) {
       Expect.fail("Socket should not be able to connect");
     });
-  }, onError: (err) {
+  }, (err, s) {
     if (err is! SocketException) Expect.fail("Not expected error: $err");
     completer.complete("socket test, ok.");
     events.add("SocketException");
@@ -26,9 +26,9 @@
 
 Future testFileSystemException() {
   var completer = new Completer();
-  runZoned(() {
+  runZonedGuarded(() {
     new File("lol it's not a file\n").openRead().listen(null);
-  }, onError: (err) {
+  }, (err, s) {
     if (err is! FileSystemException) Expect.fail("Not expected error: $err");
     completer.complete("file test, ok.");
     events.add("FileSystemException");
diff --git a/tests/standalone/io/file_system_watcher_test.dart b/tests/standalone/io/file_system_watcher_test.dart
index 3ef4175..7714f38 100644
--- a/tests/standalone/io/file_system_watcher_test.dart
+++ b/tests/standalone/io/file_system_watcher_test.dart
@@ -452,11 +452,11 @@
 }
 
 void watcher(SendPort sendPort) async {
-  runZoned(() {
+  runZonedGuarded(() {
     var watcher = Directory.systemTemp.watch(recursive: true);
     watcher.listen((data) async {});
     sendPort.send('start');
-  }, onError: (error) {
+  }, (error, stack) {
     print(error);
     sendPort.send('end');
   });
diff --git a/tests/standalone/io/http_server_test.dart b/tests/standalone/io/http_server_test.dart
index 911d7bf..3351df7 100644
--- a/tests/standalone/io/http_server_test.dart
+++ b/tests/standalone/io/http_server_test.dart
@@ -159,7 +159,7 @@
 void testHttpServerZoneError() {
   asyncStart();
   Expect.equals(Zone.root, Zone.current);
-  runZoned(() {
+  runZonedGuarded(() {
     Expect.notEquals(Zone.root, Zone.current);
     HttpServer.bind("127.0.0.1", 0).then((server) {
       Expect.notEquals(Zone.root, Zone.current);
@@ -178,14 +178,14 @@
         socket.listen(null);
       });
     });
-  }, onError: (e) {
+  }, (e, s) {
     asyncEnd();
   });
 }
 
 void testHttpServerClientClose() {
   HttpServer.bind("127.0.0.1", 0).then((server) {
-    runZoned(() {
+    runZonedGuarded(() {
       server.listen((request) {
         request.response.bufferOutput = false;
         request.response.add(new Uint8List(64 * 1024));
@@ -195,7 +195,7 @@
           });
         });
       });
-    }, onError: (e, s) {
+    }, (e, s) {
       Expect.fail("Unexpected error: $e(${e.hashCode})\n$s");
     });
     var client = new HttpClient();
diff --git a/tests/standalone/io/raw_socket_test.dart b/tests/standalone/io/raw_socket_test.dart
index 8280094..935db37 100644
--- a/tests/standalone/io/raw_socket_test.dart
+++ b/tests/standalone/io/raw_socket_test.dart
@@ -426,7 +426,7 @@
 void testSocketZoneError() {
   asyncStart();
   Expect.equals(Zone.root, Zone.current);
-  runZoned(() {
+  runZonedGuarded(() {
     Expect.notEquals(Zone.root, Zone.current);
     RawServerSocket.bind(InternetAddress.loopbackIPv4, 0).then((server) {
       Expect.notEquals(Zone.root, Zone.current);
@@ -451,7 +451,7 @@
         socket.close();
       });
     });
-  }, onError: (e) {
+  }, (e, s) {
     asyncEnd();
   });
 }
diff --git a/tests/standalone/io/wait_for_event_zone_caught_error_test.dart b/tests/standalone/io/wait_for_event_zone_caught_error_test.dart
index 09e60c4..90484e0 100644
--- a/tests/standalone/io/wait_for_event_zone_caught_error_test.dart
+++ b/tests/standalone/io/wait_for_event_zone_caught_error_test.dart
@@ -17,12 +17,12 @@
   initWaitForEvent();
   asyncStart();
   bool flag = false;
-  runZoned(() {
+  runZonedGuarded(() {
     Timer.run(() {
       asyncEnd();
       throw "Exception";
     });
-  }, onError: (e) {
+  }, (e, s) {
     flag = true;
   });
   Expect.isFalse(flag);
diff --git a/tests/standalone/io/wait_for_exception_test.dart b/tests/standalone/io/wait_for_exception_test.dart
index f5c207d..6c83553 100644
--- a/tests/standalone/io/wait_for_exception_test.dart
+++ b/tests/standalone/io/wait_for_exception_test.dart
@@ -11,12 +11,12 @@
 main() {
   asyncStart();
   Completer<bool> c = new Completer<bool>();
-  runZoned(() {
+  runZonedGuarded(() {
     Timer.run(() {
       asyncEnd();
       throw "Error";
     });
-  }, onError: (e) {
+  }, (e, s) {
     Expect.isTrue(e is String);
     c.complete(true);
   });
diff --git a/tests/standalone_2/io/async_catch_errors_test.dart b/tests/standalone_2/io/async_catch_errors_test.dart
index 431057b..c039ad8 100644
--- a/tests/standalone_2/io/async_catch_errors_test.dart
+++ b/tests/standalone_2/io/async_catch_errors_test.dart
@@ -12,11 +12,11 @@
 
 Future testSocketException() {
   var completer = new Completer();
-  runZoned(() {
+  runZonedGuarded(() {
     Socket.connect("4", 1).then((Socket s) {
       Expect.fail("Socket should not be able to connect");
     });
-  }, onError: (err) {
+  }, (err, s) {
     if (err is! SocketException) Expect.fail("Not expected error: $err");
     completer.complete("socket test, ok.");
     events.add("SocketException");
@@ -26,9 +26,9 @@
 
 Future testFileSystemException() {
   var completer = new Completer();
-  runZoned(() {
+  runZonedGuarded(() {
     new File("lol it's not a file\n").openRead().listen(null);
-  }, onError: (err) {
+  }, (err, s) {
     if (err is! FileSystemException) Expect.fail("Not expected error: $err");
     completer.complete("file test, ok.");
     events.add("FileSystemException");
diff --git a/tests/standalone_2/io/file_system_watcher_test.dart b/tests/standalone_2/io/file_system_watcher_test.dart
index ebb08de..d366ff8 100644
--- a/tests/standalone_2/io/file_system_watcher_test.dart
+++ b/tests/standalone_2/io/file_system_watcher_test.dart
@@ -451,11 +451,11 @@
 }
 
 void watcher(SendPort sendPort) async {
-  runZoned(() {
+  runZonedGuarded(() {
     var watcher = Directory.systemTemp.watch(recursive: true);
     watcher.listen((data) async {});
     sendPort.send('start');
-  }, onError: (error) {
+  }, (error, stack) {
     print(error);
     sendPort.send('end');
   });
diff --git a/tests/standalone_2/io/http_server_test.dart b/tests/standalone_2/io/http_server_test.dart
index b36fd7e..c9910af 100644
--- a/tests/standalone_2/io/http_server_test.dart
+++ b/tests/standalone_2/io/http_server_test.dart
@@ -159,7 +159,7 @@
 void testHttpServerZoneError() {
   asyncStart();
   Expect.equals(Zone.root, Zone.current);
-  runZoned(() {
+  runZonedGuarded(() {
     Expect.notEquals(Zone.root, Zone.current);
     HttpServer.bind("127.0.0.1", 0).then((server) {
       Expect.notEquals(Zone.root, Zone.current);
@@ -178,14 +178,14 @@
         socket.listen(null);
       });
     });
-  }, onError: (e) {
+  }, (e, s) {
     asyncEnd();
   });
 }
 
 void testHttpServerClientClose() {
   HttpServer.bind("127.0.0.1", 0).then((server) {
-    runZoned(() {
+    runZonedGuarded(() {
       server.listen((request) {
         request.response.bufferOutput = false;
         request.response.add(new Uint8List(64 * 1024));
@@ -195,7 +195,7 @@
           });
         });
       });
-    }, onError: (e, s) {
+    }, (e, s) {
       Expect.fail("Unexpected error: $e(${e.hashCode})\n$s");
     });
     var client = new HttpClient();
diff --git a/tests/standalone_2/io/raw_socket_test.dart b/tests/standalone_2/io/raw_socket_test.dart
index cf8087d..385b720 100644
--- a/tests/standalone_2/io/raw_socket_test.dart
+++ b/tests/standalone_2/io/raw_socket_test.dart
@@ -429,7 +429,7 @@
 void testSocketZoneError() {
   asyncStart();
   Expect.equals(Zone.root, Zone.current);
-  runZoned(() {
+  runZonedGuarded(() {
     Expect.notEquals(Zone.root, Zone.current);
     RawServerSocket.bind(InternetAddress.loopbackIPv4, 0).then((server) {
       Expect.notEquals(Zone.root, Zone.current);
@@ -454,7 +454,7 @@
         socket.close();
       });
     });
-  }, onError: (e) {
+  }, (e, s) {
     asyncEnd();
   });
 }
diff --git a/tests/standalone_2/io/wait_for_event_zone_caught_error_test.dart b/tests/standalone_2/io/wait_for_event_zone_caught_error_test.dart
index 09e60c4..90484e0 100644
--- a/tests/standalone_2/io/wait_for_event_zone_caught_error_test.dart
+++ b/tests/standalone_2/io/wait_for_event_zone_caught_error_test.dart
@@ -17,12 +17,12 @@
   initWaitForEvent();
   asyncStart();
   bool flag = false;
-  runZoned(() {
+  runZonedGuarded(() {
     Timer.run(() {
       asyncEnd();
       throw "Exception";
     });
-  }, onError: (e) {
+  }, (e, s) {
     flag = true;
   });
   Expect.isFalse(flag);
diff --git a/tests/standalone_2/io/wait_for_exception_test.dart b/tests/standalone_2/io/wait_for_exception_test.dart
index f5c207d..6c83553 100644
--- a/tests/standalone_2/io/wait_for_exception_test.dart
+++ b/tests/standalone_2/io/wait_for_exception_test.dart
@@ -11,12 +11,12 @@
 main() {
   asyncStart();
   Completer<bool> c = new Completer<bool>();
-  runZoned(() {
+  runZonedGuarded(() {
     Timer.run(() {
       asyncEnd();
       throw "Error";
     });
-  }, onError: (e) {
+  }, (e, s) {
     Expect.isTrue(e is String);
     c.complete(true);
   });
diff --git a/tools/VERSION b/tools/VERSION
index 858a4ac..85a4ce0 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
 MAJOR 2
 MINOR 8
 PATCH 0
-PRERELEASE 17
+PRERELEASE 18
 PRERELEASE_PATCH 0
-ABI_VERSION 30
-OLDEST_SUPPORTED_ABI_VERSION 30
+ABI_VERSION 31
+OLDEST_SUPPORTED_ABI_VERSION 31
diff --git a/tools/approve_results.dart b/tools/approve_results.dart
deleted file mode 100755
index ee8611f..0000000
--- a/tools/approve_results.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env dart
-// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-main(List<String> args) async {
-  print("""
-This command-line approval script is no longer used.
-
-You can approve test failures using the web UI at
-<https://dart-ci.firebaseapp.com/>.
-
-Please see instructions for approving failing tests
-at:
-
-https://goto.google.com/dart-test-approval
-https://goto.google.com/dart-status-file-free-workflow
-https://goto.google.com/dart-test-approval-faq""");
-}
diff --git a/tools/bots/results.dart b/tools/bots/results.dart
index 1383b3b..d3707f4 100644
--- a/tools/bots/results.dart
+++ b/tools/bots/results.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// results.json and flaky.json parses.
+// results.json and flaky.json parser.
 
 import 'dart:async';
 import 'dart:convert';
@@ -17,10 +17,6 @@
 /// Cloud storage location containing results.
 const testResultsStoragePath = "gs://dart-test-results/builders";
 
-/// Cloud storage location containing approved results.
-const approvedResultsStoragePath =
-    "gs://dart-test-results-approved-results/builders";
-
 /// Limit the number of concurrent subprocesses by half the number of cores.
 final gsutilPool = new Pool(max(1, Platform.numberOfProcessors ~/ 2));
 
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index f69d3e0..9bf31e1 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -475,6 +475,9 @@
         "builder-tag": "cfe"
       }
     },
+    "flutter-frontend": {
+      "__comment__": "This configuration is only used for a custom test runner. If it conflicts with a new configuration you are adding, you can make this configuration more specific by adding options."
+    },
     "unittest-asserts-no-sdk-(linux|mac|win)": {
       "options": {
         "compiler": "dartk",
@@ -1042,7 +1045,7 @@
           "testRunner": true,
           "arguments": [
             "pkg/front_end/test/unit_test_suites.dart",
-            "-ncfe-${system}-release-x64",
+            "-ncfe-unittest-asserts-${mode}-${system}",
             "--verbose"
           ]
         }
@@ -1937,7 +1940,7 @@
           "testRunner": true,
           "arguments": [
             "pkg/dev_compiler/test/modular_suite.dart",
-            "-ndartdevk-${system}-release",
+            "-ndartdevk-checked-${system}-release-chrome",
             "--verbose",
             "--use-sdk"
           ]
@@ -2124,7 +2127,7 @@
           "testRunner": true,
           "arguments": [
             "pkg/dev_compiler/test/modular_suite.dart",
-            "-ndartdevk-${system}-release",
+            "-ndartdevk-checked-mac-release-chrome",
             "--verbose",
             "--use-sdk"
           ]
@@ -2266,7 +2269,7 @@
           "testRunner": true,
           "arguments": [
             "pkg/compiler/tool/modular_test_suite.dart",
-            "-ndart2js-${system}-release-d8",
+            "-nunittest-asserts-no-sdk-linux",
             "--verbose",
             "--use-sdk"
           ]